diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000000..6a3ab0c92074 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: ["rust-lang.org/funding"] diff --git a/.github/ISSUE_TEMPLATE/ice.md b/.github/ISSUE_TEMPLATE/ice.md index 2afcd210a6eb..1ab1ddf46016 100644 --- a/.github/ISSUE_TEMPLATE/ice.md +++ b/.github/ISSUE_TEMPLATE/ice.md @@ -2,6 +2,7 @@ name: Internal Compiler Error about: Create a report for an internal compiler error in rustc. labels: C-bug, I-ICE, T-compiler +title: "[ICE]: " --- b --> d + // \ + // \-> c + // Here, `shorter_fr+` of `'a` == `['b, 'c]`. + // Propagating `'d: 'b` is correct and should occur; `'d: 'c` is redundant because of + // `'d: 'b` and could reject valid code. + // + // So we filter the constraints to regions already outlived by `longer_fr-`, but if + // the filter yields an empty set, we fall back to the original one. + let subset: Vec<_> = constraints + .iter() + .filter(|&&(fr_minus, shorter_fr_plus)| { + self.eval_outlives(fr_minus, shorter_fr_plus) + }) + .copied() + .collect(); + let propagated_constraints = if subset.is_empty() { constraints } else { subset }; + debug!( + "try_propagate_universal_region_error: constraints={:?}", + propagated_constraints + ); + + assert!( + !propagated_constraints.is_empty(), + "Expected at least one constraint to propagate here" + ); + + for (fr_minus, fr_plus) in propagated_constraints { + // Push the constraint `long_fr-: shorter_fr+` propagated_outlives_requirements.push(ClosureOutlivesRequirement { subject: ClosureOutlivesSubject::Region(fr_minus), - outlived_free_region: fr, + outlived_free_region: fr_plus, blame_span: blame_constraint.cause.span, category: blame_constraint.category, }); @@ -1311,7 +1363,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn check_bound_universal_region( &self, longer_fr: RegionVid, - placeholder: ty::PlaceholderRegion, + placeholder: ty::PlaceholderRegion<'tcx>, errors_buffer: &mut RegionErrors<'tcx>, ) { debug!("check_bound_universal_region(fr={:?}, placeholder={:?})", longer_fr, placeholder,); @@ -1327,11 +1379,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { .elements_contained_in(longer_fr_scc) .find(|e| *e != RegionElement::PlaceholderRegion(placeholder)) { + let illegally_outlived_r = self.region_from_element(longer_fr, &error_element); // Stop after the first error, it gets too noisy otherwise, and does not provide more information. - errors_buffer.push(RegionErrorKind::BoundUniversalRegionError { + errors_buffer.push(RegionErrorKind::PlaceholderOutlivesIllegalRegion { longer_fr, - error_element, - placeholder, + illegally_outlived_r, }); } else { debug!("check_bound_universal_region: all bounds satisfied"); @@ -1520,10 +1572,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Get the region outlived by `longer_fr` and live at `element`. - pub(crate) fn region_from_element( + fn region_from_element( &self, longer_fr: RegionVid, - element: &RegionElement, + element: &RegionElement<'tcx>, ) -> RegionVid { match *element { RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), @@ -1564,7 +1616,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn best_blame_constraint( &self, from_region: RegionVid, - from_region_origin: NllRegionVariableOrigin, + from_region_origin: NllRegionVariableOrigin<'tcx>, to_region: RegionVid, ) -> (BlameConstraint<'tcx>, Vec>) { assert!(from_region != to_region, "Trying to blame a region for itself!"); @@ -1697,6 +1749,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // should be as limited as possible; the note is prone to false positives and this // constraint usually isn't best to blame. ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: _, unsize_to: Some(unsize_ty), is_implicit_coercion: true, } if to_region == self.universal_regions().fr_static diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 0c4a82f3d2f3..23ad964c7cd9 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -24,13 +24,13 @@ use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use tracing::{debug, instrument}; use super::reverse_sccs::ReverseSccGraph; -use crate::BorrowckInferCtxt; use crate::consumers::RegionInferenceContext; use crate::session_diagnostics::LifetimeMismatchOpaqueParam; use crate::type_check::canonical::fully_perform_op_raw; use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::type_check::{Locations, MirTypeckRegionConstraints}; use crate::universal_regions::{RegionClassification, UniversalRegions}; +use crate::{BorrowckInferCtxt, CollectRegionConstraintsResult}; mod member_constraints; mod region_ctxt; @@ -126,6 +126,31 @@ fn nll_var_to_universal_region<'tcx>( } } +/// Record info needed to report the same name error later. +#[derive(Copy, Clone, Debug)] +pub(crate) struct UnexpectedHiddenRegion<'tcx> { + // The def_id of the body where this error occurs. + // Needed to handle region vars with their corresponding `infcx`. + def_id: LocalDefId, + opaque_type_key: OpaqueTypeKey<'tcx>, + hidden_type: ProvisionalHiddenType<'tcx>, + member_region: Region<'tcx>, +} + +impl<'tcx> UnexpectedHiddenRegion<'tcx> { + pub(crate) fn to_error(self) -> (LocalDefId, DeferredOpaqueTypeError<'tcx>) { + let UnexpectedHiddenRegion { def_id, opaque_type_key, hidden_type, member_region } = self; + ( + def_id, + DeferredOpaqueTypeError::UnexpectedHiddenRegion { + opaque_type_key, + hidden_type, + member_region, + }, + ) + } +} + /// Collect all defining uses of opaque types inside of this typeck root. This /// expects the hidden type to be mapped to the definition parameters of the opaque /// and errors if we end up with distinct hidden types. @@ -176,11 +201,13 @@ struct DefiningUse<'tcx> { /// It also means that this whole function is not really soundness critical as we /// recheck all uses of the opaques regardless. pub(crate) fn compute_definition_site_hidden_types<'tcx>( + def_id: LocalDefId, infcx: &BorrowckInferCtxt<'tcx>, universal_region_relations: &Frozen>, constraints: &MirTypeckRegionConstraints<'tcx>, location_map: Rc, hidden_types: &mut FxIndexMap>, + unconstrained_hidden_type_errors: &mut Vec>, opaque_types: &[(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)], ) -> Vec> { let mut errors = Vec::new(); @@ -204,8 +231,10 @@ pub(crate) fn compute_definition_site_hidden_types<'tcx>( // up equal to one of their choice regions and compute the actual hidden type of // the opaque type definition. This is stored in the `root_cx`. compute_definition_site_hidden_types_from_defining_uses( + def_id, &rcx, hidden_types, + unconstrained_hidden_type_errors, &defining_uses, &mut errors, ); @@ -274,8 +303,10 @@ fn collect_defining_uses<'tcx>( #[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))] fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( + def_id: LocalDefId, rcx: &RegionCtxt<'_, 'tcx>, hidden_types: &mut FxIndexMap>, + unconstrained_hidden_type_errors: &mut Vec>, defining_uses: &[DefiningUse<'tcx>], errors: &mut Vec>, ) { @@ -293,16 +324,29 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( Ok(hidden_type) => hidden_type, Err(r) => { debug!("UnexpectedHiddenRegion: {:?}", r); - errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion { - hidden_type, - opaque_type_key, - member_region: ty::Region::new_var(tcx, r), - }); - let guar = tcx.dcx().span_delayed_bug( - hidden_type.span, - "opaque type with non-universal region args", - ); - ty::ProvisionalHiddenType::new_error(tcx, guar) + // If we're using the next solver, the unconstrained region may be resolved by a + // fully defining use from another body. + // So we don't generate error eagerly here. + if rcx.infcx.tcx.use_typing_mode_borrowck() { + unconstrained_hidden_type_errors.push(UnexpectedHiddenRegion { + def_id, + hidden_type, + opaque_type_key, + member_region: ty::Region::new_var(tcx, r), + }); + continue; + } else { + errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion { + hidden_type, + opaque_type_key, + member_region: ty::Region::new_var(tcx, r), + }); + let guar = tcx.dcx().span_delayed_bug( + hidden_type.span, + "opaque type with non-universal region args", + ); + ty::ProvisionalHiddenType::new_error(tcx, guar) + } } }; @@ -570,6 +614,40 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>( errors } +/// We handle `UnexpectedHiddenRegion` error lazily in the next solver as +/// there may be a fully defining use in another body. +/// +/// In case such a defining use does not exist, we register an error here. +pub(crate) fn handle_unconstrained_hidden_type_errors<'tcx>( + tcx: TyCtxt<'tcx>, + hidden_types: &mut FxIndexMap>, + unconstrained_hidden_type_errors: &mut Vec>, + collect_region_constraints_results: &mut FxIndexMap< + LocalDefId, + CollectRegionConstraintsResult<'tcx>, + >, +) { + let mut unconstrained_hidden_type_errors = std::mem::take(unconstrained_hidden_type_errors); + unconstrained_hidden_type_errors + .retain(|unconstrained| !hidden_types.contains_key(&unconstrained.opaque_type_key.def_id)); + + unconstrained_hidden_type_errors.iter().for_each(|t| { + tcx.dcx() + .span_delayed_bug(t.hidden_type.span, "opaque type with non-universal region args"); + }); + + // `UnexpectedHiddenRegion` error contains region var which only makes sense in the + // corresponding `infcx`. + // So we need to insert the error to the body where it originates from. + for error in unconstrained_hidden_type_errors { + let (def_id, error) = error.to_error(); + let Some(result) = collect_region_constraints_results.get_mut(&def_id) else { + unreachable!("the body should depend on opaques type if it has opaque use"); + }; + result.deferred_opaque_type_errors.push(error); + } +} + /// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types. /// We do not check these new uses so this could be unsound. /// diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs index 90b15cbdd2cc..ada8908e220a 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs @@ -27,7 +27,7 @@ pub(super) struct RegionCtxt<'a, 'tcx> { pub(super) constraint_sccs: ConstraintSccs, pub(super) scc_annotations: IndexVec, pub(super) rev_scc_graph: ReverseSccGraph, - pub(super) scc_values: RegionValues, + pub(super) scc_values: RegionValues<'tcx, ConstraintSccIndex>, } impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index eb611fa34757..c1fed1260340 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -22,7 +22,7 @@ rustc_index::newtype_index! { /// An individual element in a region value -- the value of a /// particular region variable consists of a set of these elements. #[derive(Debug, Clone, PartialEq)] -pub(crate) enum RegionElement { +pub(crate) enum RegionElement<'tcx> { /// A point in the control-flow graph. Location(Location), @@ -32,7 +32,7 @@ pub(crate) enum RegionElement { /// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)` /// type). - PlaceholderRegion(ty::PlaceholderRegion), + PlaceholderRegion(ty::PlaceholderRegion<'tcx>), } /// Records the CFG locations where each region is live. When we initially compute liveness, we use @@ -131,9 +131,17 @@ impl LivenessValues { } } - /// Returns whether `region` is marked live at the given `location`. + /// Returns whether `region` is marked live at the given + /// [`location`][rustc_middle::mir::Location]. pub(crate) fn is_live_at(&self, region: RegionVid, location: Location) -> bool { let point = self.location_map.point_from_location(location); + self.is_live_at_point(region, point) + } + + /// Returns whether `region` is marked live at the given + /// [`point`][rustc_mir_dataflow::points::PointIndex]. + #[inline] + pub(crate) fn is_live_at_point(&self, region: RegionVid, point: PointIndex) -> bool { if let Some(points) = &self.points { points.row(region).is_some_and(|r| r.contains(point)) } else { @@ -196,25 +204,28 @@ impl LivenessValues { /// NLL. #[derive(Debug, Default)] #[derive(Clone)] // FIXME(#146079) -pub(crate) struct PlaceholderIndices { - indices: FxIndexSet, +pub(crate) struct PlaceholderIndices<'tcx> { + indices: FxIndexSet>, } -impl PlaceholderIndices { +impl<'tcx> PlaceholderIndices<'tcx> { /// Returns the `PlaceholderIndex` for the inserted `PlaceholderRegion` - pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { + pub(crate) fn insert(&mut self, placeholder: ty::PlaceholderRegion<'tcx>) -> PlaceholderIndex { let (index, _) = self.indices.insert_full(placeholder); index.into() } - pub(crate) fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex { + pub(crate) fn lookup_index( + &self, + placeholder: ty::PlaceholderRegion<'tcx>, + ) -> PlaceholderIndex { self.indices.get_index_of(&placeholder).unwrap().into() } pub(crate) fn lookup_placeholder( &self, placeholder: PlaceholderIndex, - ) -> ty::PlaceholderRegion { + ) -> ty::PlaceholderRegion<'tcx> { self.indices[placeholder.index()] } @@ -241,9 +252,9 @@ impl PlaceholderIndices { /// Here, the variable `'0` would contain the free region `'a`, /// because (since it is returned) it must live for at least `'a`. But /// it would also contain various points from within the function. -pub(crate) struct RegionValues { +pub(crate) struct RegionValues<'tcx, N: Idx> { location_map: Rc, - placeholder_indices: PlaceholderIndices, + placeholder_indices: PlaceholderIndices<'tcx>, points: SparseIntervalMatrix, free_regions: SparseBitMatrix, @@ -252,14 +263,14 @@ pub(crate) struct RegionValues { placeholders: SparseBitMatrix, } -impl RegionValues { +impl<'tcx, N: Idx> RegionValues<'tcx, N> { /// Creates a new set of "region values" that tracks causal information. /// Each of the regions in num_region_variables will be initialized with an /// empty set of points and no causal information. pub(crate) fn new( location_map: Rc, num_universal_regions: usize, - placeholder_indices: PlaceholderIndices, + placeholder_indices: PlaceholderIndices<'tcx>, ) -> Self { let num_points = location_map.num_points(); let num_placeholders = placeholder_indices.len(); @@ -274,7 +285,7 @@ impl RegionValues { /// Adds the given element to the value for the given region. Returns whether /// the element is newly added (i.e., was not already present). - pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex) -> bool { + pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex<'tcx>) -> bool { debug!("add(r={:?}, elem={:?})", r, elem); elem.add_to_row(self, r) } @@ -293,7 +304,7 @@ impl RegionValues { } /// Returns `true` if the region `r` contains the given element. - pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex) -> bool { + pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex<'tcx>) -> bool { elem.contained_in_row(self, r) } @@ -359,7 +370,7 @@ impl RegionValues { pub(crate) fn placeholders_contained_in( &self, r: N, - ) -> impl Iterator { + ) -> impl Iterator> { self.placeholders .row(r) .into_iter() @@ -368,7 +379,7 @@ impl RegionValues { } /// Returns all the elements contained in a given region's value. - pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator { + pub(crate) fn elements_contained_in(&self, r: N) -> impl Iterator> { let points_iter = self.locations_outlived_by(r).map(RegionElement::Location); let free_regions_iter = @@ -386,42 +397,50 @@ impl RegionValues { } } -pub(crate) trait ToElementIndex: Debug + Copy { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool; +pub(crate) trait ToElementIndex<'tcx>: Debug + Copy { + fn add_to_row(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool; - fn contained_in_row(self, values: &RegionValues, row: N) -> bool; + fn contained_in_row(self, values: &RegionValues<'tcx, N>, row: N) -> bool; } -impl ToElementIndex for Location { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool { +impl ToElementIndex<'_> for Location { + fn add_to_row(self, values: &mut RegionValues<'_, N>, row: N) -> bool { let index = values.location_map.point_from_location(self); values.points.insert(row, index) } - fn contained_in_row(self, values: &RegionValues, row: N) -> bool { + fn contained_in_row(self, values: &RegionValues<'_, N>, row: N) -> bool { let index = values.location_map.point_from_location(self); values.points.contains(row, index) } } -impl ToElementIndex for RegionVid { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool { +impl ToElementIndex<'_> for RegionVid { + fn add_to_row(self, values: &mut RegionValues<'_, N>, row: N) -> bool { values.free_regions.insert(row, self) } - fn contained_in_row(self, values: &RegionValues, row: N) -> bool { + fn contained_in_row(self, values: &RegionValues<'_, N>, row: N) -> bool { values.free_regions.contains(row, self) } } -impl ToElementIndex for ty::PlaceholderRegion { - fn add_to_row(self, values: &mut RegionValues, row: N) -> bool { - let index = values.placeholder_indices.lookup_index(self); +impl<'tcx> ToElementIndex<'tcx> for ty::PlaceholderRegion<'tcx> { + fn add_to_row(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool + where + Self: Into>, + { + let placeholder: ty::PlaceholderRegion<'tcx> = self.into(); + let index = values.placeholder_indices.lookup_index(placeholder); values.placeholders.insert(row, index) } - fn contained_in_row(self, values: &RegionValues, row: N) -> bool { - let index = values.placeholder_indices.lookup_index(self); + fn contained_in_row(self, values: &RegionValues<'tcx, N>, row: N) -> bool + where + Self: Into>, + { + let placeholder: ty::PlaceholderRegion<'tcx> = self.into(); + let index = values.placeholder_indices.lookup_index(placeholder); values.placeholders.contains(row, index) } } @@ -441,7 +460,9 @@ pub(crate) fn pretty_print_points( } /// For debugging purposes, returns a pretty-printed string of the given region elements. -fn pretty_print_region_elements(elements: impl IntoIterator) -> String { +fn pretty_print_region_elements<'tcx>( + elements: impl IntoIterator>, +) -> String { let mut result = String::new(); result.push('{'); diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index c3ff8cba9472..a082aba35b8a 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -12,8 +12,9 @@ use smallvec::SmallVec; use crate::consumers::BorrowckConsumer; use crate::nll::compute_closure_requirements_modulo_opaques; use crate::region_infer::opaque_types::{ - apply_definition_site_hidden_types, clone_and_resolve_opaque_types, + UnexpectedHiddenRegion, apply_definition_site_hidden_types, clone_and_resolve_opaque_types, compute_definition_site_hidden_types, detect_opaque_types_added_while_handling_opaque_types, + handle_unconstrained_hidden_type_errors, }; use crate::type_check::{Locations, constraint_conversion}; use crate::{ @@ -26,7 +27,12 @@ use crate::{ pub(super) struct BorrowCheckRootCtxt<'tcx> { pub tcx: TyCtxt<'tcx>, root_def_id: LocalDefId, + /// This contains fully resolved hidden types or `ty::Error`. hidden_types: FxIndexMap>, + /// This contains unconstrained regions in hidden types. + /// Only used for deferred error reporting. See + /// [`crate::region_infer::opaque_types::handle_unconstrained_hidden_type_errors`] + unconstrained_hidden_type_errors: Vec>, /// The region constraints computed by [borrowck_collect_region_constraints]. This uses /// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before /// their parents. @@ -49,6 +55,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { tcx, root_def_id, hidden_types: Default::default(), + unconstrained_hidden_type_errors: Default::default(), collect_region_constraints_results: Default::default(), propagated_borrowck_results: Default::default(), tainted_by_errors: None, @@ -84,23 +91,32 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { fn handle_opaque_type_uses(&mut self) { let mut per_body_info = Vec::new(); - for input in self.collect_region_constraints_results.values_mut() { + for (def_id, input) in &mut self.collect_region_constraints_results { let (num_entries, opaque_types) = clone_and_resolve_opaque_types( &input.infcx, &input.universal_region_relations, &mut input.constraints, ); input.deferred_opaque_type_errors = compute_definition_site_hidden_types( + *def_id, &input.infcx, &input.universal_region_relations, &input.constraints, Rc::clone(&input.location_map), &mut self.hidden_types, + &mut self.unconstrained_hidden_type_errors, &opaque_types, ); per_body_info.push((num_entries, opaque_types)); } + handle_unconstrained_hidden_type_errors( + self.tcx, + &mut self.hidden_types, + &mut self.unconstrained_hidden_type_errors, + &mut self.collect_region_constraints_results, + ); + for (input, (opaque_types_storage_num_entries, opaque_types)) in self.collect_region_constraints_results.values_mut().zip(per_body_info) { @@ -255,7 +271,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { } // We now apply the closure requirements of nested bodies modulo - // regions. In case a body does not depend on opaque types, we + // opaques. In case a body does not depend on opaque types, we // eagerly check its region constraints and use the final closure // requirements. // diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 5143b2fa2059..7bde534dafd2 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -7,16 +7,16 @@ use rustc_span::Span; use crate::diagnostics::RegionName; #[derive(Diagnostic)] -#[diag(borrowck_move_unsized, code = E0161)] +#[diag("cannot move a value of type `{$ty}`", code = E0161)] pub(crate) struct MoveUnsized<'tcx> { pub ty: Ty<'tcx>, #[primary_span] - #[label] + #[label("the size of `{$ty}` cannot be statically determined")] pub span: Span, } #[derive(Diagnostic)] -#[diag(borrowck_higher_ranked_lifetime_error)] +#[diag("higher-ranked lifetime error")] pub(crate) struct HigherRankedLifetimeError { #[subdiagnostic] pub cause: Option, @@ -26,21 +26,21 @@ pub(crate) struct HigherRankedLifetimeError { #[derive(Subdiagnostic)] pub(crate) enum HigherRankedErrorCause { - #[note(borrowck_could_not_prove)] + #[note("could not prove `{$predicate}`")] CouldNotProve { predicate: String }, - #[note(borrowck_could_not_normalize)] + #[note("could not normalize `{$value}`")] CouldNotNormalize { value: String }, } #[derive(Diagnostic)] -#[diag(borrowck_higher_ranked_subtype_error)] +#[diag("higher-ranked subtype error")] pub(crate) struct HigherRankedSubtypeError { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(borrowck_generic_does_not_live_long_enough)] +#[diag("`{$kind}` does not live long enough")] pub(crate) struct GenericDoesNotLiveLongEnough { pub kind: String, #[primary_span] @@ -48,15 +48,20 @@ pub(crate) struct GenericDoesNotLiveLongEnough { } #[derive(LintDiagnostic)] -#[diag(borrowck_var_does_not_need_mut)] +#[diag("variable does not need to be mutable")] pub(crate) struct VarNeedNotMut { - #[suggestion(style = "short", applicability = "machine-applicable", code = "")] + #[suggestion( + "remove this `mut`", + style = "short", + applicability = "machine-applicable", + code = "" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(borrowck_var_cannot_escape_closure)] -#[note] -#[note(borrowck_cannot_escape)] +#[diag("captured variable cannot escape `FnMut` closure body")] +#[note("`FnMut` closures only have access to their captured variables while they are executing...")] +#[note("...therefore, they cannot allow references to captured variables to escape")] pub(crate) struct FnMutError { #[primary_span] pub span: Span, @@ -66,17 +71,17 @@ pub(crate) struct FnMutError { #[derive(Subdiagnostic)] pub(crate) enum VarHereDenote { - #[label(borrowck_var_here_captured)] + #[label("variable captured here")] Captured { #[primary_span] span: Span, }, - #[label(borrowck_var_here_defined)] + #[label("variable defined here")] Defined { #[primary_span] span: Span, }, - #[label(borrowck_closure_inferred_mut)] + #[label("inferred to be a `FnMut` closure")] FnMutInferred { #[primary_span] span: Span, @@ -85,17 +90,21 @@ pub(crate) enum VarHereDenote { #[derive(Subdiagnostic)] pub(crate) enum FnMutReturnTypeErr { - #[label(borrowck_returned_closure_escaped)] + #[label( + "returns a closure that contains a reference to a captured variable, which then escapes the closure body" + )] ReturnClosure { #[primary_span] span: Span, }, - #[label(borrowck_returned_async_block_escaped)] + #[label( + "returns an `async` block that contains a reference to a captured variable, which then escapes the closure body" + )] ReturnAsyncBlock { #[primary_span] span: Span, }, - #[label(borrowck_returned_ref_escaped)] + #[label("returns a reference to a captured variable which escapes the closure body")] ReturnRef { #[primary_span] span: Span, @@ -103,7 +112,7 @@ pub(crate) enum FnMutReturnTypeErr { } #[derive(Diagnostic)] -#[diag(borrowck_lifetime_constraints_error)] +#[diag("lifetime may not live long enough")] pub(crate) struct LifetimeOutliveErr { #[primary_span] pub span: Span, @@ -111,7 +120,9 @@ pub(crate) struct LifetimeOutliveErr { #[derive(Subdiagnostic)] pub(crate) enum LifetimeReturnCategoryErr<'a> { - #[label(borrowck_returned_lifetime_wrong)] + #[label( + "{$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}`" + )] WrongReturn { #[primary_span] span: Span, @@ -119,7 +130,9 @@ pub(crate) enum LifetimeReturnCategoryErr<'a> { outlived_fr_name: RegionName, fr_name: &'a RegionName, }, - #[label(borrowck_returned_lifetime_short)] + #[label( + "{$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`" + )] ShortReturn { #[primary_span] span: Span, @@ -131,7 +144,7 @@ pub(crate) enum LifetimeReturnCategoryErr<'a> { #[derive(Subdiagnostic)] pub(crate) enum RequireStaticErr { - #[note(borrowck_used_impl_require_static)] + #[note("the used `impl` has a `'static` requirement")] UsedImpl { #[primary_span] multi_span: MultiSpan, @@ -140,42 +153,42 @@ pub(crate) enum RequireStaticErr { #[derive(Subdiagnostic)] pub(crate) enum CaptureVarPathUseCause { - #[label(borrowck_borrow_due_to_use_coroutine)] + #[label("borrow occurs due to use in coroutine")] BorrowInCoroutine { #[primary_span] path_span: Span, }, - #[label(borrowck_use_due_to_use_coroutine)] + #[label("use occurs due to use in coroutine")] UseInCoroutine { #[primary_span] path_span: Span, }, - #[label(borrowck_assign_due_to_use_coroutine)] + #[label("assign occurs due to use in coroutine")] AssignInCoroutine { #[primary_span] path_span: Span, }, - #[label(borrowck_assign_part_due_to_use_coroutine)] + #[label("assign to part occurs due to use in coroutine")] AssignPartInCoroutine { #[primary_span] path_span: Span, }, - #[label(borrowck_borrow_due_to_use_closure)] + #[label("borrow occurs due to use in closure")] BorrowInClosure { #[primary_span] path_span: Span, }, - #[label(borrowck_use_due_to_use_closure)] + #[label("use occurs due to use in closure")] UseInClosure { #[primary_span] path_span: Span, }, - #[label(borrowck_assign_due_to_use_closure)] + #[label("assignment occurs due to use in closure")] AssignInClosure { #[primary_span] path_span: Span, }, - #[label(borrowck_assign_part_due_to_use_closure)] + #[label("assignment to part occurs due to use in closure")] AssignPartInClosure { #[primary_span] path_span: Span, @@ -184,17 +197,17 @@ pub(crate) enum CaptureVarPathUseCause { #[derive(Subdiagnostic)] pub(crate) enum CaptureVarKind { - #[label(borrowck_capture_immute)] + #[label("capture is immutable because of use here")] Immut { #[primary_span] kind_span: Span, }, - #[label(borrowck_capture_mut)] + #[label("capture is mutable because of use here")] Mut { #[primary_span] kind_span: Span, }, - #[label(borrowck_capture_move)] + #[label("capture is moved because of use here")] Move { #[primary_span] kind_span: Span, @@ -203,77 +216,97 @@ pub(crate) enum CaptureVarKind { #[derive(Subdiagnostic)] pub(crate) enum CaptureVarCause { - #[label(borrowck_var_borrow_by_use_place_in_coroutine)] + #[label( + "{$is_single_var -> + *[true] borrow occurs + [false] borrows occur + } due to use of {$place} in coroutine" + )] BorrowUsePlaceCoroutine { is_single_var: bool, place: String, #[primary_span] var_span: Span, }, - #[label(borrowck_var_borrow_by_use_place_in_closure)] + #[label( + "{$is_single_var -> + *[true] borrow occurs + [false] borrows occur + } due to use of {$place} in closure" + )] BorrowUsePlaceClosure { is_single_var: bool, place: String, #[primary_span] var_span: Span, }, - #[label(borrowck_var_borrow_by_use_in_coroutine)] + #[label("borrow occurs due to use in coroutine")] BorrowUseInCoroutine { #[primary_span] var_span: Span, }, - #[label(borrowck_var_borrow_by_use_in_closure)] + #[label("borrow occurs due to use in closure")] BorrowUseInClosure { #[primary_span] var_span: Span, }, - #[label(borrowck_var_move_by_use_in_coroutine)] + #[label("move occurs due to use in coroutine")] MoveUseInCoroutine { #[primary_span] var_span: Span, }, - #[label(borrowck_var_move_by_use_in_closure)] + #[label("move occurs due to use in closure")] MoveUseInClosure { #[primary_span] var_span: Span, }, - #[label(borrowck_var_first_borrow_by_use_place_in_coroutine)] + #[label("first borrow occurs due to use of {$place} in coroutine")] FirstBorrowUsePlaceCoroutine { place: String, #[primary_span] var_span: Span, }, - #[label(borrowck_var_first_borrow_by_use_place_in_closure)] + #[label("first borrow occurs due to use of {$place} in closure")] FirstBorrowUsePlaceClosure { place: String, #[primary_span] var_span: Span, }, - #[label(borrowck_var_second_borrow_by_use_place_in_coroutine)] + #[label("second borrow occurs due to use of {$place} in coroutine")] SecondBorrowUsePlaceCoroutine { place: String, #[primary_span] var_span: Span, }, - #[label(borrowck_var_second_borrow_by_use_place_in_closure)] + #[label("second borrow occurs due to use of {$place} in closure")] SecondBorrowUsePlaceClosure { place: String, #[primary_span] var_span: Span, }, - #[label(borrowck_var_mutable_borrow_by_use_place_in_closure)] + #[label("mutable borrow occurs due to use of {$place} in closure")] MutableBorrowUsePlaceClosure { place: String, #[primary_span] var_span: Span, }, - #[label(borrowck_partial_var_move_by_use_in_coroutine)] + #[label( + "variable {$is_partial -> + [true] partially moved + *[false] moved + } due to use in coroutine" + )] PartialMoveUseInCoroutine { #[primary_span] var_span: Span, is_partial: bool, }, - #[label(borrowck_partial_var_move_by_use_in_closure)] + #[label( + "variable {$is_partial -> + [true] partially moved + *[false] moved + } due to use in closure" + )] PartialMoveUseInClosure { #[primary_span] var_span: Span, @@ -282,34 +315,57 @@ pub(crate) enum CaptureVarCause { } #[derive(Diagnostic)] -#[diag(borrowck_cannot_move_when_borrowed, code = E0505)] +#[diag("cannot move out of {$place -> + [value] value + *[other] {$place} +} because it is borrowed", code = E0505)] pub(crate) struct MoveBorrow<'a> { pub place: &'a str, pub borrow_place: &'a str, pub value_place: &'a str, #[primary_span] - #[label(borrowck_move_label)] + #[label( + "move out of {$value_place -> + [value] value + *[other] {$value_place} + } occurs here" + )] pub span: Span, - #[label] + #[label( + "borrow of {$borrow_place -> + [value] value + *[other] {$borrow_place} + } occurs here" + )] pub borrow_span: Span, } #[derive(Diagnostic)] -#[diag(borrowck_opaque_type_lifetime_mismatch)] +#[diag("opaque type used twice with different lifetimes")] pub(crate) struct LifetimeMismatchOpaqueParam<'tcx> { pub arg: GenericArg<'tcx>, pub prev: GenericArg<'tcx>, #[primary_span] - #[label] - #[note] + #[label("lifetime `{$arg}` used here")] + #[note( + "if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types" + )] pub span: Span, - #[label(borrowck_prev_lifetime_label)] + #[label("lifetime `{$prev}` previously used here")] pub prev_span: Span, } #[derive(Subdiagnostic)] pub(crate) enum CaptureReasonLabel<'a> { - #[label(borrowck_moved_due_to_call)] + #[label( + "{$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this {$is_loop_message -> + [true] call, in previous iteration of loop + *[false] call + }" + )] Call { #[primary_span] fn_call_span: Span, @@ -317,7 +373,15 @@ pub(crate) enum CaptureReasonLabel<'a> { is_partial: bool, is_loop_message: bool, }, - #[label(borrowck_moved_due_to_usage_in_operator)] + #[label( + "{$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to usage in {$is_loop_message -> + [true] operator, in previous iteration of loop + *[false] operator + }" + )] OperatorUse { #[primary_span] fn_call_span: Span, @@ -325,7 +389,15 @@ pub(crate) enum CaptureReasonLabel<'a> { is_partial: bool, is_loop_message: bool, }, - #[label(borrowck_moved_due_to_implicit_into_iter_call)] + #[label( + "{$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this implicit call to {$is_loop_message -> + [true] `.into_iter()`, in previous iteration of loop + *[false] `.into_iter()` + }" + )] ImplicitCall { #[primary_span] fn_call_span: Span, @@ -333,7 +405,15 @@ pub(crate) enum CaptureReasonLabel<'a> { is_partial: bool, is_loop_message: bool, }, - #[label(borrowck_moved_due_to_method_call)] + #[label( + "{$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this method {$is_loop_message -> + [true] call, in previous iteration of loop + *[false] call + }" + )] MethodCall { #[primary_span] fn_call_span: Span, @@ -341,7 +421,15 @@ pub(crate) enum CaptureReasonLabel<'a> { is_partial: bool, is_loop_message: bool, }, - #[label(borrowck_moved_due_to_await)] + #[label( + "{$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this {$is_loop_message -> + [true] await, in previous iteration of loop + *[false] await + }" + )] Await { #[primary_span] fn_call_span: Span, @@ -349,7 +437,18 @@ pub(crate) enum CaptureReasonLabel<'a> { is_partial: bool, is_loop_message: bool, }, - #[label(borrowck_value_moved_here)] + #[label( + "value {$is_partial -> + [true] partially moved + *[false] moved + } {$is_move_msg -> + [true] into closure here + *[false] here + }{$is_loop_message -> + [true] , in previous iteration of loop + *[false] {\"\"} + }" + )] MovedHere { #[primary_span] move_span: Span, @@ -357,7 +456,7 @@ pub(crate) enum CaptureReasonLabel<'a> { is_move_msg: bool, is_loop_message: bool, }, - #[label(borrowck_consider_borrow_type_contents)] + #[label("help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents")] BorrowContent { #[primary_span] var_span: Span, @@ -366,22 +465,22 @@ pub(crate) enum CaptureReasonLabel<'a> { #[derive(Subdiagnostic)] pub(crate) enum CaptureReasonNote { - #[note(borrowck_moved_a_fn_once_in_call)] + #[note("this value implements `FnOnce`, which causes it to be moved when called")] FnOnceMoveInCall { #[primary_span] var_span: Span, }, - #[note(borrowck_calling_operator_moves)] + #[note("calling this operator moves the value")] UnOpMoveByOperator { #[primary_span] span: Span, }, - #[note(borrowck_calling_operator_moves_lhs)] + #[note("calling this operator moves the left-hand side")] LhsMoveByOperator { #[primary_span] span: Span, }, - #[note(borrowck_func_take_self_moved_place)] + #[note("`{$func}` takes ownership of the receiver `self`, which moves {$place_name}")] FuncTakeSelf { func: String, place_name: String, @@ -393,7 +492,7 @@ pub(crate) enum CaptureReasonNote { #[derive(Subdiagnostic)] pub(crate) enum CaptureReasonSuggest<'tcx> { #[suggestion( - borrowck_suggest_iterate_over_slice, + "consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop", applicability = "maybe-incorrect", code = "&", style = "verbose" @@ -404,7 +503,7 @@ pub(crate) enum CaptureReasonSuggest<'tcx> { span: Span, }, #[suggestion( - borrowck_suggest_create_fresh_reborrow, + "consider reborrowing the `Pin` instead of moving it", applicability = "maybe-incorrect", code = ".as_mut()", style = "verbose" @@ -417,13 +516,18 @@ pub(crate) enum CaptureReasonSuggest<'tcx> { #[derive(Subdiagnostic)] pub(crate) enum CaptureArgLabel { - #[label(borrowck_value_capture_here)] + #[label( + "value captured {$is_within -> + [true] here by coroutine + *[false] here + }" + )] Capture { is_within: bool, #[primary_span] args_span: Span, }, - #[label(borrowck_move_out_place_here)] + #[label("{$place} is moved here")] MoveOutPlace { place: String, #[primary_span] @@ -433,13 +537,17 @@ pub(crate) enum CaptureArgLabel { #[derive(Subdiagnostic)] pub(crate) enum OnClosureNote<'a> { - #[note(borrowck_closure_invoked_twice)] + #[note( + "closure cannot be invoked more than once because it moves the variable `{$place_name}` out of its environment" + )] InvokedTwice { place_name: &'a str, #[primary_span] span: Span, }, - #[note(borrowck_closure_moved_twice)] + #[note( + "closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place_name}` out of its environment" + )] MovedTwice { place_name: &'a str, #[primary_span] @@ -449,7 +557,12 @@ pub(crate) enum OnClosureNote<'a> { #[derive(Subdiagnostic)] pub(crate) enum TypeNoCopy<'a, 'tcx> { - #[label(borrowck_ty_no_impl_copy)] + #[label( + "{$is_partial_move -> + [true] partial move + *[false] move + } occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait" + )] Label { is_partial_move: bool, ty: Ty<'tcx>, @@ -457,12 +570,24 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> { #[primary_span] span: Span, }, - #[note(borrowck_ty_no_impl_copy)] + #[note( + "{$is_partial_move -> + [true] partial move + *[false] move + } occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait" + )] Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str }, } #[derive(Diagnostic)] -#[diag(borrowck_simd_intrinsic_arg_const)] +#[diag( + "{$arg -> + [1] 1st + [2] 2nd + [3] 3rd + *[other] {$arg}th + } argument of `{$intrinsic}` is required to be a `const` item" +)] pub(crate) struct SimdIntrinsicArgConst { #[primary_span] pub span: Span, @@ -471,8 +596,8 @@ pub(crate) struct SimdIntrinsicArgConst { } #[derive(LintDiagnostic)] -#[diag(borrowck_tail_expr_drop_order)] +#[diag("relative drop order changing in Rust 2024")] pub(crate) struct TailExprDropOrder { - #[label] + #[label("this temporary value will be dropped at the end of the block")] pub borrowed: Span, } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index aece0bda3469..21ea2c70fbb3 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -343,8 +343,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return; } - // FIXME: Ideally MIR types are normalized, but this is not always true. - let mir_ty = self.normalize(mir_ty, Locations::All(span)); + // This is a hack. `body.local_decls` are not necessarily normalized in the old + // solver due to not deeply normalizing in writeback. So we must re-normalize here. + // + // I am not sure of a test case where this actually matters. There is a similar + // hack in `equate_inputs_and_outputs` which does have associated test cases. + let mir_ty = match self.infcx.next_trait_solver() { + true => mir_ty, + false => self.normalize(mir_ty, Locations::All(span)), + }; let cause = ObligationCause::dummy_with_span(span); let param_env = self.infcx.param_env; @@ -353,6 +360,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Boring, type_op::custom::CustomTypeOp::new( |ocx| { + // The `AscribeUserType` query would normally emit a wf + // obligation for the unnormalized user_ty here. This is + // where the "incorrectly skips the WF checks we normally do" + // happens let user_ty = ocx.normalize(&cause, param_env, user_ty); ocx.eq(&cause, param_env, user_ty, mir_ty)?; Ok(()) diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index d27a73535bab..c4d964441b1d 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -94,28 +94,10 @@ impl UniversalRegionRelations<'_> { /// words, returns the largest (*) known region `fr1` that (a) is /// outlived by `fr` and (b) is not local. /// - /// (*) If there are multiple competing choices, we pick the "postdominating" - /// one. See `TransitiveRelation::postdom_upper_bound` for details. - pub(crate) fn non_local_lower_bound(&self, fr: RegionVid) -> Option { + /// (*) If there are multiple competing choices, we return all of them. + pub(crate) fn non_local_lower_bounds(&self, fr: RegionVid) -> Vec { debug!("non_local_lower_bound(fr={:?})", fr); - let lower_bounds = self.non_local_bounds(&self.outlives, fr); - - // In case we find more than one, reduce to one for - // convenience. This is to prevent us from generating more - // complex constraints, but it will cause spurious errors. - let post_dom = self.outlives.mutual_immediate_postdominator(lower_bounds); - - debug!("non_local_bound: post_dom={:?}", post_dom); - - post_dom.and_then(|post_dom| { - // If the mutual immediate postdom is not local, then - // there is no non-local result we can return. - if !self.universal_regions.is_local_free_region(post_dom) { - Some(post_dom) - } else { - None - } - }) + self.non_local_bounds(&self.outlives, fr) } /// Helper for `non_local_upper_bounds` and `non_local_lower_bounds`. @@ -247,8 +229,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // not ready to process them yet. // - Then compute the implied bounds. This will adjust // the `region_bound_pairs` and so forth. - // - After this is done, we'll process the constraints, once - // the `relations` is built. + // - After this is done, we'll register the constraints in + // the `BorrowckInferCtxt`. Checking these constraints is + // handled later by actual borrow checking. let mut normalized_inputs_and_output = Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1); for ty in unnormalized_input_output_tys { @@ -272,6 +255,15 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { constraints.push(c) } + // Currently `implied_outlives_bounds` will normalize the provided + // `Ty`, despite this it's still important to normalize the ty ourselves + // as normalization may introduce new region variables (#136547). + // + // If we do not add implied bounds for the type involving these new + // region variables then we'll wind up with the normalized form of + // the signature having not-wf types due to unsatisfied region + // constraints. + // // Note: we need this in examples like // ``` // trait Foo { @@ -280,7 +272,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // } // impl Foo for () { // type Bar = (); - // fn foo(&self) ->&() {} + // fn foo(&self) -> &() {} // } // ``` // Both &Self::Bar and &() are WF @@ -295,6 +287,15 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { } // Add implied bounds from impl header. + // + // We don't use `assumed_wf_types` to source the entire set of implied bounds for + // a few reasons: + // - `DefiningTy` for closure has the `&'env Self` type while `assumed_wf_types` doesn't + // - We compute implied bounds from the unnormalized types in the `DefiningTy` but do not + // do so for types in impl headers + // - We must compute the normalized signature and then compute implied bounds from that + // in order to connect any unconstrained region vars created during normalization to + // the types of the locals corresponding to the inputs and outputs of the item. (#136547) if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) { for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) { let result: Result<_, ErrorGuaranteed> = param_env @@ -370,10 +371,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { known_type_outlives_obligations.push(outlives); } - /// Update the type of a single local, which should represent - /// either the return type of the MIR or one of its arguments. At - /// the same time, compute and add any implied bounds that come - /// from this local. + /// Compute and add any implied bounds that come from a given type. #[instrument(level = "debug", skip(self))] fn add_implied_bounds( &mut self, diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index eb31b5de05d2..3bce78b4e2e2 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,9 +7,8 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). -use std::assert_matches::assert_matches; - use itertools::Itertools; +use rustc_data_structures::assert_matches; use rustc_hir as hir; use rustc_infer::infer::{BoundRegionConversionTime, RegionVariableOrigin}; use rustc_middle::mir::*; @@ -127,6 +126,31 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } + // FIXME(BoxyUwU): This should probably be part of a larger borrowck dev-guide chapter + // + /// Enforce that the types of the locals corresponding to the inputs and output of + /// the body are equal to those of the (normalized) signature. + /// + /// This is necessary for two reasons: + /// - Locals in the MIR all start out with `'erased` regions and then are replaced + /// with unconstrained nll vars. If we have a function returning `&'a u32` then + /// the local `_0: &'?10 u32` needs to have its region var equated with the nll + /// var representing `'a`. i.e. borrow check must uphold that `'?10 = 'a`. + /// - When computing the normalized signature we may introduce new unconstrained nll + /// vars due to higher ranked where clauses ([#136547]). We then wind up with implied + /// bounds involving these vars. + /// + /// For this reason it is important that we equate with the *normalized* signature + /// which was produced when computing implied bounds. If we do not do so then we will + /// wind up with implied bounds on nll vars which cannot actually be used as the nll + /// var never gets related to anything. + /// + /// For 'closure-like' bodies this function effectively relates the *inferred* signature + /// of the closure against the locals corresponding to the closure's inputs/output. It *does + /// not* relate the user provided types for the signature to the locals, this is handled + /// separately by: [`TypeChecker::check_signature_annotation`]. + /// + /// [#136547]: #[instrument(skip(self), level = "debug")] pub(super) fn equate_inputs_and_outputs(&mut self, normalized_inputs_and_output: &[Ty<'tcx>]) { let (&normalized_output_ty, normalized_input_tys) = @@ -174,38 +198,44 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } - // Return types are a bit more complex. They may contain opaque `impl Trait` types. - let mir_output_ty = self.body.local_decls[RETURN_PLACE].ty; + // Equate expected output ty with the type of the RETURN_PLACE in MIR + let mir_output_ty = self.body.return_ty(); let output_span = self.body.local_decls[RETURN_PLACE].source_info.span; self.equate_normalized_input_or_output(normalized_output_ty, mir_output_ty, output_span); } #[instrument(skip(self), level = "debug")] fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span) { + if self.infcx.next_trait_solver() { + return self + .eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) + .unwrap_or_else(|terr| { + span_mirbug!( + self, + Location::START, + "equate_normalized_input_or_output: `{a:?}=={b:?}` failed with `{terr:?}`", + ); + }); + } + + // This is a hack. `body.local_decls` are not necessarily normalized in the old + // solver due to not deeply normalizing in writeback. So we must re-normalize here. + // + // However, in most cases normalizing is unnecessary so we only do so if it may be + // necessary for type equality to hold. This leads to some (very minor) performance + // wins. if let Err(_) = self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) { - // FIXME(jackh726): This is a hack. It's somewhat like - // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd - // like to normalize *before* inserting into `local_decls`, but - // doing so ends up causing some other trouble. let b = self.normalize(b, Locations::All(span)); - - // Note: if we have to introduce new placeholders during normalization above, then we - // won't have added those universes to the universe info, which we would want in - // `relate_tys`. - if let Err(terr) = - self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) - { - span_mirbug!( - self, - Location::START, - "equate_normalized_input_or_output: `{:?}=={:?}` failed with `{:?}`", - a, - b, - terr - ); - } - } + self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) + .unwrap_or_else(|terr| { + span_mirbug!( + self, + Location::START, + "equate_normalized_input_or_output: `{a:?}=={b:?}` failed with `{terr:?}`", + ); + }); + }; } } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index ca1b850f7665..442c37e26ec1 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -11,7 +11,7 @@ use tracing::debug; use super::TypeChecker; use crate::constraints::OutlivesConstraintSet; -use crate::polonius::PoloniusLivenessContext; +use crate::polonius::PoloniusContext; use crate::region_infer::values::LivenessValues; use crate::universal_regions::UniversalRegions; @@ -48,7 +48,7 @@ pub(super) fn generate<'tcx>( if typeck.tcx().sess.opts.unstable_opts.polonius.is_next_enabled() { let (_, boring_locals) = compute_relevant_live_locals(typeck.tcx(), &free_regions, typeck.body); - typeck.polonius_liveness.as_mut().unwrap().boring_nll_locals = + typeck.polonius_context.as_mut().unwrap().boring_nll_locals = boring_locals.into_iter().collect(); free_regions = typeck.universal_regions.universal_regions_iter().collect(); } @@ -63,7 +63,7 @@ pub(super) fn generate<'tcx>( typeck.tcx(), &mut typeck.constraints.liveness_constraints, &typeck.universal_regions, - &mut typeck.polonius_liveness, + &mut typeck.polonius_context, typeck.body, ); } @@ -140,11 +140,11 @@ fn record_regular_live_regions<'tcx>( tcx: TyCtxt<'tcx>, liveness_constraints: &mut LivenessValues, universal_regions: &UniversalRegions<'tcx>, - polonius_liveness: &mut Option, + polonius_context: &mut Option, body: &Body<'tcx>, ) { let mut visitor = - LiveVariablesVisitor { tcx, liveness_constraints, universal_regions, polonius_liveness }; + LiveVariablesVisitor { tcx, liveness_constraints, universal_regions, polonius_context }; for (bb, data) in body.basic_blocks.iter_enumerated() { visitor.visit_basic_block_data(bb, data); } @@ -155,7 +155,7 @@ struct LiveVariablesVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, liveness_constraints: &'a mut LivenessValues, universal_regions: &'a UniversalRegions<'tcx>, - polonius_liveness: &'a mut Option, + polonius_context: &'a mut Option, } impl<'a, 'tcx> Visitor<'tcx> for LiveVariablesVisitor<'a, 'tcx> { @@ -207,8 +207,8 @@ impl<'a, 'tcx> LiveVariablesVisitor<'a, 'tcx> { }); // When using `-Zpolonius=next`, we record the variance of each live region. - if let Some(polonius_liveness) = self.polonius_liveness { - polonius_liveness.record_live_region_variance(self.tcx, self.universal_regions, value); + if let Some(polonius_context) = self.polonius_context { + polonius_context.record_live_region_variance(self.tcx, self.universal_regions, value); } } } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 7ac94020de03..840210496eb4 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -622,8 +622,8 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { }); // When using `-Zpolonius=next`, we record the variance of each live region. - if let Some(polonius_liveness) = typeck.polonius_liveness.as_mut() { - polonius_liveness.record_live_region_variance( + if let Some(polonius_context) = typeck.polonius_context.as_mut() { + polonius_context.record_live_region_variance( typeck.infcx.tcx, typeck.universal_regions, value, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 43005fca2984..2935559147b7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -19,6 +19,7 @@ use rustc_infer::infer::{ BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, }; use rustc_infer::traits::PredicateObligations; +use rustc_middle::bug; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; @@ -28,7 +29,6 @@ use rustc_middle::ty::{ self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, UserArgs, UserTypeAnnotationIndex, fold_regions, }; -use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::move_paths::MoveData; use rustc_mir_dataflow::points::DenseLocationMap; use rustc_span::def_id::CRATE_DEF_ID; @@ -42,8 +42,8 @@ use tracing::{debug, instrument, trace}; use crate::borrow_set::BorrowSet; use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet}; use crate::diagnostics::UniverseInfo; +use crate::polonius::PoloniusContext; use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable}; -use crate::polonius::{PoloniusContext, PoloniusLivenessContext}; use crate::region_infer::TypeTest; use crate::region_infer::values::{LivenessValues, PlaceholderIndex, PlaceholderIndices}; use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst}; @@ -123,21 +123,24 @@ pub(crate) fn type_check<'tcx>( known_type_outlives_obligations, } = free_region_relations::create(infcx, universal_regions, &mut constraints); - let pre_obligations = infcx.take_registered_region_obligations(); - assert!( - pre_obligations.is_empty(), - "there should be no incoming region obligations = {pre_obligations:#?}", - ); - let pre_assumptions = infcx.take_registered_region_assumptions(); - assert!( - pre_assumptions.is_empty(), - "there should be no incoming region assumptions = {pre_assumptions:#?}", - ); + { + // Scope these variables so it's clear they're not used later + let pre_obligations = infcx.take_registered_region_obligations(); + assert!( + pre_obligations.is_empty(), + "there should be no incoming region obligations = {pre_obligations:#?}", + ); + let pre_assumptions = infcx.take_registered_region_assumptions(); + assert!( + pre_assumptions.is_empty(), + "there should be no incoming region assumptions = {pre_assumptions:#?}", + ); + } debug!(?normalized_inputs_and_output); - let polonius_liveness = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { - Some(PoloniusLivenessContext::default()) + let polonius_context = if infcx.tcx.sess.opts.unstable_opts.polonius.is_next_enabled() { + Some(PoloniusContext::default()) } else { None }; @@ -159,7 +162,7 @@ pub(crate) fn type_check<'tcx>( borrow_set, constraints: &mut constraints, deferred_closure_requirements: &mut deferred_closure_requirements, - polonius_liveness, + polonius_context, }; typeck.check_user_type_annotations(); @@ -169,14 +172,7 @@ pub(crate) fn type_check<'tcx>( liveness::generate(&mut typeck, &location_map, move_data); - // We're done with typeck, we can finalize the polonius liveness context for region inference. - let polonius_context = typeck.polonius_liveness.take().map(|liveness_context| { - PoloniusContext::create_from_liveness( - liveness_context, - infcx.num_region_vars(), - typeck.constraints.liveness_constraints.points(), - ) - }); + let polonius_context = typeck.polonius_context; // In case type check encountered an error region, we suppress unhelpful extra // errors in by clearing out all outlives bounds that we may end up checking. @@ -235,7 +231,7 @@ struct TypeChecker<'a, 'tcx> { constraints: &'a mut MirTypeckRegionConstraints<'tcx>, deferred_closure_requirements: &'a mut DeferredClosureRequirements<'tcx>, /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints. - polonius_liveness: Option, + polonius_context: Option, } /// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions @@ -258,7 +254,7 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { /// /// To keep everything in sync, do not insert this set /// directly. Instead, use the `placeholder_region` helper. - pub(crate) placeholder_indices: PlaceholderIndices, + pub(crate) placeholder_indices: PlaceholderIndices<'tcx>, /// Each time we add a placeholder to `placeholder_indices`, we /// also create a corresponding "representative" region vid for @@ -289,7 +285,7 @@ impl<'tcx> MirTypeckRegionConstraints<'tcx> { pub(crate) fn placeholder_region( &mut self, infcx: &InferCtxt<'tcx>, - placeholder: ty::PlaceholderRegion, + placeholder: ty::PlaceholderRegion<'tcx>, ) -> ty::Region<'tcx> { let placeholder_index = self.placeholder_indices.insert(placeholder); match self.placeholder_index_to_region.get(placeholder_index) { @@ -387,18 +383,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn check_user_type_annotations(&mut self) { debug!(?self.user_type_annotations); - let tcx = self.tcx(); for user_annotation in self.user_type_annotations { let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation; let annotation = self.instantiate_canonical(span, user_ty); - if let ty::UserTypeKind::TypeOf(def, args) = annotation.kind - && let DefKind::InlineConst = tcx.def_kind(def) - { - assert!(annotation.bounds.is_empty()); - self.check_inline_const(inferred_ty, def.expect_local(), args, span); - } else { - self.ascribe_user_type(inferred_ty, annotation, span); - } + self.ascribe_user_type(inferred_ty, annotation, span); } } @@ -560,36 +548,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.constraints.liveness_constraints.add_location(region, location); } } - - fn check_inline_const( - &mut self, - inferred_ty: Ty<'tcx>, - def_id: LocalDefId, - args: UserArgs<'tcx>, - span: Span, - ) { - assert!(args.user_self_ty.is_none()); - let tcx = self.tcx(); - let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args); - if let Err(terr) = - self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring) - { - span_bug!( - span, - "bad inline const pattern: ({:?} = {:?}) {:?}", - const_ty, - inferred_ty, - terr - ); - } - let args = self.infcx.resolve_vars_if_possible(args.args); - let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span)); - self.normalize_and_prove_instantiated_predicates( - def_id.to_def_id(), - predicates, - Locations::All(span), - ); - } } impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { @@ -810,7 +768,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty::BoundRegionKind::Anon => sym::anon, ty::BoundRegionKind::Named(def_id) => tcx.item_name(def_id), ty::BoundRegionKind::ClosureEnv => sym::env, - ty::BoundRegionKind::NamedAnon(_) => { + ty::BoundRegionKind::NamedForPrinting(_) => { bug!("only used for pretty printing") } }; @@ -1023,7 +981,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // element, so we require the `Copy` trait. if len.try_to_target_usize(tcx).is_none_or(|len| len > 1) { match operand { - Operand::Copy(..) | Operand::Constant(..) => { + Operand::Copy(..) | Operand::Constant(..) | Operand::RuntimeChecks(_) => { // These are always okay: direct use of a const, or a value that can // evidently be copied. } @@ -1046,19 +1004,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } - &Rvalue::NullaryOp(NullOp::RuntimeChecks(_)) => {} - - Rvalue::ShallowInitBox(_operand, ty) => { - let trait_ref = - ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, span), [*ty]); - - self.prove_trait_ref( - trait_ref, - location.to_locations(), - ConstraintCategory::SizedBound, - ); - } - Rvalue::Cast(cast_kind, op, ty) => { match *cast_kind { CastKind::PointerCoercion( @@ -1113,7 +1058,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); let src_ty = self.normalize(src_ty, location); @@ -1121,7 +1070,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1142,7 +1095,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.prove_predicate( ty::ClauseKind::WellFormed(src_ty.into()), location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ); // The type that we see in the fcx is like @@ -1155,7 +1112,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { src_ty, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1184,7 +1145,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1217,7 +1182,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ty_fn_ptr_from, *ty, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1246,6 +1215,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { trait_ref, location.to_locations(), ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, is_implicit_coercion, unsize_to: Some(unsize_to), }, @@ -1271,7 +1241,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { *ty_from, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1334,7 +1308,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { *ty_elem, *ty_to, location.to_locations(), - ConstraintCategory::Cast { is_implicit_coercion, unsize_to: None }, + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, + is_implicit_coercion, + unsize_to: None, + }, ) { span_mirbug!( self, @@ -1491,55 +1469,96 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { trait_ref, location.to_locations(), ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: false, is_implicit_coercion: true, unsize_to: None, }, ); - } else if let ty::Dynamic(src_tty, _src_lt) = + } else if let ty::Dynamic(src_tty, src_lt) = *self.struct_tail(src.ty, location).kind() && let ty::Dynamic(dst_tty, dst_lt) = *self.struct_tail(dst.ty, location).kind() - && src_tty.principal().is_some() - && dst_tty.principal().is_some() { - // This checks (lifetime part of) vtable validity for pointer casts, - // which is irrelevant when there are aren't principal traits on - // both sides (aka only auto traits). - // - // Note that other checks (such as denying `dyn Send` -> `dyn - // Debug`) are in `rustc_hir_typeck`. + match (src_tty.principal(), dst_tty.principal()) { + (Some(_), Some(_)) => { + // This checks (lifetime part of) vtable validity for pointer casts, + // which is irrelevant when there are aren't principal traits on + // both sides (aka only auto traits). + // + // Note that other checks (such as denying `dyn Send` -> `dyn + // Debug`) are in `rustc_hir_typeck`. - // Remove auto traits. - // Auto trait checks are handled in `rustc_hir_typeck` as FCW. - let src_obj = Ty::new_dynamic( - tcx, - tcx.mk_poly_existential_predicates( - &src_tty.without_auto_traits().collect::>(), + // Remove auto traits. + // Auto trait checks are handled in `rustc_hir_typeck`. + let src_obj = Ty::new_dynamic( + tcx, + tcx.mk_poly_existential_predicates( + &src_tty.without_auto_traits().collect::>(), + ), + src_lt, + ); + let dst_obj = Ty::new_dynamic( + tcx, + tcx.mk_poly_existential_predicates( + &dst_tty.without_auto_traits().collect::>(), + ), + dst_lt, + ); + + debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); + + // Trait parameters are invariant, the only part that actually has + // subtyping here is the lifetime bound of the dyn-type. + // + // For example in `dyn Trait<'a> + 'b <: dyn Trait<'c> + 'd` we would + // require that `'a == 'c` but only that `'b: 'd`. + // + // We must not allow freely casting lifetime bounds of dyn-types as it + // may allow for inaccessible VTable methods being callable: #136702 + self.sub_types( + src_obj, + dst_obj, + location.to_locations(), + ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: true, + is_implicit_coercion: false, + unsize_to: None, + }, + ) + .unwrap(); + } + (None, None) => { + // `struct_tail` returns regions which haven't been mapped + // to nll vars yet so we do it here as `outlives_constraints` + // expects nll vars. + let src_lt = self.universal_regions.to_region_vid(src_lt); + let dst_lt = self.universal_regions.to_region_vid(dst_lt); + + // The principalless (no non-auto traits) case: + // You can only cast `dyn Send + 'long` to `dyn Send + 'short`. + self.constraints.outlives_constraints.push( + OutlivesConstraint { + sup: src_lt, + sub: dst_lt, + locations: location.to_locations(), + span: location.to_locations().span(self.body), + category: ConstraintCategory::Cast { + is_raw_ptr_dyn_type_cast: true, + is_implicit_coercion: false, + unsize_to: None, + }, + variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, + }, + ); + } + (None, Some(_)) => bug!( + "introducing a principal should have errored in HIR typeck" ), - // FIXME: Once we disallow casting `*const dyn Trait + 'short` - // to `*const dyn Trait + 'long`, then this can just be `src_lt`. - dst_lt, - ); - let dst_obj = Ty::new_dynamic( - tcx, - tcx.mk_poly_existential_predicates( - &dst_tty.without_auto_traits().collect::>(), - ), - dst_lt, - ); - - debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); - - self.sub_types( - src_obj, - dst_obj, - location.to_locations(), - ConstraintCategory::Cast { - is_implicit_coercion: false, - unsize_to: None, - }, - ) - .unwrap(); + (Some(_), None) => { + bug!("dropping the principal should have been an unsizing cast") + } + } } } CastKind::Transmute => { @@ -1659,12 +1678,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let def_id = uv.def; if tcx.def_kind(def_id) == DefKind::InlineConst { let def_id = def_id.expect_local(); - let predicates = self.prove_closure_bounds( - tcx, - def_id, - uv.args, - location.to_locations(), - ); + let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location); self.normalize_and_prove_instantiated_predicates( def_id.to_def_id(), predicates, @@ -2206,9 +2220,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | Rvalue::Ref(..) | Rvalue::RawPtr(..) | Rvalue::Cast(..) - | Rvalue::ShallowInitBox(..) | Rvalue::BinaryOp(..) - | Rvalue::NullaryOp(..) | Rvalue::CopyForDeref(..) | Rvalue::UnaryOp(..) | Rvalue::Discriminant(..) @@ -2448,15 +2460,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // clauses on the struct. AggregateKind::Closure(def_id, args) | AggregateKind::CoroutineClosure(def_id, args) - | AggregateKind::Coroutine(def_id, args) => ( - def_id, - self.prove_closure_bounds( - tcx, - def_id.expect_local(), - args, - location.to_locations(), - ), - ), + | AggregateKind::Coroutine(def_id, args) => { + (def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location)) + } AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => { (CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty()) @@ -2475,12 +2481,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { tcx: TyCtxt<'tcx>, def_id: LocalDefId, args: GenericArgsRef<'tcx>, - locations: Locations, + location: Location, ) -> ty::InstantiatedPredicates<'tcx> { let root_def_id = self.root_cx.root_def_id(); // We will have to handle propagated closure requirements for this closure, // but need to defer this until the nested body has been fully borrow checked. - self.deferred_closure_requirements.push((def_id, args, locations)); + self.deferred_closure_requirements.push((def_id, args, location.to_locations())); // Equate closure args to regions inherited from `root_def_id`. Fixes #98589. let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, root_def_id); @@ -2504,7 +2510,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Err(_) = self.eq_args( typeck_root_args, parent_args, - locations, + location.to_locations(), ConstraintCategory::BoringNoLocation, ) { span_mirbug!( diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 7ac2dff12f75..e2d684e12a81 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; +use rustc_hir::def_id::DefId; use rustc_infer::infer::relate::{ PredicateEmittingRelation, Relate, RelateResult, StructurallyRelateAliases, TypeRelation, }; @@ -9,7 +10,8 @@ use rustc_infer::traits::solve::Goal; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::query::NoSolution; -use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}; +use rustc_middle::ty::relate::combine::{combine_ty_args, super_combine_consts, super_combine_tys}; +use rustc_middle::ty::relate::relate_args_invariantly; use rustc_middle::ty::{self, FnMutDelegate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; @@ -172,7 +174,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { let infcx = self.type_checker.infcx; let mut lazy_universe = None; let delegate = FnMutDelegate { - regions: &mut |br: ty::BoundRegion| { + regions: &mut |br: ty::BoundRegion<'tcx>| { // The first time this closure is called, create a // new universe for the placeholders we will make // from here out. @@ -182,17 +184,17 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { universe }); - let placeholder = ty::PlaceholderRegion { universe, bound: br }; + let placeholder = ty::PlaceholderRegion::new(universe, br); debug!(?placeholder); let placeholder_reg = self.next_placeholder_region(placeholder); debug!(?placeholder_reg); placeholder_reg }, - types: &mut |_bound_ty: ty::BoundTy| { + types: &mut |_bound_ty: ty::BoundTy<'tcx>| { unreachable!("we only replace regions in nll_relate, not types") }, - consts: &mut |_bound_const: ty::BoundConst| { + consts: &mut |_bound_const: ty::BoundConst<'tcx>| { unreachable!("we only replace regions in nll_relate, not consts") }, }; @@ -216,7 +218,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { let infcx = self.type_checker.infcx; let mut reg_map = FxHashMap::default(); let delegate = FnMutDelegate { - regions: &mut |br: ty::BoundRegion| { + regions: &mut |br: ty::BoundRegion<'tcx>| { if let Some(ex_reg_var) = reg_map.get(&br) { *ex_reg_var } else { @@ -228,10 +230,10 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { ex_reg_var } }, - types: &mut |_bound_ty: ty::BoundTy| { + types: &mut |_bound_ty: ty::BoundTy<'tcx>| { unreachable!("we only replace regions in nll_relate, not types") }, - consts: &mut |_bound_const: ty::BoundConst| { + consts: &mut |_bound_const: ty::BoundConst<'tcx>| { unreachable!("we only replace regions in nll_relate, not consts") }, }; @@ -255,7 +257,10 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { } #[instrument(skip(self), level = "debug")] - fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> { + fn next_placeholder_region( + &mut self, + placeholder: ty::PlaceholderRegion<'tcx>, + ) -> ty::Region<'tcx> { let reg = self.type_checker.constraints.placeholder_region(self.type_checker.infcx, placeholder); @@ -263,7 +268,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> { ty::BoundRegionKind::Anon => sym::anon, ty::BoundRegionKind::Named(def_id) => self.type_checker.tcx().item_name(def_id), ty::BoundRegionKind::ClosureEnv => sym::env, - ty::BoundRegionKind::NamedAnon(_) => bug!("only used for pretty printing"), + ty::BoundRegionKind::NamedForPrinting(_) => bug!("only used for pretty printing"), }; if cfg!(debug_assertions) { @@ -303,6 +308,35 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { self.type_checker.infcx.tcx } + fn relate_ty_args( + &mut self, + a_ty: Ty<'tcx>, + b_ty: Ty<'tcx>, + def_id: DefId, + a_args: ty::GenericArgsRef<'tcx>, + b_args: ty::GenericArgsRef<'tcx>, + _: impl FnOnce(ty::GenericArgsRef<'tcx>) -> Ty<'tcx>, + ) -> RelateResult<'tcx, Ty<'tcx>> { + if self.ambient_variance == ty::Invariant { + // Avoid fetching the variance if we are in an invariant context, + // slightly improves perf. + relate_args_invariantly(self, a_args, b_args)?; + Ok(a_ty) + } else { + let variances = self.cx().variances_of(def_id); + combine_ty_args( + &self.type_checker.infcx.infcx, + self, + a_ty, + b_ty, + variances, + a_args, + b_args, + |_| a_ty, + ) + } + } + #[instrument(skip(self, info), level = "trace", ret)] fn relate_with_variance>>( &mut self, @@ -328,7 +362,7 @@ impl<'b, 'tcx> TypeRelation> for NllTypeRelating<'_, 'b, 'tcx> { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { let infcx = self.type_checker.infcx; - let a = self.type_checker.infcx.shallow_resolve(a); + let a = infcx.shallow_resolve(a); assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b); if a == b { diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 64a7b4084349..aeba5ee70cf1 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -1,20 +1,16 @@ //! Code to extract the universally quantified regions declared on a -//! function and the relationships between them. For example: +//! function. For example: //! //! ``` //! fn foo<'a, 'b, 'c: 'b>() { } //! ``` //! //! here we would return a map assigning each of `{'a, 'b, 'c}` -//! to an index, as well as the `FreeRegionMap` which can compute -//! relationships between them. +//! to an index. //! //! The code in this file doesn't *do anything* with those results; it //! just returns them for other code to use. -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::untranslatable_diagnostic)] - use std::cell::Cell; use std::iter; @@ -208,10 +204,10 @@ struct UniversalRegionIndices<'tcx> { /// `ty::Region` to the internal `RegionVid` we are using. This is /// used because trait matching and type-checking will feed us /// region constraints that reference those regions and we need to - /// be able to map them to our internal `RegionVid`. This is - /// basically equivalent to an `GenericArgs`, except that it also - /// contains an entry for `ReStatic` -- it might be nice to just - /// use an args, and then handle `ReStatic` another way. + /// be able to map them to our internal `RegionVid`. + /// + /// This is similar to just using `GenericArgs`, except that it contains + /// an entry for `'static`, and also late bound parameters in scope. indices: FxIndexMap, RegionVid>, /// The vid assigned to `'static`. Used only for diagnostics. @@ -271,8 +267,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// Creates a new and fully initialized `UniversalRegions` that /// contains indices for all the free regions found in the given /// MIR -- that is, all the regions that appear in the function's - /// signature. This will also compute the relationships that are - /// known between those regions. + /// signature. pub(crate) fn new(infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId) -> Self { UniversalRegionsBuilder { infcx, mir_def }.build() } @@ -454,8 +449,6 @@ struct UniversalRegionsBuilder<'infcx, 'tcx> { mir_def: LocalDefId, } -const FR: NllRegionVariableOrigin = NllRegionVariableOrigin::FreeRegion; - impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { fn build(self) -> UniversalRegions<'tcx> { debug!("build(mir_def={:?})", self.mir_def); @@ -466,8 +459,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars()); // Create the "global" region that is always free in all contexts: 'static. - let fr_static = - self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(kw::Static)).as_var(); + let fr_static = self + .infcx + .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::Free(kw::Static) + }) + .as_var(); // We've now added all the global regions. The next ones we // add will be external. @@ -500,7 +497,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { debug!(?r); let region_vid = { let name = r.get_name_or_anon(self.infcx.tcx); - self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name)) + self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::LateBound(name) + }) }; debug!(?region_vid); @@ -526,7 +525,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let r = ty::Region::new_late_param(self.infcx.tcx, self.mir_def.to_def_id(), kind); let region_vid = { let name = r.get_name_or_anon(self.infcx.tcx); - self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name)) + self.infcx.next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::LateBound(name) + }) }; debug!(?region_vid); @@ -539,38 +540,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { &indices, ); - let (unnormalized_output_ty, mut unnormalized_input_tys) = + let (unnormalized_output_ty, unnormalized_input_tys) = inputs_and_output.split_last().unwrap(); - // C-variadic fns also have a `VaList` input that's not listed in the signature - // (as it's created inside the body itself, not passed in from outside). - if let DefiningTy::FnDef(def_id, _) = defining_ty { - if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { - let va_list_did = self - .infcx - .tcx - .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def)); - - let reg_vid = self - .infcx - .next_nll_region_var(FR, || RegionCtxt::Free(sym::c_dash_variadic)) - .as_var(); - - let region = ty::Region::new_var(self.infcx.tcx, reg_vid); - let va_list_ty = self - .infcx - .tcx - .type_of(va_list_did) - .instantiate(self.infcx.tcx, &[region.into()]); - - unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter( - unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)), - ); - } - } - - let fr_fn_body = - self.infcx.next_nll_region_var(FR, || RegionCtxt::Free(sym::fn_body)).as_var(); + let fr_fn_body = self + .infcx + .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::Free(sym::fn_body) + }) + .as_var(); let num_universals = self.infcx.num_region_vars(); @@ -613,8 +591,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { debug!("defining_ty (pre-replacement): {:?}", defining_ty); - let defining_ty = - self.infcx.replace_free_regions_with_nll_infer_vars(FR, defining_ty); + let defining_ty = self.infcx.replace_free_regions_with_nll_infer_vars( + NllRegionVariableOrigin::FreeRegion, + defining_ty, + ); match *defining_ty.kind() { ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args), @@ -634,15 +614,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => { let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.to_def_id() == typeck_root_def_id - // Do not ICE when checking default_field_values consts with lifetimes (#135649) - && DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id)) - { - let args = - self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_args); + if self.mir_def.to_def_id() == typeck_root_def_id { + let args = self.infcx.replace_free_regions_with_nll_infer_vars( + NllRegionVariableOrigin::FreeRegion, + identity_args, + ); DefiningTy::Const(self.mir_def.to_def_id(), args) } else { - // FIXME this line creates a dependency between borrowck and typeck. + // FIXME: this line creates a query dependency between borrowck and typeck. // // This is required for `AscribeUserType` canonical query, which will call // `type_of(inline_const_def_id)`. That `type_of` would inject erased lifetimes @@ -659,7 +638,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { InlineConstArgsParts { parent_args: identity_args, ty }, ) .args; - let args = self.infcx.replace_free_regions_with_nll_infer_vars(FR, args); + let args = self.infcx.replace_free_regions_with_nll_infer_vars( + NllRegionVariableOrigin::FreeRegion, + args, + ); DefiningTy::InlineConst(self.mir_def.to_def_id(), args) } } @@ -680,30 +662,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id); - let fr_args = match defining_ty { - DefiningTy::Closure(_, args) - | DefiningTy::CoroutineClosure(_, args) - | DefiningTy::Coroutine(_, args) - | DefiningTy::InlineConst(_, args) => { - // In the case of closures, we rely on the fact that - // the first N elements in the ClosureArgs are - // inherited from the `typeck_root_def_id`. - // Therefore, when we zip together (below) with - // `identity_args`, we will get only those regions - // that correspond to early-bound regions declared on - // the `typeck_root_def_id`. - assert!(args.len() >= identity_args.len()); - assert_eq!(args.regions().count(), identity_args.regions().count()); - args - } - - DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args, - - DefiningTy::GlobalAsm(_) => ty::List::empty(), - }; + let renumbered_args = defining_ty.args(); let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); - let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var())); + // This relies on typeck roots being generics_of parents with their + // parameters at the start of nested bodies' generics. + assert!(renumbered_args.len() >= identity_args.len()); + let arg_mapping = + iter::zip(identity_args.regions(), renumbered_args.regions().map(|r| r.as_var())); UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), @@ -818,7 +784,40 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::FnDef(def_id, _) => { let sig = tcx.fn_sig(def_id).instantiate_identity(); let sig = indices.fold_to_region_vids(tcx, sig); - sig.inputs_and_output() + let inputs_and_output = sig.inputs_and_output(); + + // C-variadic fns also have a `VaList` input that's not listed in the signature + // (as it's created inside the body itself, not passed in from outside). + if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { + let va_list_did = self + .infcx + .tcx + .require_lang_item(LangItem::VaList, self.infcx.tcx.def_span(self.mir_def)); + + let reg_vid = self + .infcx + .next_nll_region_var(NllRegionVariableOrigin::FreeRegion, || { + RegionCtxt::Free(sym::c_dash_variadic) + }) + .as_var(); + + let region = ty::Region::new_var(self.infcx.tcx, reg_vid); + let va_list_ty = self + .infcx + .tcx + .type_of(va_list_did) + .instantiate(self.infcx.tcx, &[region.into()]); + + // The signature needs to follow the order [input_tys, va_list_ty, output_ty] + return inputs_and_output.map_bound(|tys| { + let (output_ty, input_tys) = tys.split_last().unwrap(); + tcx.mk_type_list_from_iter( + input_tys.iter().copied().chain([va_list_ty, *output_ty]), + ) + }); + } + + inputs_and_output } DefiningTy::Const(def_id, _) => { @@ -843,8 +842,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { }; // FIXME(#129952): We probably want a more principled approach here. - if let Err(terr) = inputs_and_output.skip_binder().error_reported() { - self.infcx.set_tainted_by_errors(terr); + if let Err(e) = inputs_and_output.error_reported() { + self.infcx.set_tainted_by_errors(e); } inputs_and_output @@ -856,7 +855,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> { #[instrument(skip(self), level = "debug")] fn replace_free_regions_with_nll_infer_vars( &self, - origin: NllRegionVariableOrigin, + origin: NllRegionVariableOrigin<'tcx>, value: T, ) -> T where diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index ce9a3ce3f248..dd84a2c1802d 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -15,7 +15,6 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl deleted file mode 100644 index 86671d0326da..000000000000 --- a/compiler/rustc_builtin_macros/messages.ftl +++ /dev/null @@ -1,306 +0,0 @@ -builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function -builtin_macros_alloc_must_statics = allocators must be statics - -builtin_macros_asm_attribute_not_supported = - this attribute is not supported on assembly - -builtin_macros_asm_clobber_abi = clobber_abi -builtin_macros_asm_clobber_no_reg = asm with `clobber_abi` must specify explicit registers for outputs -builtin_macros_asm_clobber_outputs = generic outputs - -builtin_macros_asm_duplicate_arg = duplicate argument named `{$name}` - .label = previously here - .arg = duplicate argument - -builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names - -builtin_macros_asm_mayunwind = asm labels are not allowed with the `may_unwind` option - -builtin_macros_asm_modifier_invalid = asm template modifier must be a single character - -builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive - -builtin_macros_asm_no_matched_argument_name = there is no argument named `{$name}` - -builtin_macros_asm_noreturn = asm outputs are not allowed with the `noreturn` option - -builtin_macros_asm_opt_already_provided = the `{$symbol}` option was already provided - .label = this option was already provided - .suggestion = remove this option - -builtin_macros_asm_pos_after = positional arguments cannot follow named arguments or explicit register arguments - .pos = positional argument - .named = named argument - .explicit = explicit register argument - -builtin_macros_asm_pure_combine = the `pure` option must be combined with either `nomem` or `readonly` - -builtin_macros_asm_pure_no_output = asm with the `pure` option must have at least one output - -builtin_macros_asm_unsupported_clobber_abi = `clobber_abi` cannot be used with `{$macro_name}!` - -builtin_macros_asm_unsupported_option = the `{$symbol}` option cannot be used with `{$macro_name}!` - .label = the `{$symbol}` option is not meaningful for global-scoped inline assembly - .suggestion = remove this option - -builtin_macros_assert_missing_comma = unexpected string literal - .suggestion = try adding a comma - -builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument - .label = boolean expression required - -builtin_macros_assert_requires_expression = macro requires an expression as an argument - .suggestion = try removing semicolon - -builtin_macros_autodiff = autodiff must be applied to function -builtin_macros_autodiff_missing_config = autodiff requires at least a name and mode -builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode -builtin_macros_autodiff_not_build = this rustc version does not support autodiff -builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found} -builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode -builtin_macros_autodiff_ty_activity = {$act} can not be used for this type -builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}` - -builtin_macros_autodiff_width = autodiff width must fit u32, but is {$width} - -builtin_macros_avoid_att_syntax = avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - -builtin_macros_avoid_intel_syntax = avoid using `.intel_syntax`, Intel syntax is the default - -builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s - .label = not applicable here - .label2 = not a `struct`, `enum` or `union` - -builtin_macros_bench_sig = functions used as benches must have signature `fn(&mut Bencher) -> impl Termination` - - -builtin_macros_cannot_derive_union = this trait cannot be derived for unions - -builtin_macros_cfg_accessible_has_args = `cfg_accessible` path cannot accept arguments - -builtin_macros_cfg_accessible_indeterminate = cannot determine whether the path is accessible or not - -builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a literal -builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified -builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified - -builtin_macros_cfg_select_no_matches = none of the predicates in this `cfg_select` evaluated to true - -builtin_macros_cfg_select_unreachable = unreachable predicate - .label = always matches - .label2 = this predicate is never reached - -builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized` - -builtin_macros_coerce_pointee_requires_one_field = `CoercePointee` can only be derived on `struct`s with at least one field - -builtin_macros_coerce_pointee_requires_one_generic = `CoercePointee` can only be derived on `struct`s that are generic over at least one type - -builtin_macros_coerce_pointee_requires_one_pointee = exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits - -builtin_macros_coerce_pointee_requires_transparent = `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]` - -builtin_macros_coerce_pointee_too_many_pointees = only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits - .label = here another type parameter is marked as `#[pointee]` - - -builtin_macros_concat_bytes_array = cannot concatenate doubly nested array - .note = byte strings are treated as arrays of bytes - .help = try flattening the array - -builtin_macros_concat_bytes_bad_repeat = repeat count is not a positive number - -builtin_macros_concat_bytes_invalid = cannot concatenate {$lit_kind} literals - .byte_char = try using a byte character - .byte_str = try using a byte string - .c_str = try using a null-terminated byte string - .c_str_note = concatenating C strings is ambiguous about including the '\0' - .number_array = try wrapping the number in an array - -builtin_macros_concat_bytes_missing_literal = expected a byte literal - .note = only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()` - -builtin_macros_concat_bytes_non_u8 = numeric literal is not a `u8` - -builtin_macros_concat_bytes_oob = numeric literal is out of bounds - -builtin_macros_concat_bytestr = cannot concatenate a byte string literal -builtin_macros_concat_c_str_lit = cannot concatenate a C string literal - -builtin_macros_concat_missing_literal = expected a literal - .note = only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()` - -builtin_macros_default_arg = `#[default]` attribute does not accept a value - .suggestion = try using `#[default]` - -builtin_macros_derive_from_usage_note = `#[derive(From)]` can only be used on structs with exactly one field - -builtin_macros_derive_from_wrong_field_count = `#[derive(From)]` used on a struct with {$multiple_fields -> - [true] multiple fields - *[false] no fields -} - -builtin_macros_derive_from_wrong_target = `#[derive(From)]` used on {$kind} - -builtin_macros_derive_macro_call = `derive` cannot be used on items with type macros - -builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept arguments - .suggestion = remove the arguments - -builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values - .suggestion = remove the value - -builtin_macros_duplicate_macro_attribute = duplicated attribute - -builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time - .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead - .cargo_typo = there is a similar Cargo environment variable: `{$suggested_var}` - .custom = use `std::env::var({$var_expr})` to read the variable at run time - -builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Unicode string - -builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments - -builtin_macros_expected_comma_in_list = expected token: `,` - -builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern - -builtin_macros_expected_other = expected operand, {$is_inline_asm -> - [false] options - *[true] clobber_abi, options - }, or additional template string - -builtin_macros_export_macro_rules = cannot export macro_rules! macros from a `proc-macro` crate type currently - -builtin_macros_format_duplicate_arg = duplicate argument named `{$ident}` - .label1 = previously here - .label2 = duplicate argument - -builtin_macros_format_no_arg_named = there is no argument named `{$name}` - .note = did you intend to capture a variable `{$name}` from the surrounding scope? - .note2 = to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro - -builtin_macros_format_pos_mismatch = {$n} positional {$n -> - [one] argument - *[more] arguments - } in format string, but {$desc} - -builtin_macros_format_positional_after_named = positional arguments cannot follow named arguments - .label = positional arguments must be before named arguments - .named_args = named argument - -builtin_macros_format_redundant_args = redundant {$n -> - [one] argument - *[more] arguments - } - .help = {$n -> - [one] the formatting string already captures the binding directly, it doesn't need to be included in the argument list - *[more] the formatting strings already captures the bindings directly, they don't need to be included in the argument list - } - .note = {$n -> - [one] the formatting specifier is referencing the binding already - *[more] the formatting specifiers are referencing the bindings already - } - .suggestion = this can be removed - -builtin_macros_format_remove_raw_ident = remove the `r#` - -builtin_macros_format_reorder_format_parameter = did you mean `{$replacement}`? - -builtin_macros_format_requires_string = requires at least a format string argument - -builtin_macros_format_string_invalid = invalid format string: {$desc} - .label = {$label1} in format string - .note = {$note} - .second_label = {$label} - -builtin_macros_format_unknown_trait = unknown format trait `{$ty}` - .note = the only appropriate formatting traits are: - - ``, which uses the `Display` trait - - `?`, which uses the `Debug` trait - - `e`, which uses the `LowerExp` trait - - `E`, which uses the `UpperExp` trait - - `o`, which uses the `Octal` trait - - `p`, which uses the `Pointer` trait - - `b`, which uses the `Binary` trait - - `x`, which uses the `LowerHex` trait - - `X`, which uses the `UpperHex` trait - .suggestion = use the `{$trait_name}` trait - -builtin_macros_format_unused_arg = {$named -> - [true] named argument - *[false] argument - } never used - -builtin_macros_format_unused_args = multiple unused formatting arguments - .label = multiple missing formatting specifiers - -builtin_macros_format_use_positional = consider using a positional formatting argument instead - -builtin_macros_incomplete_include = include macro expected single expression in source - -builtin_macros_multiple_default_attrs = multiple `#[default]` attributes - .note = only one `#[default]` attribute is needed - .label = `#[default]` used here - .label_again = `#[default]` used again here - .help = try removing {$only_one -> - [true] this - *[false] these - } - -builtin_macros_multiple_defaults = multiple declared defaults - .label = first default - .additional = additional default - .note = only one variant can be default - .suggestion = make `{$ident}` default - -builtin_macros_naked_functions_testing_attribute = - cannot use `#[unsafe(naked)]` with testing attributes - .label = function marked with testing attribute here - .naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes - -builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]` - .label = this enum needs a unit variant marked with `#[default]` - .suggestion = make this unit variant default by placing `#[default]` on it - -builtin_macros_non_exhaustive_default = default variant must be exhaustive - .label = declared `#[non_exhaustive]` here - .help = consider a manual implementation of `Default` - -builtin_macros_non_generic_pointee = the `#[pointee]` attribute may only be used on generic parameters - -builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants{$post} - .help = consider a manual implementation of `Default` - -builtin_macros_only_one_argument = {$name} takes 1 argument - -builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]` - -builtin_macros_proc_macro_attribute_only_usable_with_crate_type = the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type - -builtin_macros_requires_cfg_pattern = - macro requires a cfg-pattern as an argument - .label = cfg-pattern required - -builtin_macros_source_utils_expected_item = expected item, found `{$token}` - -builtin_macros_takes_no_arguments = {$name} takes no arguments - -builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests - .label = `{$kind}` because of this - -builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items - -builtin_macros_test_runner_invalid = `test_runner` argument must be a path -builtin_macros_test_runner_nargs = `#![test_runner(..)]` accepts exactly 1 argument - -builtin_macros_tests_not_support = building tests with panic=abort is not supported without `-Zpanic_abort_tests` - -builtin_macros_trace_macros = trace_macros! accepts only `true` or `false` - -builtin_macros_unexpected_lit = expected path to a trait, found literal - .label = not a trait - .str_lit = try using `#[derive({$sym})]` - .other = for example, write `#[derive(Debug)]` for `Debug` - -builtin_macros_unnameable_test_items = cannot test inner items diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index e5d9d2080c08..5f78758513e1 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -43,7 +43,7 @@ pub(crate) fn expand( // Generate anonymous constant serving as container for the allocator methods. let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); - let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); + let const_body = ast::ConstItemRhsKind::new_body(ecx.expr_block(ecx.block(span, stmts))); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) @@ -83,13 +83,14 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span let body = Some(cx.block_expr(call)); let kind = ItemKind::Fn(Box::new(Fn { - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, sig, ident: Ident::from_str_and_span(&global_fn_name(ALLOC_ERROR_HANDLER), span), generics: Generics::default(), contract: None, body, define_opaque: None, + eii_impls: ThinVec::new(), })); let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 2958686f86cd..62a39d957b9c 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -288,6 +288,18 @@ fn expand_preparsed_asm( let msg = "asm template must be a string literal"; let template_sp = template_expr.span; let template_is_mac_call = matches!(template_expr.kind, ast::ExprKind::MacCall(_)); + + // Gets the span inside `template_sp` corresponding to the given range + let span_in_template = |range: std::ops::Range| -> Span { + if template_is_mac_call { + // When the template is a macro call we can't reliably get inner spans + // so just use the entire template span (see ICEs #129503, #131292) + template_sp + } else { + template_sp.from_inner(InnerSpan::new(range.start, range.end)) + } + }; + let ExprToSpannedString { symbol: template_str, style: template_style, @@ -382,13 +394,8 @@ fn expand_preparsed_asm( if !parser.errors.is_empty() { let err = parser.errors.remove(0); - let err_sp = if template_is_mac_call { - // If the template is a macro call we can't reliably point to the error's - // span so just use the template's span as the error span (fixes #129503) - template_span - } else { - template_span.from_inner(InnerSpan::new(err.span.start, err.span.end)) - }; + + let err_sp = span_in_template(err.span); let msg = format!("invalid asm template string: {}", err.description); let mut e = ecx.dcx().struct_span_err(err_sp, msg); @@ -397,8 +404,7 @@ fn expand_preparsed_asm( e.note(note); } if let Some((label, span)) = err.secondary_label { - let err_sp = template_span.from_inner(InnerSpan::new(span.start, span.end)); - e.span_label(err_sp, label); + e.span_label(span_in_template(span), label); } let guar = e.emit(); return ExpandResult::Ready(Err(guar)); @@ -477,8 +483,7 @@ fn expand_preparsed_asm( ecx.dcx() .create_err(errors::AsmNoMatchedArgumentName { name: name.to_owned(), - span: template_span - .from_inner(InnerSpan::new(span.start, span.end)), + span: span_in_template(span), }) .emit(); None @@ -490,11 +495,7 @@ fn expand_preparsed_asm( let mut chars = arg.format.ty.chars(); let mut modifier = chars.next(); if chars.next().is_some() { - let span = arg - .format - .ty_span - .map(|sp| template_sp.from_inner(InnerSpan::new(sp.start, sp.end))) - .unwrap_or(template_sp); + let span = arg.format.ty_span.map(span_in_template).unwrap_or(template_sp); ecx.dcx().emit_err(errors::AsmModifierInvalid { span }); modifier = None; } diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 31855cbd4e6c..21b20e2bb974 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -315,7 +315,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::Path(_, _) | ExprKind::Ret(_) | ExprKind::Try(_) - | ExprKind::TryBlock(_) + | ExprKind::TryBlock(_, _) | ExprKind::Type(_, _) | ExprKind::Underscore | ExprKind::While(_, _, _) diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index ddc59bfe1414..264f797a7825 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -17,7 +17,7 @@ mod llvm_enzyme { use rustc_ast::{ self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemKind, BindingMode, FnRetTy, FnSig, GenericArg, GenericArgs, GenericParamKind, Generics, ItemKind, - MetaItemInner, PatKind, Path, PathSegment, TyKind, Visibility, + MetaItemInner, MgcaDisambiguation, PatKind, Path, PathSegment, TyKind, Visibility, }; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::{Ident, Span, Symbol, sym}; @@ -209,11 +209,6 @@ mod llvm_enzyme { mut item: Annotatable, mode: DiffMode, ) -> Vec { - // FIXME(bjorn3) maybe have the backend directly tell if autodiff is supported? - if cfg!(not(feature = "llvm_enzyme")) { - ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span }); - return vec![item]; - } let dcx = ecx.sess.dcx(); // first get information about the annotable item: visibility, signature, name and generic @@ -339,13 +334,14 @@ mod llvm_enzyme { // The first element of it is the name of the function to be generated let d_fn = Box::new(ast::Fn { - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, sig: d_sig, ident: first_ident(&meta_item_vec[0]), generics, contract: None, body: Some(d_body), define_opaque: None, + eii_impls: ThinVec::new(), }); let mut rustc_ad_attr = Box::new(ast::NormalAttr::from_ident(Ident::with_dummy_span(sym::rustc_autodiff))); @@ -362,7 +358,7 @@ mod llvm_enzyme { let inline_item = ast::AttrItem { unsafety: ast::Safety::Default, path: ast::Path::from_ident(Ident::with_dummy_span(sym::inline)), - args: ast::AttrArgs::Delimited(never_arg), + args: rustc_ast::ast::AttrItemKind::Unparsed(ast::AttrArgs::Delimited(never_arg)), tokens: None, }; let inline_never_attr = Box::new(ast::NormalAttr { item: inline_item, tokens: None }); @@ -425,11 +421,13 @@ mod llvm_enzyme { } }; // Now update for d_fn - rustc_ad_attr.item.args = rustc_ast::AttrArgs::Delimited(rustc_ast::DelimArgs { - dspan: DelimSpan::dummy(), - delim: rustc_ast::token::Delimiter::Parenthesis, - tokens: ts, - }); + rustc_ad_attr.item.args = rustc_ast::ast::AttrItemKind::Unparsed( + rustc_ast::AttrArgs::Delimited(rustc_ast::DelimArgs { + dspan: DelimSpan::dummy(), + delim: rustc_ast::token::Delimiter::Parenthesis, + tokens: ts, + }), + ); let new_id = ecx.sess.psess.attr_id_generator.mk_attr_id(); let d_attr = outer_normal_attr(&rustc_ad_attr, new_id, span); @@ -558,7 +556,11 @@ mod llvm_enzyme { } GenericParamKind::Const { .. } => { let expr = ecx.expr_path(ast::Path::from_ident(p.ident)); - let anon_const = AnonConst { id: ast::DUMMY_NODE_ID, value: expr }; + let anon_const = AnonConst { + id: ast::DUMMY_NODE_ID, + value: expr, + mgca_disambiguation: MgcaDisambiguation::Direct, + }; Some(AngleBracketedArg::Arg(GenericArg::Const(anon_const))) } GenericParamKind::Lifetime { .. } => None, @@ -813,6 +815,7 @@ mod llvm_enzyme { let anon_const = rustc_ast::AnonConst { id: ast::DUMMY_NODE_ID, value: ecx.expr_usize(span, 1 + x.width as usize), + mgca_disambiguation: MgcaDisambiguation::Direct, }; TyKind::Array(ty.clone(), anon_const) }; @@ -827,6 +830,7 @@ mod llvm_enzyme { let anon_const = rustc_ast::AnonConst { id: ast::DUMMY_NODE_ID, value: ecx.expr_usize(span, x.width as usize), + mgca_disambiguation: MgcaDisambiguation::Direct, }; let kind = TyKind::Array(ty.clone(), anon_const); let ty = diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index b24e3065622d..3ebde949b99b 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -10,10 +10,11 @@ use rustc_attr_parsing::{ AttributeParser, CFG_TEMPLATE, ParsedDescription, ShouldEmit, parse_cfg_entry, }; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; -use rustc_hir::AttrPath; use rustc_hir::attrs::CfgEntry; +use rustc_hir::{AttrPath, Target}; use rustc_parse::exp; -use rustc_span::{ErrorGuaranteed, Ident, Span}; +use rustc_parse::parser::Recovery; +use rustc_span::{ErrorGuaranteed, Span, sym}; use crate::errors; @@ -26,13 +27,7 @@ pub(crate) fn expand_cfg( ExpandResult::Ready(match parse_cfg(cx, sp, tts) { Ok(cfg) => { - let matches_cfg = attr::eval_config_entry( - cx.sess, - &cfg, - cx.current_expansion.lint_node_id, - ShouldEmit::ErrorsAndLints, - ) - .as_bool(); + let matches_cfg = attr::eval_config_entry(cx.sess, &cfg).as_bool(); MacEager::expr(cx.expr_bool(sp, matches_cfg)) } @@ -46,20 +41,25 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result bool { impl<'ast> visit::Visitor<'ast> for CfgFinder { type Result = ControlFlow<()>; fn visit_attribute(&mut self, attr: &'ast Attribute) -> ControlFlow<()> { - if attr - .ident() - .is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr) - { + if attr.name().is_some_and(|name| name == sym::cfg || name == sym::cfg_attr) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) @@ -113,7 +110,8 @@ impl CfgEval<'_> { let res: PResult<'_, Annotatable> = try { match annotatable { Annotatable::Item(_) => { - let item = parser.parse_item(ForceCollect::Yes)?.unwrap(); + let item = + parser.parse_item(ForceCollect::Yes, AllowConstBlockItems::Yes)?.unwrap(); Annotatable::Item(self.flat_map_item(item).pop().unwrap()) } Annotatable::AssocItem(_, ctxt) => { diff --git a/compiler/rustc_builtin_macros/src/cfg_select.rs b/compiler/rustc_builtin_macros/src/cfg_select.rs index b77a121ca0b9..35098722a910 100644 --- a/compiler/rustc_builtin_macros/src/cfg_select.rs +++ b/compiler/rustc_builtin_macros/src/cfg_select.rs @@ -1,30 +1,63 @@ use rustc_ast::tokenstream::TokenStream; +use rustc_ast::{Expr, ast}; use rustc_attr_parsing as attr; -use rustc_attr_parsing::{ - CfgSelectBranches, CfgSelectPredicate, EvalConfigResult, ShouldEmit, parse_cfg_select, -}; -use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; +use rustc_attr_parsing::{CfgSelectBranches, EvalConfigResult, parse_cfg_select}; +use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacResult, MacroExpanderResult}; use rustc_span::{Ident, Span, sym}; +use smallvec::SmallVec; -use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable}; +use crate::errors::CfgSelectNoMatches; -/// Selects the first arm whose predicate evaluates to true. -fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> { - let mut result = None; - for (cfg, tt, arm_span) in branches.reachable { - if let EvalConfigResult::True = attr::eval_config_entry( - &ecx.sess, - &cfg, - ecx.current_expansion.lint_node_id, - ShouldEmit::ErrorsAndLints, - ) { - // FIXME(#149215) Ideally we should short-circuit here, but `eval_config_entry` currently emits lints so we cannot do this yet. - result.get_or_insert((tt, arm_span)); - } +/// This intermediate structure is used to emit parse errors for the branches that are not chosen. +/// The `MacResult` instance below parses all branches, emitting any errors it encounters, but only +/// keeps the parse result for the selected branch. +struct CfgSelectResult<'cx, 'sess> { + ecx: &'cx mut ExtCtxt<'sess>, + site_span: Span, + selected_tts: TokenStream, + selected_span: Span, + other_branches: CfgSelectBranches, +} + +fn tts_to_mac_result<'cx, 'sess>( + ecx: &'cx mut ExtCtxt<'sess>, + site_span: Span, + tts: TokenStream, + span: Span, +) -> Box { + match ExpandResult::from_tts(ecx, tts, site_span, span, Ident::with_dummy_span(sym::cfg_select)) + { + ExpandResult::Ready(x) => x, + _ => unreachable!("from_tts always returns Ready"), } +} - let wildcard = branches.wildcard.map(|(_, tt, span)| (tt, span)); - result.or(wildcard) +macro_rules! forward_to_parser_any_macro { + ($method_name:ident, $ret_ty:ty) => { + fn $method_name(self: Box) -> Option<$ret_ty> { + let CfgSelectResult { ecx, site_span, selected_tts, selected_span, .. } = *self; + + for (tts, span) in self.other_branches.into_iter_tts() { + let _ = tts_to_mac_result(ecx, site_span, tts, span).$method_name(); + } + + tts_to_mac_result(ecx, site_span, selected_tts, selected_span).$method_name() + } + }; +} + +impl<'cx, 'sess> MacResult for CfgSelectResult<'cx, 'sess> { + forward_to_parser_any_macro!(make_expr, Box); + forward_to_parser_any_macro!(make_stmts, SmallVec<[ast::Stmt; 1]>); + forward_to_parser_any_macro!(make_items, SmallVec<[Box; 1]>); + + forward_to_parser_any_macro!(make_impl_items, SmallVec<[Box; 1]>); + forward_to_parser_any_macro!(make_trait_impl_items, SmallVec<[Box; 1]>); + forward_to_parser_any_macro!(make_trait_items, SmallVec<[Box; 1]>); + forward_to_parser_any_macro!(make_foreign_items, SmallVec<[Box; 1]>); + + forward_to_parser_any_macro!(make_ty, Box); + forward_to_parser_any_macro!(make_pat, Box); } pub(super) fn expand_cfg_select<'cx>( @@ -39,27 +72,18 @@ pub(super) fn expand_cfg_select<'cx>( Some(ecx.ecfg.features), ecx.current_expansion.lint_node_id, ) { - Ok(branches) => { - if let Some((underscore, _, _)) = branches.wildcard { - // Warn for every unreachable predicate. We store the fully parsed branch for rustfmt. - for (predicate, _, _) in &branches.unreachable { - let span = match predicate { - CfgSelectPredicate::Wildcard(underscore) => underscore.span, - CfgSelectPredicate::Cfg(cfg) => cfg.span(), - }; - let err = CfgSelectUnreachable { span, wildcard_span: underscore.span }; - ecx.dcx().emit_warn(err); - } - } - - if let Some((tts, arm_span)) = select_arm(ecx, branches) { - return ExpandResult::from_tts( + Ok(mut branches) => { + if let Some((selected_tts, selected_span)) = branches.pop_first_match(|cfg| { + matches!(attr::eval_config_entry(&ecx.sess, cfg), EvalConfigResult::True) + }) { + let mac = CfgSelectResult { ecx, - tts, - sp, - arm_span, - Ident::with_dummy_span(sym::cfg_select), - ); + selected_tts, + selected_span, + other_branches: branches, + site_span: sp, + }; + return ExpandResult::Ready(Box::new(mac)); } else { // Emit a compiler error when none of the predicates matched. let guar = ecx.dcx().emit_err(CfgSelectNoMatches { span: sp }); diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs index 7fc4b437c1d8..e2109caf2e59 100644 --- a/compiler/rustc_builtin_macros/src/compile_error.rs +++ b/compiler/rustc_builtin_macros/src/compile_error.rs @@ -19,9 +19,8 @@ pub(crate) fn expand_compile_error<'cx>( Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)), }; - #[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")] - #[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")] let guar = cx.dcx().span_err(sp, var.to_string()); + cx.resolver.mark_scope_with_compile_error(cx.current_expansion.lint_node_id); ExpandResult::Ready(DummyResult::any(sp, guar)) } diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index d6fdf088b0d1..1d9551f93a14 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -136,7 +136,7 @@ pub(crate) fn expand_deriving_coerce_pointee( of_trait: Some(Box::new(ast::TraitImplHeader { safety: ast::Safety::Default, polarity: ast::ImplPolarity::Positive, - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, trait_ref, })), constness: ast::Const::No, @@ -159,7 +159,7 @@ pub(crate) fn expand_deriving_coerce_pointee( of_trait: Some(Box::new(ast::TraitImplHeader { safety: ast::Safety::Default, polarity: ast::ImplPolarity::Positive, - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, trait_ref, })), constness: ast::Const::No, @@ -463,44 +463,44 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b> } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_transparent, code = E0802)] +#[diag("`CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`", code = E0802)] struct RequireTransparent { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_one_field, code = E0802)] +#[diag("`CoercePointee` can only be derived on `struct`s with at least one field", code = E0802)] struct RequireOneField { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_one_generic, code = E0802)] +#[diag("`CoercePointee` can only be derived on `struct`s that are generic over at least one type", code = E0802)] struct RequireOneGeneric { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_one_pointee, code = E0802)] +#[diag("exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits", code = E0802)] struct RequireOnePointee { #[primary_span] span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_too_many_pointees, code = E0802)] +#[diag("only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits", code = E0802)] struct TooManyPointees { #[primary_span] one: Span, - #[label] + #[label("here another type parameter is marked as `#[pointee]`")] another: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_coerce_pointee_requires_maybe_sized, code = E0802)] +#[diag("`derive(CoercePointee)` requires `{$name}` to be marked `?Sized`", code = E0802)] struct RequiresMaybeSized { #[primary_span] span: Span, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index baffc525d95a..5362bcde1aad 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -540,6 +540,7 @@ impl<'a> TraitDef<'a> { .filter(|a| { a.has_any_name(&[ sym::allow, + sym::expect, sym::warn, sym::deny, sym::forbid, @@ -613,7 +614,7 @@ impl<'a> TraitDef<'a> { }, attrs: ast::AttrVec::new(), kind: ast::AssocItemKind::Type(Box::new(ast::TyAlias { - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, ident, generics: Generics::default(), after_where_clause: ast::WhereClause::default(), @@ -638,27 +639,27 @@ impl<'a> TraitDef<'a> { GenericParamKind::Type { .. } => { // Extra restrictions on the generics parameters to the // type being derived upon. + let span = param.ident.span.with_ctxt(ctxt); let bounds: Vec<_> = self .additional_bounds .iter() .map(|p| { - cx.trait_bound( - p.to_path(cx, self.span, type_ident, generics), - self.is_const, - ) + cx.trait_bound(p.to_path(cx, span, type_ident, generics), self.is_const) }) .chain( // Add a bound for the current trait. - self.skip_path_as_bound - .not() - .then(|| cx.trait_bound(trait_path.clone(), self.is_const)), + self.skip_path_as_bound.not().then(|| { + let mut trait_path = trait_path.clone(); + trait_path.span = span; + cx.trait_bound(trait_path, self.is_const) + }), ) .chain({ // Add a `Copy` bound if required. if is_packed && self.needs_copy_as_bound_if_packed { let p = deriving::path_std!(marker::Copy); Some(cx.trait_bound( - p.to_path(cx, self.span, type_ident, generics), + p.to_path(cx, span, type_ident, generics), self.is_const, )) } else { @@ -671,7 +672,7 @@ impl<'a> TraitDef<'a> { ) .collect(); - cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None) + cx.typaram(span, param.ident, bounds, None) } GenericParamKind::Const { ty, span, .. } => { let const_nodefault_kind = GenericParamKind::Const { @@ -791,7 +792,8 @@ impl<'a> TraitDef<'a> { .collect(); // Create the type of `self`. - let path = cx.path_all(self.span, false, vec![type_ident], self_params); + let path = + cx.path_all(type_ident.span.with_ctxt(ctxt), false, vec![type_ident], self_params); let self_type = cx.ty_path(path); let rustc_const_unstable = cx.path_ident(self.span, Ident::new(sym::rustc_const_unstable, self.span)); @@ -807,24 +809,29 @@ impl<'a> TraitDef<'a> { rustc_ast::AttrItem { unsafety: Safety::Default, path: rustc_const_unstable, - args: AttrArgs::Delimited(DelimArgs { - dspan: DelimSpan::from_single(self.span), - delim: rustc_ast::token::Delimiter::Parenthesis, - tokens: [ - TokenKind::Ident(sym::feature, IdentIsRaw::No), - TokenKind::Eq, - TokenKind::lit(LitKind::Str, sym::derive_const, None), - TokenKind::Comma, - TokenKind::Ident(sym::issue, IdentIsRaw::No), - TokenKind::Eq, - TokenKind::lit(LitKind::Str, sym::derive_const_issue, None), - ] - .into_iter() - .map(|kind| { - TokenTree::Token(Token { kind, span: self.span }, Spacing::Alone) - }) - .collect(), - }), + args: rustc_ast::ast::AttrItemKind::Unparsed(AttrArgs::Delimited( + DelimArgs { + dspan: DelimSpan::from_single(self.span), + delim: rustc_ast::token::Delimiter::Parenthesis, + tokens: [ + TokenKind::Ident(sym::feature, IdentIsRaw::No), + TokenKind::Eq, + TokenKind::lit(LitKind::Str, sym::derive_const, None), + TokenKind::Comma, + TokenKind::Ident(sym::issue, IdentIsRaw::No), + TokenKind::Eq, + TokenKind::lit(LitKind::Str, sym::derive_const_issue, None), + ] + .into_iter() + .map(|kind| { + TokenTree::Token( + Token { kind, span: self.span }, + Spacing::Alone, + ) + }) + .collect(), + }, + )), tokens: None, }, self.span, @@ -844,7 +851,7 @@ impl<'a> TraitDef<'a> { of_trait: Some(Box::new(ast::TraitImplHeader { safety: self.safety, polarity: ast::ImplPolarity::Positive, - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, trait_ref, })), constness: if self.is_const { ast::Const::Yes(DUMMY_SP) } else { ast::Const::No }, @@ -981,16 +988,6 @@ impl<'a> MethodDef<'a> { f(cx, span, &substructure) } - fn get_ret_ty( - &self, - cx: &ExtCtxt<'_>, - trait_: &TraitDef<'_>, - generics: &Generics, - type_ident: Ident, - ) -> Box { - self.ret_ty.to_ty(cx, trait_.span, type_ident, generics) - } - fn is_static(&self) -> bool { !self.explicit_self } @@ -1063,16 +1060,20 @@ impl<'a> MethodDef<'a> { self_arg.into_iter().chain(nonself_args).collect() }; - let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); + let ret_type = if let Ty::Unit = &self.ret_ty { + ast::FnRetTy::Default(span) + } else { + ast::FnRetTy::Ty(self.ret_ty.to_ty(cx, span, type_ident, generics)) + }; let method_ident = Ident::new(self.name, span); - let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type)); + let fn_decl = cx.fn_decl(args, ret_type); let body_block = body.into_block(cx, span); let trait_lo_sp = span.shrink_to_lo(); let sig = ast::FnSig { header: ast::FnHeader::default(), decl: fn_decl, span }; - let defaultness = ast::Defaultness::Final; + let defaultness = ast::Defaultness::Implicit; // Create the method. Box::new(ast::AssocItem { @@ -1092,6 +1093,7 @@ impl<'a> MethodDef<'a> { contract: None, body: Some(body_block), define_opaque: None, + eii_impls: ThinVec::new(), })), tokens: None, }) diff --git a/compiler/rustc_builtin_macros/src/eii.rs b/compiler/rustc_builtin_macros/src/eii.rs new file mode 100644 index 000000000000..7b651ed84828 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/eii.rs @@ -0,0 +1,497 @@ +use rustc_ast::token::{Delimiter, TokenKind}; +use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; +use rustc_ast::{ + Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Path, StmtKind, Visibility, ast, +}; +use rustc_ast_pretty::pprust::path_to_string; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; +use thin_vec::{ThinVec, thin_vec}; + +use crate::errors::{ + EiiExternTargetExpectedList, EiiExternTargetExpectedMacro, EiiExternTargetExpectedUnsafe, + EiiMacroExpectedMaxOneArgument, EiiOnlyOnce, EiiSharedMacroExpectedFunction, + EiiSharedMacroInStatementPosition, +}; + +/// ```rust +/// #[eii] +/// fn panic_handler(); +/// +/// // or: +/// +/// #[eii(panic_handler)] +/// fn panic_handler(); +/// +/// // expansion: +/// +/// extern "Rust" { +/// fn panic_handler(); +/// } +/// +/// #[rustc_builtin_macro(eii_shared_macro)] +/// #[eii_declaration(panic_handler)] +/// macro panic_handler() {} +/// ``` +pub(crate) fn eii( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + item: Annotatable, +) -> Vec { + eii_(ecx, span, meta_item, item, false) +} + +pub(crate) fn unsafe_eii( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + item: Annotatable, +) -> Vec { + eii_(ecx, span, meta_item, item, true) +} + +fn eii_( + ecx: &mut ExtCtxt<'_>, + eii_attr_span: Span, + meta_item: &ast::MetaItem, + orig_item: Annotatable, + impl_unsafe: bool, +) -> Vec { + let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span); + + let item = if let Annotatable::Item(item) = orig_item { + item + } else if let Annotatable::Stmt(ref stmt) = orig_item + && let StmtKind::Item(ref item) = stmt.kind + && let ItemKind::Fn(ref f) = item.kind + { + ecx.dcx().emit_err(EiiSharedMacroInStatementPosition { + span: eii_attr_span.to(item.span), + name: path_to_string(&meta_item.path), + item_span: f.ident.span, + }); + return vec![orig_item]; + } else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span: eii_attr_span, + name: path_to_string(&meta_item.path), + }); + return vec![orig_item]; + }; + + let ast::Item { attrs, id: _, span: _, vis, kind: ItemKind::Fn(func), tokens: _ } = + item.as_ref() + else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span: eii_attr_span, + name: path_to_string(&meta_item.path), + }); + return vec![Annotatable::Item(item)]; + }; + // only clone what we need + let attrs = attrs.clone(); + let func = (**func).clone(); + let vis = vis.clone(); + + let attrs_from_decl = + filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path); + + let Ok(macro_name) = name_for_impl_macro(ecx, &func, &meta_item) else { + // we don't need to wrap in Annotatable::Stmt conditionally since + // EII can't be used on items in statement position + return vec![Annotatable::Item(item)]; + }; + + // span of the declaring item without attributes + let item_span = func.sig.span; + let foreign_item_name = func.ident; + + let mut module_items = Vec::new(); + + if func.body.is_some() { + module_items.push(generate_default_impl( + ecx, + &func, + impl_unsafe, + macro_name, + eii_attr_span, + item_span, + foreign_item_name, + )) + } + + module_items.push(generate_foreign_item( + ecx, + eii_attr_span, + item_span, + func, + vis, + &attrs_from_decl, + )); + module_items.push(generate_attribute_macro_to_implement( + ecx, + eii_attr_span, + macro_name, + foreign_item_name, + impl_unsafe, + &attrs_from_decl, + )); + + // we don't need to wrap in Annotatable::Stmt conditionally since + // EII can't be used on items in statement position + module_items.into_iter().map(Annotatable::Item).collect() +} + +/// Decide on the name of the macro that can be used to implement the EII. +/// This is either an explicitly given name, or the name of the item in the +/// declaration of the EII. +fn name_for_impl_macro( + ecx: &mut ExtCtxt<'_>, + func: &ast::Fn, + meta_item: &MetaItem, +) -> Result { + if meta_item.is_word() { + Ok(func.ident) + } else if let Some([first]) = meta_item.meta_item_list() + && let Some(m) = first.meta_item() + && m.path.segments.len() == 1 + { + Ok(m.path.segments[0].ident) + } else { + Err(ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument { + span: meta_item.span, + name: path_to_string(&meta_item.path), + })) + } +} + +/// Ensure that in the list of attrs, there's only a single `eii` attribute. +fn filter_attrs_for_multiple_eii_attr( + ecx: &mut ExtCtxt<'_>, + attrs: ThinVec, + eii_attr_span: Span, + eii_attr_path: &Path, +) -> ThinVec { + attrs + .into_iter() + .filter(|i| { + if i.has_name(sym::eii) { + ecx.dcx().emit_err(EiiOnlyOnce { + span: i.span, + first_span: eii_attr_span, + name: path_to_string(eii_attr_path), + }); + false + } else { + true + } + }) + .collect() +} + +fn generate_default_impl( + ecx: &mut ExtCtxt<'_>, + func: &ast::Fn, + impl_unsafe: bool, + macro_name: Ident, + eii_attr_span: Span, + item_span: Span, + foreign_item_name: Ident, +) -> Box { + // FIXME: re-add some original attrs + let attrs = ThinVec::new(); + + let mut default_func = func.clone(); + default_func.eii_impls.push(EiiImpl { + node_id: DUMMY_NODE_ID, + inner_span: macro_name.span, + eii_macro_path: ast::Path::from_ident(macro_name), + impl_safety: if impl_unsafe { + ast::Safety::Unsafe(eii_attr_span) + } else { + ast::Safety::Default + }, + span: eii_attr_span, + is_default: true, + known_eii_macro_resolution: Some(ast::EiiDecl { + foreign_item: ecx.path( + foreign_item_name.span, + // prefix self to explicitly escape the const block generated below + // NOTE: this is why EIIs can't be used on statements + vec![Ident::from_str_and_span("self", foreign_item_name.span), foreign_item_name], + ), + impl_unsafe, + }), + }); + + let anon_mod = |span: Span, stmts: ThinVec| { + let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new())); + let underscore = Ident::new(kw::Underscore, item_span); + ecx.item_const( + span, + underscore, + unit, + ast::ConstItemRhsKind::new_body(ecx.expr_block(ecx.block(span, stmts))), + ) + }; + + // const _: () = { + // + // } + anon_mod( + item_span, + thin_vec![ecx.stmt_item( + item_span, + ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func))) + ),], + ) +} + +/// Generates a foreign item, like +/// +/// ```rust, ignore +/// extern "…" { safe fn item(); } +/// ``` +fn generate_foreign_item( + ecx: &mut ExtCtxt<'_>, + eii_attr_span: Span, + item_span: Span, + mut func: ast::Fn, + vis: Visibility, + attrs_from_decl: &[Attribute], +) -> Box { + let mut foreign_item_attrs = ThinVec::new(); + foreign_item_attrs.extend_from_slice(attrs_from_decl); + + // Add the rustc_eii_foreign_item on the foreign item. Usually, foreign items are mangled. + // This attribute makes sure that we later know that this foreign item's symbol should not be. + foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_foreign_item, eii_attr_span)); + + let abi = match func.sig.header.ext { + // extern "X" fn => extern "X" {} + ast::Extern::Explicit(lit, _) => Some(lit), + // extern fn => extern {} + ast::Extern::Implicit(_) => None, + // fn => extern "Rust" {} + ast::Extern::None => Some(ast::StrLit { + symbol: sym::Rust, + suffix: None, + symbol_unescaped: sym::Rust, + style: ast::StrStyle::Cooked, + span: eii_attr_span, + }), + }; + + // ABI has been moved to the extern {} block, so we remove it from the fn item. + func.sig.header.ext = ast::Extern::None; + func.body = None; + + // And mark safe functions explicitly as `safe fn`. + if func.sig.header.safety == ast::Safety::Default { + func.sig.header.safety = ast::Safety::Safe(func.sig.span); + } + + ecx.item( + eii_attr_span, + ThinVec::new(), + ast::ItemKind::ForeignMod(ast::ForeignMod { + extern_span: eii_attr_span, + safety: ast::Safety::Unsafe(eii_attr_span), + abi, + items: From::from([Box::new(ast::ForeignItem { + attrs: foreign_item_attrs, + id: ast::DUMMY_NODE_ID, + span: item_span, + vis, + kind: ast::ForeignItemKind::Fn(Box::new(func.clone())), + tokens: None, + })]), + }), + ) +} + +/// Generate a stub macro (a bit like in core) that will roughly look like: +/// +/// ```rust, ignore, example +/// // Since this a stub macro, the actual code that expands it lives in the compiler. +/// // This attribute tells the compiler that +/// #[builtin_macro(eii_shared_macro)] +/// // the metadata to link this macro to the generated foreign item. +/// #[eii_declaration()] +/// macro macro_name { () => {} } +/// ``` +fn generate_attribute_macro_to_implement( + ecx: &mut ExtCtxt<'_>, + span: Span, + macro_name: Ident, + foreign_item_name: Ident, + impl_unsafe: bool, + attrs_from_decl: &[Attribute], +) -> Box { + let mut macro_attrs = ThinVec::new(); + + // To avoid e.g. `error: attribute macro has missing stability attribute` + // errors for eii's in std. + macro_attrs.extend_from_slice(attrs_from_decl); + + // Avoid "missing stability attribute" errors for eiis in std. See #146993. + macro_attrs.push(ecx.attr_name_value_str(sym::rustc_macro_transparency, sym::semiopaque, span)); + + // #[builtin_macro(eii_shared_macro)] + macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span)); + + // cant use ecx methods here to construct item since we need it to be public + Box::new(ast::Item { + attrs: macro_attrs, + id: ast::DUMMY_NODE_ID, + span, + // pub + vis: ast::Visibility { span, kind: ast::VisibilityKind::Public, tokens: None }, + kind: ast::ItemKind::MacroDef( + // macro macro_name + macro_name, + ast::MacroDef { + // { () => {} } + body: Box::new(ast::DelimArgs { + dspan: DelimSpan::from_single(span), + delim: Delimiter::Brace, + tokens: TokenStream::from_iter([ + TokenTree::Delimited( + DelimSpan::from_single(span), + DelimSpacing::new(Spacing::Alone, Spacing::Alone), + Delimiter::Parenthesis, + TokenStream::default(), + ), + TokenTree::token_alone(TokenKind::FatArrow, span), + TokenTree::Delimited( + DelimSpan::from_single(span), + DelimSpacing::new(Spacing::Alone, Spacing::Alone), + Delimiter::Brace, + TokenStream::default(), + ), + ]), + }), + macro_rules: false, + // #[eii_declaration(foreign_item_ident)] + eii_declaration: Some(ast::EiiDecl { + foreign_item: ast::Path::from_ident(foreign_item_name), + impl_unsafe, + }), + }, + ), + tokens: None, + }) +} + +pub(crate) fn eii_declaration( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, +) -> Vec { + let i = if let Annotatable::Item(ref mut item) = item { + item + } else if let Annotatable::Stmt(ref mut stmt) = item + && let StmtKind::Item(ref mut item) = stmt.kind + { + item + } else { + ecx.dcx().emit_err(EiiExternTargetExpectedMacro { span }); + return vec![item]; + }; + + let ItemKind::MacroDef(_, d) = &mut i.kind else { + ecx.dcx().emit_err(EiiExternTargetExpectedMacro { span }); + return vec![item]; + }; + + let Some(list) = meta_item.meta_item_list() else { + ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span }); + return vec![item]; + }; + + if list.len() > 2 { + ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span }); + return vec![item]; + } + + let Some(extern_item_path) = list.get(0).and_then(|i| i.meta_item()).map(|i| i.path.clone()) + else { + ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span }); + return vec![item]; + }; + + let impl_unsafe = if let Some(i) = list.get(1) { + if i.lit().and_then(|i| i.kind.str()).is_some_and(|i| i == kw::Unsafe) { + true + } else { + ecx.dcx().emit_err(EiiExternTargetExpectedUnsafe { span: i.span() }); + return vec![item]; + } + } else { + false + }; + + d.eii_declaration = Some(EiiDecl { foreign_item: extern_item_path, impl_unsafe }); + + // Return the original item and the new methods. + vec![item] +} + +/// all Eiis share this function as the implementation for their attribute. +pub(crate) fn eii_shared_macro( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &ast::MetaItem, + mut item: Annotatable, +) -> Vec { + let i = if let Annotatable::Item(ref mut item) = item { + item + } else if let Annotatable::Stmt(ref mut stmt) = item + && let StmtKind::Item(ref mut item) = stmt.kind + { + item + } else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span, + name: path_to_string(&meta_item.path), + }); + return vec![item]; + }; + + let ItemKind::Fn(f) = &mut i.kind else { + ecx.dcx().emit_err(EiiSharedMacroExpectedFunction { + span, + name: path_to_string(&meta_item.path), + }); + return vec![item]; + }; + + let is_default = if meta_item.is_word() { + false + } else if let Some([first]) = meta_item.meta_item_list() + && let Some(m) = first.meta_item() + && m.path.segments.len() == 1 + { + m.path.segments[0].ident.name == kw::Default + } else { + ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument { + span: meta_item.span, + name: path_to_string(&meta_item.path), + }); + return vec![item]; + }; + + f.eii_impls.push(EiiImpl { + node_id: DUMMY_NODE_ID, + inner_span: meta_item.path.span, + eii_macro_path: meta_item.path.clone(), + impl_safety: meta_item.unsafety, + span, + is_default, + known_eii_macro_resolution: None, + }); + + vec![item] +} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index dd6a5a20cceb..29ab8ee505d6 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -1,150 +1,157 @@ use rustc_errors::codes::*; use rustc_errors::{ Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, SingleLabelManySpans, - Subdiagnostic, + Subdiagnostic, msg, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Ident, Span, Symbol}; #[derive(LintDiagnostic)] -#[diag(builtin_macros_avoid_intel_syntax)] +#[diag("avoid using `.intel_syntax`, Intel syntax is the default")] pub(crate) struct AvoidIntelSyntax; #[derive(LintDiagnostic)] -#[diag(builtin_macros_avoid_att_syntax)] +#[diag("avoid using `.att_syntax`, prefer using `options(att_syntax)` instead")] pub(crate) struct AvoidAttSyntax; #[derive(LintDiagnostic)] -#[diag(builtin_macros_incomplete_include)] +#[diag("include macro expected single expression in source")] pub(crate) struct IncompleteInclude; #[derive(LintDiagnostic)] -#[diag(builtin_macros_unnameable_test_items)] +#[diag("cannot test inner items")] pub(crate) struct UnnameableTestItems; #[derive(LintDiagnostic)] -#[diag(builtin_macros_duplicate_macro_attribute)] +#[diag("duplicated attribute")] pub(crate) struct DuplicateMacroAttribute; #[derive(Diagnostic)] -#[diag(builtin_macros_requires_cfg_pattern)] +#[diag("macro requires a cfg-pattern as an argument")] pub(crate) struct RequiresCfgPattern { #[primary_span] - #[label] + #[label("cfg-pattern required")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_expected_one_cfg_pattern)] +#[diag("expected 1 cfg-pattern")] pub(crate) struct OneCfgPattern { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_alloc_error_must_be_fn)] +#[diag("alloc_error_handler must be a function")] pub(crate) struct AllocErrorMustBeFn { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_assert_requires_boolean)] +#[diag("macro requires a boolean expression as an argument")] pub(crate) struct AssertRequiresBoolean { #[primary_span] - #[label] + #[label("boolean expression required")] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_assert_requires_expression)] +#[diag("macro requires an expression as an argument")] pub(crate) struct AssertRequiresExpression { #[primary_span] pub(crate) span: Span, - #[suggestion(code = "", applicability = "maybe-incorrect")] + #[suggestion("try removing semicolon", code = "", applicability = "maybe-incorrect")] pub(crate) token: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_assert_missing_comma)] +#[diag("unexpected string literal")] pub(crate) struct AssertMissingComma { #[primary_span] pub(crate) span: Span, - #[suggestion(code = ", ", applicability = "maybe-incorrect", style = "short")] + #[suggestion( + "try adding a comma", + code = ", ", + applicability = "maybe-incorrect", + style = "short" + )] pub(crate) comma: Span, } #[derive(Diagnostic)] pub(crate) enum CfgAccessibleInvalid { - #[diag(builtin_macros_cfg_accessible_unspecified_path)] + #[diag("`cfg_accessible` path is not specified")] UnspecifiedPath(#[primary_span] Span), - #[diag(builtin_macros_cfg_accessible_multiple_paths)] + #[diag("multiple `cfg_accessible` paths are specified")] MultiplePaths(#[primary_span] Span), - #[diag(builtin_macros_cfg_accessible_literal_path)] + #[diag("`cfg_accessible` path cannot be a literal")] LiteralPath(#[primary_span] Span), - #[diag(builtin_macros_cfg_accessible_has_args)] + #[diag("`cfg_accessible` path cannot accept arguments")] HasArguments(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(builtin_macros_cfg_accessible_indeterminate)] +#[diag("cannot determine whether the path is accessible or not")] pub(crate) struct CfgAccessibleIndeterminate { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_missing_literal)] -#[note] +#[diag("expected a literal")] +#[note("only literals (like `\"foo\"`, `-42` and `3.14`) can be passed to `concat!()`")] pub(crate) struct ConcatMissingLiteral { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytestr)] +#[diag("cannot concatenate a byte string literal")] pub(crate) struct ConcatBytestr { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_c_str_lit)] +#[diag("cannot concatenate a C string literal")] pub(crate) struct ConcatCStrLit { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_export_macro_rules)] +#[diag("cannot export macro_rules! macros from a `proc-macro` crate type currently")] pub(crate) struct ExportMacroRules { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_proc_macro)] +#[diag( + "`proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`" +)] pub(crate) struct ProcMacro { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_trace_macros)] +#[diag("trace_macros! accepts only `true` or `false`")] pub(crate) struct TraceMacros { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_bench_sig)] +#[diag("functions used as benches must have signature `fn(&mut Bencher) -> impl Termination`")] pub(crate) struct BenchSig { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_alloc_must_statics)] +#[diag("allocators must be statics")] pub(crate) struct AllocMustStatics { #[primary_span] pub(crate) span: Span, @@ -155,27 +162,27 @@ pub(crate) use autodiff::*; mod autodiff { use super::*; #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_missing_config)] + #[diag("autodiff requires at least a name and mode")] pub(crate) struct AutoDiffMissingConfig { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_unknown_activity)] + #[diag("did not recognize Activity: `{$act}`")] pub(crate) struct AutoDiffUnknownActivity { #[primary_span] pub(crate) span: Span, pub(crate) act: String, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_ty_activity)] + #[diag("{$act} can not be used for this type")] pub(crate) struct AutoDiffInvalidTypeForActivity { #[primary_span] pub(crate) span: Span, pub(crate) act: String, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_number_activities)] + #[diag("expected {$expected} activities, but found {$found}")] pub(crate) struct AutoDiffInvalidNumberActivities { #[primary_span] pub(crate) span: Span, @@ -183,7 +190,7 @@ mod autodiff { pub(crate) found: usize, } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_mode_activity)] + #[diag("{$act} can not be used in {$mode} Mode")] pub(crate) struct AutoDiffInvalidApplicationModeAct { #[primary_span] pub(crate) span: Span, @@ -192,7 +199,7 @@ mod autodiff { } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_ret_activity)] + #[diag("invalid return activity {$act} in {$mode} Mode")] pub(crate) struct AutoDiffInvalidRetAct { #[primary_span] pub(crate) span: Span, @@ -201,7 +208,7 @@ mod autodiff { } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_width)] + #[diag("autodiff width must fit u32, but is {$width}")] pub(crate) struct AutoDiffInvalidWidth { #[primary_span] pub(crate) span: Span, @@ -209,40 +216,29 @@ mod autodiff { } #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff)] + #[diag("autodiff must be applied to function")] pub(crate) struct AutoDiffInvalidApplication { #[primary_span] pub(crate) span: Span, } } -pub(crate) use ad_fallback::*; -mod ad_fallback { - use super::*; - #[derive(Diagnostic)] - #[diag(builtin_macros_autodiff_not_build)] - pub(crate) struct AutoDiffSupportNotBuild { - #[primary_span] - pub(crate) span: Span, - } -} - #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_invalid)] +#[diag("cannot concatenate {$lit_kind} literals")] pub(crate) struct ConcatBytesInvalid { #[primary_span] pub(crate) span: Span, pub(crate) lit_kind: &'static str, #[subdiagnostic] pub(crate) sugg: Option, - #[note(builtin_macros_c_str_note)] + #[note("concatenating C strings is ambiguous about including the '\\0'")] pub(crate) cs_note: Option<()>, } #[derive(Subdiagnostic)] pub(crate) enum ConcatBytesInvalidSuggestion { #[suggestion( - builtin_macros_byte_char, + "try using a byte character", code = "b{snippet}", applicability = "machine-applicable" )] @@ -252,7 +248,7 @@ pub(crate) enum ConcatBytesInvalidSuggestion { snippet: String, }, #[suggestion( - builtin_macros_byte_str, + "try using a byte string", code = "b{snippet}", applicability = "machine-applicable" )] @@ -261,15 +257,19 @@ pub(crate) enum ConcatBytesInvalidSuggestion { span: Span, snippet: String, }, - #[note(builtin_macros_c_str_note)] - #[suggestion(builtin_macros_c_str, code = "{as_bstr}", applicability = "machine-applicable")] + #[note("concatenating C strings is ambiguous about including the '\\0'")] + #[suggestion( + "try using a null-terminated byte string", + code = "{as_bstr}", + applicability = "machine-applicable" + )] CStrLit { #[primary_span] span: Span, as_bstr: String, }, #[suggestion( - builtin_macros_number_array, + "try wrapping the number in an array", code = "[{snippet}]", applicability = "machine-applicable" )] @@ -281,63 +281,65 @@ pub(crate) enum ConcatBytesInvalidSuggestion { } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_oob)] +#[diag("numeric literal is out of bounds")] pub(crate) struct ConcatBytesOob { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_non_u8)] +#[diag("numeric literal is not a `u8`")] pub(crate) struct ConcatBytesNonU8 { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_missing_literal)] -#[note] +#[diag("expected a byte literal")] +#[note( + "only byte literals (like `b\"foo\"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`" +)] pub(crate) struct ConcatBytesMissingLiteral { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_array)] +#[diag("cannot concatenate doubly nested array")] pub(crate) struct ConcatBytesArray { #[primary_span] pub(crate) span: Span, - #[note] - #[help] + #[note("byte strings are treated as arrays of bytes")] + #[help("try flattening the array")] pub(crate) bytestr: bool, } #[derive(Diagnostic)] -#[diag(builtin_macros_concat_bytes_bad_repeat)] +#[diag("repeat count is not a positive number")] pub(crate) struct ConcatBytesBadRepeat { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_bad_derive_target, code = E0774)] +#[diag("`derive` may only be applied to `struct`s, `enum`s and `union`s", code = E0774)] pub(crate) struct BadDeriveTarget { #[primary_span] - #[label] + #[label("not applicable here")] pub(crate) span: Span, - #[label(builtin_macros_label2)] + #[label("not a `struct`, `enum` or `union`")] pub(crate) item: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_tests_not_support)] +#[diag("building tests with panic=abort is not supported without `-Zpanic_abort_tests`")] pub(crate) struct TestsNotSupport {} #[derive(Diagnostic)] -#[diag(builtin_macros_unexpected_lit, code = E0777)] +#[diag("expected path to a trait, found literal", code = E0777)] pub(crate) struct BadDeriveLit { #[primary_span] - #[label] + #[label("not a trait")] pub(crate) span: Span, #[subdiagnostic] pub help: BadDeriveLitHelp, @@ -345,55 +347,59 @@ pub(crate) struct BadDeriveLit { #[derive(Subdiagnostic)] pub(crate) enum BadDeriveLitHelp { - #[help(builtin_macros_str_lit)] + #[help("try using `#[derive({$sym})]`")] StrLit { sym: Symbol }, - #[help(builtin_macros_other)] + #[help("for example, write `#[derive(Debug)]` for `Debug`")] Other, } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_path_args_list)] +#[diag("traits in `#[derive(...)]` don't accept arguments")] pub(crate) struct DerivePathArgsList { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove the arguments", code = "", applicability = "machine-applicable")] #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_path_args_value)] +#[diag("traits in `#[derive(...)]` don't accept values")] pub(crate) struct DerivePathArgsValue { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove the value", code = "", applicability = "machine-applicable")] #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_no_default_variant, code = E0665)] +#[diag("`#[derive(Default)]` on enum with no `#[default]`", code = E0665)] pub(crate) struct NoDefaultVariant { #[primary_span] pub(crate) span: Span, - #[label] + #[label("this enum needs a unit variant marked with `#[default]`")] pub(crate) item_span: Span, #[subdiagnostic] pub(crate) suggs: Vec, } #[derive(Subdiagnostic)] -#[suggestion(builtin_macros_suggestion, code = "#[default] ", applicability = "maybe-incorrect")] +#[suggestion( + "make this unit variant default by placing `#[default]` on it", + code = "#[default] ", + applicability = "maybe-incorrect" +)] pub(crate) struct NoDefaultVariantSugg { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_multiple_defaults)] -#[note] +#[diag("multiple declared defaults")] +#[note("only one variant can be default")] pub(crate) struct MultipleDefaults { #[primary_span] pub(crate) span: Span, - #[label] + #[label("first default")] pub(crate) first: Span, - #[label(builtin_macros_additional)] + #[label("additional default")] pub additional: Vec, #[subdiagnostic] pub suggs: Vec, @@ -401,7 +407,7 @@ pub(crate) struct MultipleDefaults { #[derive(Subdiagnostic)] #[multipart_suggestion( - builtin_macros_suggestion, + "make `{$ident}` default", applicability = "maybe-incorrect", style = "tool-only" )] @@ -412,8 +418,8 @@ pub(crate) struct MultipleDefaultsSugg { } #[derive(Diagnostic)] -#[diag(builtin_macros_non_unit_default)] -#[help] +#[diag("the `#[default]` attribute may only be used on unit enum variants{$post}")] +#[help("consider a manual implementation of `Default`")] pub(crate) struct NonUnitDefault { #[primary_span] pub(crate) span: Span, @@ -421,26 +427,31 @@ pub(crate) struct NonUnitDefault { } #[derive(Diagnostic)] -#[diag(builtin_macros_non_exhaustive_default)] -#[help] +#[diag("default variant must be exhaustive")] +#[help("consider a manual implementation of `Default`")] pub(crate) struct NonExhaustiveDefault { #[primary_span] pub(crate) span: Span, - #[label] + #[label("declared `#[non_exhaustive]` here")] pub(crate) non_exhaustive: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_multiple_default_attrs)] -#[note] +#[diag("multiple `#[default]` attributes")] +#[note("only one `#[default]` attribute is needed")] pub(crate) struct MultipleDefaultAttrs { #[primary_span] pub(crate) span: Span, - #[label] + #[label("`#[default]` used here")] pub(crate) first: Span, - #[label(builtin_macros_label_again)] + #[label("`#[default]` used again here")] pub(crate) first_rest: Span, - #[help] + #[help( + "try removing {$only_one -> + [true] this + *[false] these + }" + )] pub(crate) rest: MultiSpan, pub(crate) only_one: bool, #[subdiagnostic] @@ -449,7 +460,7 @@ pub(crate) struct MultipleDefaultAttrs { #[derive(Subdiagnostic)] #[multipart_suggestion( - builtin_macros_help, + "consider a manual implementation of `Default`", applicability = "machine-applicable", style = "tool-only" )] @@ -459,16 +470,21 @@ pub(crate) struct MultipleDefaultAttrsSugg { } #[derive(Diagnostic)] -#[diag(builtin_macros_default_arg)] +#[diag("`#[default]` attribute does not accept a value")] pub(crate) struct DefaultHasArg { #[primary_span] - #[suggestion(code = "#[default]", style = "hidden", applicability = "maybe-incorrect")] + #[suggestion( + "try using `#[default]`", + code = "#[default]", + style = "hidden", + applicability = "maybe-incorrect" + )] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_from_wrong_target)] -#[note(builtin_macros_derive_from_usage_note)] +#[diag("`#[derive(From)]` used on {$kind}")] +#[note("`#[derive(From)]` can only be used on structs with exactly one field")] pub(crate) struct DeriveFromWrongTarget<'a> { #[primary_span] pub(crate) span: MultiSpan, @@ -476,8 +492,13 @@ pub(crate) struct DeriveFromWrongTarget<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_from_wrong_field_count)] -#[note(builtin_macros_derive_from_usage_note)] +#[diag( + "`#[derive(From)]` used on a struct with {$multiple_fields -> + [true] multiple fields + *[false] no fields + }" +)] +#[note("`#[derive(From)]` can only be used on structs with exactly one field")] pub(crate) struct DeriveFromWrongFieldCount { #[primary_span] pub(crate) span: MultiSpan, @@ -485,21 +506,21 @@ pub(crate) struct DeriveFromWrongFieldCount { } #[derive(Diagnostic)] -#[diag(builtin_macros_derive_macro_call)] +#[diag("`derive` cannot be used on items with type macros")] pub(crate) struct DeriveMacroCall { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_cannot_derive_union)] +#[diag("this trait cannot be derived for unions")] pub(crate) struct DeriveUnion { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_env_takes_args)] +#[diag("`env!()` takes 1 or 2 arguments")] pub(crate) struct EnvTakesArgs { #[primary_span] pub(crate) span: Span, @@ -514,10 +535,6 @@ pub(crate) struct EnvNotDefinedWithUserMessage { impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for EnvNotDefinedWithUserMessage { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - #[expect( - rustc::untranslatable_diagnostic, - reason = "cannot translate user-provided messages" - )] let mut diag = Diag::new(dcx, level, self.msg_from_user.to_string()); diag.span(self.span); diag @@ -526,24 +543,26 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for EnvNotDefinedWithUserMessag #[derive(Diagnostic)] pub(crate) enum EnvNotDefined<'a> { - #[diag(builtin_macros_env_not_defined)] - #[help(builtin_macros_cargo)] + #[diag("environment variable `{$var}` not defined at compile time")] + #[help( + "Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead" + )] CargoEnvVar { #[primary_span] span: Span, var: Symbol, var_expr: &'a rustc_ast::Expr, }, - #[diag(builtin_macros_env_not_defined)] - #[help(builtin_macros_cargo_typo)] + #[diag("environment variable `{$var}` not defined at compile time")] + #[help("there is a similar Cargo environment variable: `{$suggested_var}`")] CargoEnvVarTypo { #[primary_span] span: Span, var: Symbol, suggested_var: Symbol, }, - #[diag(builtin_macros_env_not_defined)] - #[help(builtin_macros_custom)] + #[diag("environment variable `{$var}` not defined at compile time")] + #[help("use `std::env::var({$var_expr})` to read the variable at run time")] CustomEnvVar { #[primary_span] span: Span, @@ -553,7 +572,7 @@ pub(crate) enum EnvNotDefined<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_env_not_unicode)] +#[diag("environment variable `{$var}` is not a valid Unicode string")] pub(crate) struct EnvNotUnicode { #[primary_span] pub(crate) span: Span, @@ -561,39 +580,39 @@ pub(crate) struct EnvNotUnicode { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_requires_string)] +#[diag("requires at least a format string argument")] pub(crate) struct FormatRequiresString { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_duplicate_arg)] +#[diag("duplicate argument named `{$ident}`")] pub(crate) struct FormatDuplicateArg { #[primary_span] pub(crate) span: Span, - #[label(builtin_macros_label1)] + #[label("previously here")] pub(crate) prev: Span, - #[label(builtin_macros_label2)] + #[label("duplicate argument")] pub(crate) duplicate: Span, pub(crate) ident: Ident, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_positional_after_named)] +#[diag("positional arguments cannot follow named arguments")] pub(crate) struct PositionalAfterNamed { #[primary_span] - #[label] + #[label("positional arguments must be before named arguments")] pub(crate) span: Span, - #[label(builtin_macros_named_args)] + #[label("named argument")] pub(crate) args: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_string_invalid)] +#[diag("invalid format string: {$desc}")] pub(crate) struct InvalidFormatString { #[primary_span] - #[label] + #[label("{$label1} in format string")] pub(crate) span: Span, pub(crate) desc: String, pub(crate) label1: String, @@ -606,13 +625,13 @@ pub(crate) struct InvalidFormatString { } #[derive(Subdiagnostic)] -#[note(builtin_macros_note)] +#[note("{$note}")] pub(crate) struct InvalidFormatStringNote { pub(crate) note: String, } #[derive(Subdiagnostic)] -#[label(builtin_macros_second_label)] +#[label("{$label}")] pub(crate) struct InvalidFormatStringLabel { #[primary_span] pub(crate) span: Span, @@ -622,7 +641,7 @@ pub(crate) struct InvalidFormatStringLabel { #[derive(Subdiagnostic)] pub(crate) enum InvalidFormatStringSuggestion { #[multipart_suggestion( - builtin_macros_format_use_positional, + "consider using a positional formatting argument instead", style = "verbose", applicability = "machine-applicable" )] @@ -634,17 +653,13 @@ pub(crate) enum InvalidFormatStringSuggestion { span: Span, arg: String, }, - #[suggestion( - builtin_macros_format_remove_raw_ident, - code = "", - applicability = "machine-applicable" - )] + #[suggestion("remove the `r#`", code = "", applicability = "machine-applicable")] RemoveRawIdent { #[primary_span] span: Span, }, #[suggestion( - builtin_macros_format_reorder_format_parameter, + "did you mean `{$replacement}`?", code = "{replacement}", style = "verbose", applicability = "machine-applicable" @@ -654,12 +669,35 @@ pub(crate) enum InvalidFormatStringSuggestion { span: Span, replacement: String, }, + #[suggestion( + "add a colon before the format specifier", + code = ":?", + applicability = "machine-applicable" + )] + AddMissingColon { + #[primary_span] + span: Span, + }, + + #[suggestion( + "use rust debug printing macro", + code = "{replacement}", + style = "verbose", + applicability = "machine-applicable" + )] + UseRustDebugPrintingMacro { + #[primary_span] + macro_span: Span, + replacement: String, + }, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_no_arg_named)] -#[note] -#[note(builtin_macros_note2)] +#[diag("there is no argument named `{$name}`")] +#[note("did you intend to capture a variable `{$name}` from the surrounding scope?")] +#[note( + "to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro" +)] pub(crate) struct FormatNoArgNamed { #[primary_span] pub(crate) span: Span, @@ -667,8 +705,19 @@ pub(crate) struct FormatNoArgNamed { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_unknown_trait)] -#[note] +#[diag("unknown format trait `{$ty}`")] +#[note( + "the only appropriate formatting traits are: + - ``, which uses the `Display` trait + - `?`, which uses the `Debug` trait + - `e`, which uses the `LowerExp` trait + - `E`, which uses the `UpperExp` trait + - `o`, which uses the `Octal` trait + - `p`, which uses the `Pointer` trait + - `b`, which uses the `Binary` trait + - `x`, which uses the `LowerHex` trait + - `X`, which uses the `UpperHex` trait" +)] pub(crate) struct FormatUnknownTrait<'a> { #[primary_span] pub(crate) span: Span, @@ -679,7 +728,7 @@ pub(crate) struct FormatUnknownTrait<'a> { #[derive(Subdiagnostic)] #[suggestion( - builtin_macros_suggestion, + "use the `{$trait_name}` trait", code = "{fmt}", style = "tool-only", applicability = "maybe-incorrect" @@ -692,10 +741,20 @@ pub(crate) struct FormatUnknownTraitSugg { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_unused_arg)] +#[diag( + "{$named -> + [true] named argument + *[false] argument + } never used" +)] pub(crate) struct FormatUnusedArg { #[primary_span] - #[label(builtin_macros_format_unused_arg)] + #[label( + "{$named -> + [true] named argument + *[false] argument + } never used" + )] pub(crate) span: Span, pub(crate) named: bool, } @@ -705,25 +764,35 @@ pub(crate) struct FormatUnusedArg { impl Subdiagnostic for FormatUnusedArg { fn add_to_diag(self, diag: &mut Diag<'_, G>) { diag.arg("named", self.named); - let msg = diag.eagerly_translate(crate::fluent_generated::builtin_macros_format_unused_arg); + let msg = diag.eagerly_translate(msg!( + "{$named -> + [true] named argument + *[false] argument + } never used" + )); diag.remove_arg("named"); diag.span_label(self.span, msg); } } #[derive(Diagnostic)] -#[diag(builtin_macros_format_unused_args)] +#[diag("multiple unused formatting arguments")] pub(crate) struct FormatUnusedArgs { #[primary_span] pub(crate) unused: Vec, - #[label] + #[label("multiple missing formatting specifiers")] pub(crate) fmt: Span, #[subdiagnostic] pub(crate) unused_labels: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_format_pos_mismatch)] +#[diag( + "{$n} positional {$n -> + [one] argument + *[more] arguments + } in format string, but {$desc}" +)] pub(crate) struct FormatPositionalMismatch { #[primary_span] pub(crate) span: MultiSpan, @@ -734,13 +803,23 @@ pub(crate) struct FormatPositionalMismatch { } #[derive(Diagnostic)] -#[diag(builtin_macros_format_redundant_args)] +#[diag( + "redundant {$n -> + [one] argument + *[more] arguments + }" +)] pub(crate) struct FormatRedundantArgs { #[primary_span] pub(crate) span: MultiSpan, pub(crate) n: usize, - #[note] + #[note( + "{$n -> + [one] the formatting specifier is referencing the binding already + *[more] the formatting specifiers are referencing the bindings already + }" + )] pub(crate) note: MultiSpan, #[subdiagnostic] @@ -748,38 +827,38 @@ pub(crate) struct FormatRedundantArgs { } #[derive(Subdiagnostic)] -#[multipart_suggestion(builtin_macros_suggestion, applicability = "machine-applicable")] +#[multipart_suggestion("this can be removed", applicability = "machine-applicable")] pub(crate) struct FormatRedundantArgsSugg { #[suggestion_part(code = "")] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_test_case_non_item)] +#[diag("`#[test_case]` attribute is only allowed on items")] pub(crate) struct TestCaseNonItem { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_test_bad_fn)] +#[diag("{$kind} functions cannot be used for tests")] pub(crate) struct TestBadFn { #[primary_span] pub(crate) span: Span, - #[label] + #[label("`{$kind}` because of this")] pub(crate) cause: Span, pub(crate) kind: &'static str, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_explicit_register_name)] +#[diag("explicit register arguments cannot have names")] pub(crate) struct AsmExplicitRegisterName { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_mutually_exclusive)] +#[diag("the `{$opt1}` and `{$opt2}` options are mutually exclusive")] pub(crate) struct AsmMutuallyExclusive { #[primary_span] pub(crate) spans: Vec, @@ -788,65 +867,65 @@ pub(crate) struct AsmMutuallyExclusive { } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_pure_combine)] +#[diag("the `pure` option must be combined with either `nomem` or `readonly`")] pub(crate) struct AsmPureCombine { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_pure_no_output)] +#[diag("asm with the `pure` option must have at least one output")] pub(crate) struct AsmPureNoOutput { #[primary_span] pub(crate) spans: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_modifier_invalid)] +#[diag("asm template modifier must be a single character")] pub(crate) struct AsmModifierInvalid { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_attribute_not_supported)] +#[diag("this attribute is not supported on assembly")] pub(crate) struct AsmAttributeNotSupported { #[primary_span] pub(crate) span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_duplicate_arg)] +#[diag("duplicate argument named `{$name}`")] pub(crate) struct AsmDuplicateArg { #[primary_span] - #[label(builtin_macros_arg)] + #[label("duplicate argument")] pub(crate) span: Span, - #[label] + #[label("previously here")] pub(crate) prev: Span, pub(crate) name: Symbol, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_pos_after)] +#[diag("positional arguments cannot follow named arguments or explicit register arguments")] pub(crate) struct AsmPositionalAfter { #[primary_span] - #[label(builtin_macros_pos)] + #[label("positional argument")] pub(crate) span: Span, - #[label(builtin_macros_named)] + #[label("named argument")] pub(crate) named: Vec, - #[label(builtin_macros_explicit)] + #[label("explicit register argument")] pub(crate) explicit: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_noreturn)] +#[diag("asm outputs are not allowed with the `noreturn` option")] pub(crate) struct AsmNoReturn { #[primary_span] pub(crate) outputs_sp: Vec, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_no_matched_argument_name)] +#[diag("there is no argument named `{$name}`")] pub(crate) struct AsmNoMatchedArgumentName { pub(crate) name: String, #[primary_span] @@ -854,7 +933,7 @@ pub(crate) struct AsmNoMatchedArgumentName { } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_mayunwind)] +#[diag("asm labels are not allowed with the `may_unwind` option")] pub(crate) struct AsmMayUnwind { #[primary_span] pub(crate) labels_sp: Vec, @@ -868,46 +947,54 @@ pub(crate) struct AsmClobberNoReg { impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AsmClobberNoReg { fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { // eager translation as `span_labels` takes `AsRef` - let lbl1 = dcx.eagerly_translate_to_string( - crate::fluent_generated::builtin_macros_asm_clobber_abi, - [].into_iter(), - ); - let lbl2 = dcx.eagerly_translate_to_string( - crate::fluent_generated::builtin_macros_asm_clobber_outputs, - [].into_iter(), - ); - Diag::new(dcx, level, crate::fluent_generated::builtin_macros_asm_clobber_no_reg) - .with_span(self.spans.clone()) - .with_span_labels(self.clobbers, &lbl1) - .with_span_labels(self.spans, &lbl2) + let lbl1 = dcx.eagerly_translate_to_string(msg!("clobber_abi"), [].into_iter()); + let lbl2 = dcx.eagerly_translate_to_string(msg!("generic outputs"), [].into_iter()); + Diag::new( + dcx, + level, + msg!("asm with `clobber_abi` must specify explicit registers for outputs"), + ) + .with_span(self.spans.clone()) + .with_span_labels(self.clobbers, &lbl1) + .with_span_labels(self.spans, &lbl2) } } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_opt_already_provided)] +#[diag("the `{$symbol}` option was already provided")] pub(crate) struct AsmOptAlreadyprovided { #[primary_span] - #[label] + #[label("this option was already provided")] pub(crate) span: Span, pub(crate) symbol: Symbol, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove this option", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub(crate) span_with_comma: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_unsupported_option)] +#[diag("the `{$symbol}` option cannot be used with `{$macro_name}!`")] pub(crate) struct AsmUnsupportedOption { #[primary_span] - #[label] + #[label("the `{$symbol}` option is not meaningful for global-scoped inline assembly")] pub(crate) span: Span, pub(crate) symbol: Symbol, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] + #[suggestion( + "remove this option", + code = "", + applicability = "machine-applicable", + style = "tool-only" + )] pub(crate) span_with_comma: Span, pub(crate) macro_name: &'static str, } #[derive(Diagnostic)] -#[diag(builtin_macros_asm_unsupported_clobber_abi)] +#[diag("`clobber_abi` cannot be used with `{$macro_name}!`")] pub(crate) struct AsmUnsupportedClobberAbi { #[primary_span] pub(crate) spans: Vec, @@ -915,28 +1002,14 @@ pub(crate) struct AsmUnsupportedClobberAbi { } #[derive(Diagnostic)] -#[diag(builtin_macros_test_runner_invalid)] -pub(crate) struct TestRunnerInvalid { - #[primary_span] - pub(crate) span: Span, -} - -#[derive(Diagnostic)] -#[diag(builtin_macros_test_runner_nargs)] -pub(crate) struct TestRunnerNargs { - #[primary_span] - pub(crate) span: Span, -} - -#[derive(Diagnostic)] -#[diag(builtin_macros_expected_comma_in_list)] +#[diag("expected token: `,`")] pub(crate) struct ExpectedCommaInList { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_only_one_argument)] +#[diag("{$name} takes 1 argument")] pub(crate) struct OnlyOneArgument<'a> { #[primary_span] pub span: Span, @@ -944,7 +1017,7 @@ pub(crate) struct OnlyOneArgument<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_takes_no_arguments)] +#[diag("{$name} takes no arguments")] pub(crate) struct TakesNoArguments<'a> { #[primary_span] pub span: Span, @@ -952,7 +1025,7 @@ pub(crate) struct TakesNoArguments<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_proc_macro_attribute_only_usable_with_crate_type)] +#[diag("the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type")] pub(crate) struct AttributeOnlyUsableWithCrateType<'a> { #[primary_span] pub span: Span, @@ -960,7 +1033,7 @@ pub(crate) struct AttributeOnlyUsableWithCrateType<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_source_utils_expected_item)] +#[diag("expected item, found `{$token}`")] pub(crate) struct ExpectedItem<'a> { #[primary_span] pub span: Span, @@ -968,45 +1041,102 @@ pub(crate) struct ExpectedItem<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_naked_functions_testing_attribute, code = E0736)] +#[diag("cannot use `#[unsafe(naked)]` with testing attributes", code = E0736)] pub(crate) struct NakedFunctionTestingAttribute { #[primary_span] - #[label(builtin_macros_naked_attribute)] + #[label("`#[unsafe(naked)]` is incompatible with testing attributes")] pub naked_span: Span, - #[label] + #[label("function marked with testing attribute here")] pub testing_span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_non_generic_pointee)] +#[diag("the `#[pointee]` attribute may only be used on generic parameters")] pub(crate) struct NonGenericPointee { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_expected_other)] +#[diag( + "expected operand, {$is_inline_asm -> + [false] options + *[true] clobber_abi, options + }, or additional template string" +)] pub(crate) struct AsmExpectedOther { #[primary_span] - #[label(builtin_macros_expected_other)] + #[label( + "expected operand, {$is_inline_asm -> + [false] options + *[true] clobber_abi, options + }, or additional template string" + )] pub(crate) span: Span, pub(crate) is_inline_asm: bool, } #[derive(Diagnostic)] -#[diag(builtin_macros_cfg_select_no_matches)] +#[diag("none of the predicates in this `cfg_select` evaluated to true")] pub(crate) struct CfgSelectNoMatches { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(builtin_macros_cfg_select_unreachable)] -pub(crate) struct CfgSelectUnreachable { +#[diag("`#[eii_declaration(...)]` is only valid on macros")] +pub(crate) struct EiiExternTargetExpectedMacro { #[primary_span] - #[label(builtin_macros_label2)] pub span: Span, - - #[label] - pub wildcard_span: Span, +} + +#[derive(Diagnostic)] +#[diag("`#[eii_declaration(...)]` expects a list of one or two elements")] +pub(crate) struct EiiExternTargetExpectedList { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag("expected this argument to be \"unsafe\"")] +pub(crate) struct EiiExternTargetExpectedUnsafe { + #[primary_span] + #[note("the second argument is optional")] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag("`#[{$name}]` is only valid on functions")] +pub(crate) struct EiiSharedMacroExpectedFunction { + #[primary_span] + pub span: Span, + pub name: String, +} + +#[derive(Diagnostic)] +#[diag("`#[{$name}]` can only be used on functions inside a module")] +pub(crate) struct EiiSharedMacroInStatementPosition { + #[primary_span] + pub span: Span, + pub name: String, + #[label("`#[{$name}]` is used on this item, which is part of another item's local scope")] + pub item_span: Span, +} + +#[derive(Diagnostic)] +#[diag("`#[{$name}]` can only be specified once")] +pub(crate) struct EiiOnlyOnce { + #[primary_span] + pub span: Span, + #[note("specified again here")] + pub first_span: Span, + pub name: String, +} + +#[derive(Diagnostic)] +#[diag("`#[{$name}]` expected no arguments or a single argument: `#[{$name}(default)]`")] +pub(crate) struct EiiMacroExpectedMaxOneArgument { + #[primary_span] + pub span: Span, + pub name: String, } diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index a0ee7ac19899..f47dae5eba00 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -160,6 +160,7 @@ fn make_format_args( ecx: &mut ExtCtxt<'_>, input: MacroInput, append_newline: bool, + macro_span: Span, ) -> ExpandResult, ()> { let msg = "format argument must be a string literal"; let unexpanded_fmt_span = input.fmtstr.span; @@ -329,6 +330,27 @@ fn make_format_args( replacement, }); } + parse::Suggestion::AddMissingColon(span) => { + let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end)); + e.sugg_ = Some(errors::InvalidFormatStringSuggestion::AddMissingColon { span }); + } + parse::Suggestion::UseRustDebugPrintingMacro => { + // This targets `println!("{=}", x);` and `println!("{0=}", x);` + if let [arg] = args.all_args() { + let expr_span = arg.expr.span; + if let Ok(expr_snippet) = ecx.source_map().span_to_snippet(expr_span) { + let replacement = format!("{}!({})", "dbg", expr_snippet); + + let call_span = macro_span.source_callsite(); + e.sugg_ = Some( + errors::InvalidFormatStringSuggestion::UseRustDebugPrintingMacro { + macro_span: call_span, + replacement, + }, + ); + } + } + } } let guar = ecx.dcx().emit_err(e); return ExpandResult::Ready(Err(guar)); @@ -1044,7 +1066,7 @@ fn expand_format_args_impl<'cx>( sp = ecx.with_def_site_ctxt(sp); ExpandResult::Ready(match parse_args(ecx, sp, tts) { Ok(input) => { - let ExpandResult::Ready(mac) = make_format_args(ecx, input, nl) else { + let ExpandResult::Ready(mac) = make_format_args(ecx, input, nl, sp) else { return ExpandResult::Retry(()); }; match mac { diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index e69f0838f22e..1bce3c03743a 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -47,7 +47,7 @@ pub(crate) fn expand( // Generate anonymous constant serving as container for the allocator methods. let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new())); - let const_body = ast::ConstItemRhs::Body(ecx.expr_block(ecx.block(span, stmts))); + let const_body = ast::ConstItemRhsKind::new_body(ecx.expr_block(ecx.block(span, stmts))); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { Annotatable::Stmt(Box::new(ecx.stmt_item(span, const_item))) @@ -77,13 +77,14 @@ impl AllocFnFactory<'_, '_> { let sig = FnSig { decl, header, span: self.span }; let body = Some(self.cx.block_expr(result)); let kind = ItemKind::Fn(Box::new(Fn { - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, sig, ident: Ident::from_str_and_span(&global_fn_name(method.name), self.span), generics: Generics::default(), contract: None, body, define_opaque: None, + eii_impls: ThinVec::new(), })); let item = self.cx.item(self.span, self.attrs(method), kind); self.cx.stmt_item(self.ty_span, item) @@ -127,11 +128,15 @@ impl AllocFnFactory<'_, '_> { let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span)); let ty_usize = self.cx.ty_path(usize); - args.push(self.cx.param(self.span, size, ty_usize.clone())); - args.push(self.cx.param(self.span, align, ty_usize)); + args.push(self.cx.param(self.span, size, ty_usize)); + let ty_align = self.ptr_alignment(); + args.push(self.cx.param(self.span, align, ty_align)); - let layout_new = - self.cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]); + let layout_new = self.cx.std_path(&[ + sym::alloc, + sym::Layout, + sym::from_size_alignment_unchecked, + ]); let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new)); let size = self.cx.expr_ident(self.span, size); let align = self.cx.expr_ident(self.span, align); @@ -174,6 +179,12 @@ impl AllocFnFactory<'_, '_> { self.cx.ty_path(usize) } + fn ptr_alignment(&self) -> Box { + let path = self.cx.std_path(&[sym::ptr, sym::Alignment]); + let path = self.cx.path(self.span, path); + self.cx.ty_path(path) + } + fn ptr_u8(&self) -> Box { let u8 = self.cx.path_ident(self.span, Ident::new(sym::u8, self.span)); let ty_u8 = self.cx.ty_path(u8); diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 221e7c3d553a..08da5935bbea 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -3,9 +3,7 @@ // tidy-alphabetical-start #![allow(internal_features)] -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::untranslatable_diagnostic)] -#![feature(assert_matches)] +#![cfg_attr(bootstrap, feature(assert_matches))] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] @@ -38,6 +36,7 @@ mod define_opaque; mod derive; mod deriving; mod edition_panic; +mod eii; mod env; mod errors; mod format; @@ -58,8 +57,6 @@ pub mod standard_library_imports; pub mod test_harness; pub mod util; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { let mut register = |name, kind| resolver.register_builtin_macro(name, kind); macro register_bang($($name:ident: $f:expr,)*) { @@ -117,9 +114,13 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { define_opaque: define_opaque::expand, derive: derive::Expander { is_const: false }, derive_const: derive::Expander { is_const: true }, + eii: eii::eii, + eii_declaration: eii::eii_declaration, + eii_shared_macro: eii::eii_shared_macro, global_allocator: global_allocator::expand, test: test::expand_test, test_case: test::expand_test_case, + unsafe_eii: eii::unsafe_eii, // tidy-alphabetical-end } diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs index 87a5a440140e..4126547b0515 100644 --- a/compiler/rustc_builtin_macros/src/pattern_type.rs +++ b/compiler/rustc_builtin_macros/src/pattern_type.rs @@ -1,5 +1,5 @@ use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast, token}; +use rustc_ast::{AnonConst, DUMMY_NODE_ID, MgcaDisambiguation, Ty, TyPat, TyPatKind, ast, token}; use rustc_errors::PResult; use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult}; use rustc_parse::exp; @@ -60,8 +60,20 @@ fn ty_pat(kind: TyPatKind, span: Span) -> TyPat { fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> TyPat { let kind = match pat.kind { ast::PatKind::Range(start, end, include_end) => TyPatKind::Range( - start.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), - end.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), + start.map(|value| { + Box::new(AnonConst { + id: DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::Direct, + }) + }), + end.map(|value| { + Box::new(AnonConst { + id: DUMMY_NODE_ID, + value, + mgca_disambiguation: MgcaDisambiguation::Direct, + }) + }), include_end, ), ast::PatKind::Or(variants) => { diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index e30d506a31b9..24a5d79958c6 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -385,7 +385,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> Box { cx.attr_nested_word(sym::allow, sym::deprecated, span), ]); - let block = ast::ConstItemRhs::Body(cx.expr_block( + let block = ast::ConstItemRhsKind::new_body(cx.expr_block( cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]), )); diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 16adaab15c52..16003c8ba135 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -13,7 +13,7 @@ use rustc_expand::base::{ }; use rustc_expand::module::DirOwnership; use rustc_parse::lexer::StripTokens; -use rustc_parse::parser::ForceCollect; +use rustc_parse::parser::{AllowConstBlockItems, ForceCollect}; use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error}; use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; use rustc_session::parse::ParseSess; @@ -68,13 +68,10 @@ pub(crate) fn expand_file( let topmost = cx.expansion_cause().unwrap_or(sp); let loc = cx.source_map().lookup_char_pos(topmost.lo()); - use rustc_session::RemapFileNameExt; - use rustc_session::config::RemapPathScopeComponents; + use rustc_span::RemapPathScopeComponents; ExpandResult::Ready(MacEager::expr(cx.expr_str( topmost, - Symbol::intern( - &loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(), - ), + Symbol::intern(&loc.file.name.display(RemapPathScopeComponents::MACRO).to_string_lossy()), ))) } @@ -147,9 +144,7 @@ pub(crate) fn expand_include<'cx>( let mut p = unwrap_or_emit_fatal(new_parser_from_file( self.psess, &self.path, - // Don't strip frontmatter for backward compatibility, `---` may be the start of a - // manifold negation. FIXME: Ideally, we wouldn't strip shebangs here either. - StripTokens::Shebang, + StripTokens::Nothing, Some(self.span), )); let expr = parse_expr(&mut p).ok()?; @@ -173,7 +168,7 @@ pub(crate) fn expand_include<'cx>( )); let mut ret = SmallVec::new(); loop { - match p.parse_item(ForceCollect::No) { + match p.parse_item(ForceCollect::No, AllowConstBlockItems::Yes) { Err(err) => { err.emit(); break; @@ -280,7 +275,15 @@ fn load_binary_file( } }; match cx.source_map().load_binary_file(&resolved_path) { - Ok(data) => Ok(data), + Ok(data) => { + cx.sess + .psess + .file_depinfo + .borrow_mut() + .insert(Symbol::intern(&resolved_path.to_string_lossy())); + + Ok(data) + } Err(io_err) => { let mut err = cx.dcx().struct_span_err( macro_span, diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 2068b5ca54dd..9f22d9eacb33 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -43,7 +43,7 @@ pub fn inject( let item = cx.item( span, - thin_vec![cx.attr_word(sym::macro_use, span)], + ast::AttrVec::new(), ast::ItemKind::ExternCrate(None, Ident::new(name, ident_span)), ); diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index f31ad4f591b1..45d5daf91327 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -1,17 +1,17 @@ //! The expansion from a test function to the appropriate test struct for libtest //! Ideally, this code would be in libtest but for efficiency and error messages it lives here. -use std::assert_matches::assert_matches; use std::iter; use rustc_ast::{self as ast, GenericParamKind, HasNodeId, attr, join_path_idents}; use rustc_ast_pretty::pprust; use rustc_attr_parsing::AttributeParser; +use rustc_data_structures::assert_matches; use rustc_errors::{Applicability, Diag, Level}; use rustc_expand::base::*; use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; -use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Ident, Span, Symbol, sym}; +use rustc_span::{ErrorGuaranteed, Ident, RemapPathScopeComponents, Span, Symbol, sym}; use thin_vec::{ThinVec, thin_vec}; use tracing::debug; @@ -283,13 +283,13 @@ pub(crate) fn expand_test_or_bench( // const $ident: test::TestDescAndFn = ast::ItemKind::Const( ast::ConstItem { - defaultness: ast::Defaultness::Final, + defaultness: ast::Defaultness::Implicit, ident: Ident::new(fn_.ident.name, sp), generics: ast::Generics::default(), ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), define_opaque: None, // test::TestDescAndFn { - rhs: Some(ast::ConstItemRhs::Body( + rhs_kind: ast::ConstItemRhsKind::new_body( cx.expr_struct( sp, test_path("TestDescAndFn"), @@ -371,7 +371,7 @@ pub(crate) fn expand_test_or_bench( field("testfn", test_fn), // } ], ), // } - )), + ), } .into(), ), @@ -445,7 +445,7 @@ fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize, cx.sess.source_map().span_to_location_info(span); let file_name = match source_file { - Some(sf) => sf.name.display(FileNameDisplayPreference::Remapped).to_string(), + Some(sf) => sf.name.display(RemapPathScopeComponents::MACRO).to_string(), None => "no-location".to_string(), }; diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 2a6ac5754bfa..1bb6d8a6bfd0 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -8,10 +8,11 @@ use rustc_ast::entry::EntryPointType; use rustc_ast::mut_visit::*; use rustc_ast::visit::Visitor; use rustc_ast::{ModKind, attr}; -use rustc_errors::DiagCtxtHandle; +use rustc_attr_parsing::AttributeParser; use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_feature::Features; +use rustc_hir::attrs::AttributeKind; use rustc_session::Session; use rustc_session::lint::builtin::UNNAMEABLE_TEST_ITEMS; use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency}; @@ -60,7 +61,7 @@ pub fn inject( // Do this here so that the test_runner crate attribute gets marked as used // even in non-test builds - let test_runner = get_test_runner(dcx, krate); + let test_runner = get_test_runner(sess, features, krate); if sess.is_test_crate() { let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) { @@ -329,7 +330,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box { let decl = ecx.fn_decl(ThinVec::new(), ast::FnRetTy::Ty(main_ret_ty)); let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp }; - let defaultness = ast::Defaultness::Final; + let defaultness = ast::Defaultness::Implicit; // Honor the reexport_test_harness_main attribute let main_ident = match cx.reexport_test_harness_main { @@ -345,6 +346,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box { contract: None, body: Some(main_body), define_opaque: None, + eii_impls: ThinVec::new(), })); let main = Box::new(ast::Item { @@ -385,20 +387,16 @@ fn get_test_name(i: &ast::Item) -> Option { attr::first_attr_value_str_by_name(&i.attrs, sym::rustc_test_marker) } -fn get_test_runner(dcx: DiagCtxtHandle<'_>, krate: &ast::Crate) -> Option { - let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?; - let meta_list = test_attr.meta_item_list()?; - let span = test_attr.span; - match &*meta_list { - [single] => match single.meta_item() { - Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()), - _ => { - dcx.emit_err(errors::TestRunnerInvalid { span }); - } - }, - _ => { - dcx.emit_err(errors::TestRunnerNargs { span }); - } +fn get_test_runner(sess: &Session, features: &Features, krate: &ast::Crate) -> Option { + match AttributeParser::parse_limited( + sess, + &krate.attrs, + sym::test_runner, + krate.spans.inner_span, + krate.id, + Some(features), + ) { + Some(rustc_hir::Attribute::Parsed(AttributeKind::TestRunner(path))) => Some(path), + _ => None, } - None } diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index e26f31dce67b..9ac3d0e7eac1 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -78,8 +78,6 @@ type UnexpectedExprKind<'a> = Result<(Diag<'a>, bool /* has_suggestions */), Err /// The returned bool indicates whether an applicable suggestion has already been /// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))` /// indicates that an ast error was encountered. -// FIXME(Nilstrieb) Make this function setup translatable -#[allow(rustc::untranslatable_diagnostic)] pub(crate) fn expr_to_spanned_string<'a>( cx: &'a mut ExtCtxt<'_>, expr: Box, diff --git a/compiler/rustc_codegen_cranelift/.cirrus.yml b/compiler/rustc_codegen_cranelift/.cirrus.yml index 3ed89beceb7f..9be095dbf2d8 100644 --- a/compiler/rustc_codegen_cranelift/.cirrus.yml +++ b/compiler/rustc_codegen_cranelift/.cirrus.yml @@ -1,7 +1,7 @@ task: name: freebsd freebsd_instance: - image_family: freebsd-14-2 + image_family: freebsd-15-0-amd64-ufs setup_rust_script: - pkg install -y git-tiny binutils - curl https://sh.rustup.rs -sSf --output rustup.sh diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml index 27c95572ef87..274b9504beb0 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/audit.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: | - sed -i 's/components.*/components = []/' rust-toolchain + sed -i 's/components.*/components = []/' rust-toolchain.toml - uses: rustsec/audit-check@v1.4.1 with: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml index 0930b924d177..07d9af4a9b54 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: - name: Avoid installing rustc-dev run: | - sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain + sed -i 's/components.*/components = ["rustfmt"]/' rust-toolchain.toml rustfmt -v - name: Rustfmt @@ -88,7 +88,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Set MinGW as the default toolchain if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' @@ -158,7 +158,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-x86_64-unknown-linux-gnu-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Install hyperfine run: | @@ -207,7 +207,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-dist-cargo-build-target-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }} - name: Set MinGW as the default toolchain if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml index 9253ab96353c..b22725fdc9d4 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }} - name: Test run: ./scripts/test_bootstrap.sh @@ -40,7 +40,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain.toml', 'Cargo.lock') }} - name: Install ripgrep run: | diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index 09b6c6b87c30..3d13b5540e19 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/Cargo.lock @@ -10,15 +10,15 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "bitflags" @@ -37,48 +37,48 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cranelift-assembler-x64" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f502c60b6af2025c312b37788c089943ef03156a2910da1aa046bb39eb8f61c7" +checksum = "8bd963a645179fa33834ba61fa63353998543b07f877e208da9eb47d4a70d1e7" dependencies = [ "cranelift-assembler-x64-meta", ] [[package]] name = "cranelift-assembler-x64-meta" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b7e21a74bcf08443a4ef800a4a257063e5c51ee4d7a3bd58da5262d10340830" +checksum = "3f6d5739c9dc6b5553ca758d78d87d127dd19f397f776efecf817b8ba8d0bb01" dependencies = [ "cranelift-srcgen", ] [[package]] name = "cranelift-bforest" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f337d268865c292ad5df0669a9bbf6223ca41460292a20ad5b0a57b8e9f27f93" +checksum = "ff402c11bb1c9652b67a3e885e84b1b8d00c13472c8fd85211e06a41a63c3e03" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-bitset" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0e60319a8242c8d1c7b5a2444d140c416f903f75e0d84da3256fceb822bab85" +checksum = "769a0d88c2f5539e9c5536a93a7bf164b0dc68d91e3d00723e5b4ffc1440afdc" [[package]] name = "cranelift-codegen" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78dee669e447a1c68760bf7acee33835e99d564f0137b067f74d4718dfc9970d" +checksum = "d4351f721fb3b26add1c180f0a75c7474bab2f903c8b777c6ca65238ded59a78" dependencies = [ "bumpalo", "cranelift-assembler-x64", @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601f629d172b7230f41dd0e78ee797efaf7ec1a5e113c8f395f4027dff6a92ca" +checksum = "61f86c0ba5b96713643f4dd0de0df12844de9c7bb137d6829b174b706939aa74" dependencies = [ "cranelift-assembler-x64-meta", "cranelift-codegen-shared", @@ -114,33 +114,33 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15755c2660902c7d59d96f6551a66ef629650dc3fd405f9dad841e8c58c1a4a2" +checksum = "f08605eee8d51fd976a970bd5b16c9529b51b624f8af68f80649ffb172eb85a4" [[package]] name = "cranelift-control" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727bfca18705101a294ab9077ad214a8b762ea2bc9844389d0db233d7c61ec3b" +checksum = "623aab0a09e40f0cf0b5d35eb7832bae4c4f13e3768228e051a6c1a60e88ef5f" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15564c6f0c72750ca4374f40b044857cbc8087571e46d4c7ccdbdcc29b1dec8b" +checksum = "ea0f066e07e3bcbe38884cc5c94c32c7a90267d69df80f187d9dfe421adaa7c4" dependencies = [ "cranelift-bitset", ] [[package]] name = "cranelift-frontend" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16c681f2731f1cf68eed9f3b6811571823a5ac498f59c52b73736b68599defb3" +checksum = "40865b02a0e52ca8e580ad64feef530cb1d05f6bb4972b4eef05e3eaeae81701" dependencies = [ "cranelift-codegen", "log", @@ -150,15 +150,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40cedc02f08307da019a3e06d3f20f772f829ff813aec975accb012f8930b688" +checksum = "104b3c117ae513e9af1d90679842101193a5ccb96ac9f997966d85ea25be2852" [[package]] name = "cranelift-jit" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2864461448c72d15ae3311ea63df9c7e35f22f04683785f6715a0cf17e6577d" +checksum = "3aa5f855cfb8e4253ed2d0dfc1a0b6ebe4912e67aa8b7ee14026ff55ca17f1fe" dependencies = [ "anyhow", "cranelift-codegen", @@ -171,14 +171,14 @@ dependencies = [ "region", "target-lexicon", "wasmtime-internal-jit-icache-coherence", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "cranelift-module" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b31d249bbbccc4c1ae54701087d4d49d05951897691eef44f4a60e70252743b" +checksum = "b1d01806b191b59f4fc4680293dd5f554caf2de5b62f95eff5beef7acb46c29c" dependencies = [ "anyhow", "cranelift-codegen", @@ -187,9 +187,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db03ab51c60710eb83d0217725b77db4062aca83b35359f5e6aa99ed1c275977" +checksum = "e5c54e0a358bc05b48f2032e1c320e7f468da068604f2869b77052eab68eb0fe" dependencies = [ "cranelift-codegen", "libc", @@ -198,9 +198,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131e0eb45ee10b0bd6082d0c0114c2e9a670b034d46774b39d0fc5c0ed7cedf" +checksum = "3d17e0216be5daabab616647c1918e06dae0708474ba5f7b7762ac24ea5eb126" dependencies = [ "anyhow", "cranelift-codegen", @@ -213,9 +213,9 @@ dependencies = [ [[package]] name = "cranelift-srcgen" -version = "0.125.1" +version = "0.127.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7a06c330b7994a891ad5b622ebc9aefcd17beae832dd25f577cf60c13426bf" +checksum = "cc6f4b039f453b66c75e9f7886e5a2af96276e151f44dc19b24b58f9a0c98009" [[package]] name = "crc32fast" @@ -246,9 +246,9 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "gimli" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", "indexmap", @@ -282,18 +282,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" -version = "0.8.8" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link", ] [[package]] @@ -304,9 +304,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "mach2" @@ -319,9 +319,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "object" @@ -337,27 +337,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] [[package]] name = "regalloc2" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd8138ce7c3d7c13be4f61893154b5d711bd798d2d7be3ecb8dcc7e7a06ca98" +checksum = "4e249c660440317032a71ddac302f25f1d5dff387667bcc3978d1f77aa31ac34" dependencies = [ "allocator-api2", "bumpalo", @@ -405,18 +405,27 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -431,15 +440,15 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -448,42 +457,42 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "wasmtime-internal-jit-icache-coherence" -version = "38.0.1" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d0a76f1a6e887cc1b551b02dfd6e2ce5f6738e8cacd9ad7284f6ac1aac4698f" +checksum = "0858b470463f3e7c73acd6049046049e64be17b98901c2db5047450cf83df1fe" dependencies = [ "anyhow", "cfg-if", "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "wasmtime-internal-math" -version = "38.0.1" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b900df4252ad86547e7f2b2c00201b006db4e864893bedfb3aca32b23d81868a" +checksum = "222e1a590ece4e898f20af1e541b61d2cb803f2557e7eaff23e6c1db5434454a" dependencies = [ "libm", ] [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -491,16 +500,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.53.3", + "windows-link", ] [[package]] @@ -509,31 +518,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -542,92 +534,44 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index f2001123e579..ee4bde477c47 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml @@ -8,28 +8,28 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.125.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } -cranelift-frontend = { version = "0.125.0" } -cranelift-module = { version = "0.125.0" } -cranelift-native = { version = "0.125.0" } -cranelift-jit = { version = "0.125.0", optional = true } -cranelift-object = { version = "0.125.0" } +cranelift-codegen = { version = "0.127.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] } +cranelift-frontend = { version = "0.127.0" } +cranelift-module = { version = "0.127.0" } +cranelift-native = { version = "0.127.0" } +cranelift-jit = { version = "0.127.0", optional = true } +cranelift-object = { version = "0.127.0" } target-lexicon = "0.13" gimli = { version = "0.32", default-features = false, features = ["write"] } object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } indexmap = "2.0.0" -libloading = { version = "0.8.0", optional = true } +libloading = { version = "0.9.0", optional = true } smallvec = "1.8.1" [patch.crates-io] # Uncomment to use an unreleased version of cranelift -#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } -#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" } +#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } +#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-40.0.0" } # Uncomment to use local checkout of cranelift #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" } diff --git a/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs b/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs index 5a393a217c27..762b2be8f440 100644 --- a/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs +++ b/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs @@ -11,7 +11,7 @@ static ABI_CAFE_REPO: GitRepo = GitRepo::github( "abi-cafe", ); -static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe_target"); +static ABI_CAFE: CargoProject = CargoProject::new(ABI_CAFE_REPO.source_dir(), "abi_cafe_target"); pub(crate) fn run( sysroot_kind: SysrootKind, diff --git a/compiler/rustc_codegen_cranelift/build_system/bench.rs b/compiler/rustc_codegen_cranelift/build_system/bench.rs index 192cb499536f..91353ba8a874 100644 --- a/compiler/rustc_codegen_cranelift/build_system/bench.rs +++ b/compiler/rustc_codegen_cranelift/build_system/bench.rs @@ -39,7 +39,26 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { let rustc_clif = &compiler.rustc; let rustflags = &compiler.rustflags.join("\x1f"); let manifest_path = SIMPLE_RAYTRACER_REPO.source_dir().to_path(dirs).join("Cargo.toml"); - let target_dir = dirs.build_dir.join("simple_raytracer"); + let target_dir = dirs.build_dir.join("simple-raytracer_target"); + + let raytracer_cg_llvm = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin")) + .to_str() + .unwrap() + .to_owned(); + let raytracer_cg_clif = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin")) + .to_str() + .unwrap() + .to_owned(); + let raytracer_cg_clif_opt = dirs + .build_dir + .join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin")) + .to_str() + .unwrap() + .to_owned(); let clean_cmd = format!( "RUSTC=rustc cargo clean --manifest-path {manifest_path} --target-dir {target_dir}", @@ -47,19 +66,19 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { target_dir = target_dir.display(), ); let llvm_build_cmd = format!( - "RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_llvm || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_llvm", + "RUSTC=rustc cargo build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_llvm} || true) && ln {target_dir}/debug/main {raytracer_cg_llvm}", manifest_path = manifest_path.display(), target_dir = target_dir.display(), ); let clif_build_cmd = format!( - "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm build/raytracer_cg_clif || true) && ln build/simple_raytracer/debug/main build/raytracer_cg_clif", + "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} && (rm {raytracer_cg_clif} || true) && ln {target_dir}/debug/main {raytracer_cg_clif}", cargo_clif = cargo_clif.display(), rustc_clif = rustc_clif.display(), manifest_path = manifest_path.display(), target_dir = target_dir.display(), ); let clif_build_opt_cmd = format!( - "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm build/raytracer_cg_clif_opt || true) && ln build/simple_raytracer/release/main build/raytracer_cg_clif_opt", + "RUSTC={rustc_clif} CARGO_ENCODED_RUSTFLAGS=\"{rustflags}\" CARGO_BUILD_INCREMENTAL=true {cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir} --release && (rm {raytracer_cg_clif_opt} || true) && ln {target_dir}/release/main {raytracer_cg_clif_opt}", cargo_clif = cargo_clif.display(), rustc_clif = rustc_clif.display(), manifest_path = manifest_path.display(), @@ -92,20 +111,14 @@ pub(crate) fn benchmark(dirs: &Dirs, compiler: &Compiler) { let bench_run_markdown = dirs.build_dir.join("bench_run.md"); - let raytracer_cg_llvm = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_llvm", "bin")); - let raytracer_cg_clif = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif", "bin")); - let raytracer_cg_clif_opt = - Path::new(".").join(get_file_name(&compiler.rustc, "raytracer_cg_clif_opt", "bin")); let mut bench_run = hyperfine_command( 0, bench_runs, None, &[ - ("", raytracer_cg_llvm.to_str().unwrap()), - ("", raytracer_cg_clif.to_str().unwrap()), - ("", raytracer_cg_clif_opt.to_str().unwrap()), + ("build/raytracer_cg_llvm", &raytracer_cg_llvm), + ("build/raytracer_cg_clif", &raytracer_cg_clif), + ("build/raytracer_cg_clif_opt", &raytracer_cg_clif_opt), ], &bench_run_markdown, ); diff --git a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs index b9fa0ff2d94c..c0a8cc95614f 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs +++ b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs @@ -6,7 +6,7 @@ use crate::rustc_info::get_file_name; use crate::shared_utils::{rustflags_from_env, rustflags_to_cmd_env}; use crate::utils::{CargoProject, Compiler, LogGroup}; -static CG_CLIF: CargoProject = CargoProject::new(&RelPath::source("."), "cg_clif"); +static CG_CLIF: CargoProject = CargoProject::new(RelPath::source("."), "cg_clif"); pub(crate) fn build_backend( dirs: &Dirs, @@ -22,6 +22,11 @@ pub(crate) fn build_backend( rustflags.push("-Zallow-features=rustc_private,f16,f128".to_owned()); rustflags_to_cmd_env(&mut cmd, "RUSTFLAGS", &rustflags); + // Use incr comp despite release mode unless incremental builds are explicitly disabled + if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { + cmd.env("CARGO_BUILD_INCREMENTAL", "true"); + } + if env::var("CG_CLIF_EXPENSIVE_CHECKS").is_ok() { // Enabling debug assertions implicitly enables the clif ir verifier cmd.env("CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS", "true"); diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs index 70504ee8007d..7b4c604580c1 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs +++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs @@ -140,7 +140,7 @@ impl SysrootTarget { static STDLIB_SRC: RelPath = RelPath::build("stdlib"); static STANDARD_LIBRARY: CargoProject = - CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target"); + CargoProject::new(RelPath::build("stdlib/library/sysroot"), "stdlib_target"); fn build_sysroot_for_triple( dirs: &Dirs, @@ -251,6 +251,10 @@ fn build_clif_sysroot_for_triple( if compiler.triple.contains("apple") { build_cmd.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed"); } + // Use incr comp despite release mode unless incremental builds are explicitly disabled + if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { + build_cmd.env("CARGO_BUILD_INCREMENTAL", "true"); + } spawn_and_wait(build_cmd); for entry in fs::read_dir(build_dir.join("deps")).unwrap() { diff --git a/compiler/rustc_codegen_cranelift/build_system/main.rs b/compiler/rustc_codegen_cranelift/build_system/main.rs index fc0093128300..6251687babc6 100644 --- a/compiler/rustc_codegen_cranelift/build_system/main.rs +++ b/compiler/rustc_codegen_cranelift/build_system/main.rs @@ -59,11 +59,6 @@ fn main() { } env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1"); - // Force incr comp even in release mode unless in CI or incremental builds are explicitly disabled - if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() { - env::set_var("CARGO_BUILD_INCREMENTAL", "true"); - } - let mut args = env::args().skip(1); let command = match args.next().as_deref() { Some("prepare") => Command::Prepare, @@ -79,7 +74,7 @@ fn main() { } }; - let mut out_dir = PathBuf::from("."); + let mut out_dir = std::env::current_dir().unwrap(); let mut download_dir = None; let mut sysroot_kind = SysrootKind::Clif; let mut use_unstable_features = true; diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index dd8cf929bc2f..3b6a2e7a055c 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs @@ -129,7 +129,7 @@ pub(crate) static RAND_REPO: GitRepo = GitRepo::github( "rand", ); -static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand_target"); +static RAND: CargoProject = CargoProject::new(RAND_REPO.source_dir(), "rand_target"); pub(crate) static REGEX_REPO: GitRepo = GitRepo::github( "rust-lang", @@ -139,15 +139,15 @@ pub(crate) static REGEX_REPO: GitRepo = GitRepo::github( "regex", ); -static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir(), "regex_target"); +static REGEX: CargoProject = CargoProject::new(REGEX_REPO.source_dir(), "regex_target"); static PORTABLE_SIMD_SRC: RelPath = RelPath::build("portable-simd"); -static PORTABLE_SIMD: CargoProject = CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target"); +static PORTABLE_SIMD: CargoProject = CargoProject::new(PORTABLE_SIMD_SRC, "portable-simd_target"); static SYSROOT_TESTS_SRC: RelPath = RelPath::build("sysroot_tests"); -static SYSROOT_TESTS: CargoProject = CargoProject::new(&SYSROOT_TESTS_SRC, "sysroot_tests_target"); +static SYSROOT_TESTS: CargoProject = CargoProject::new(SYSROOT_TESTS_SRC, "sysroot_tests_target"); const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ TestCase::custom("test.rust-random/rand", &|runner| { diff --git a/compiler/rustc_codegen_cranelift/build_system/utils.rs b/compiler/rustc_codegen_cranelift/build_system/utils.rs index 3266aa0ce8b6..5c7cefa120a7 100644 --- a/compiler/rustc_codegen_cranelift/build_system/utils.rs +++ b/compiler/rustc_codegen_cranelift/build_system/utils.rs @@ -75,12 +75,12 @@ impl Compiler { } pub(crate) struct CargoProject { - source: &'static RelPath, + source: RelPath, target: &'static str, } impl CargoProject { - pub(crate) const fn new(path: &'static RelPath, target: &'static str) -> CargoProject { + pub(crate) const fn new(path: RelPath, target: &'static str) -> CargoProject { CargoProject { source: path, target } } diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index b522ea193716..5293b458d8c4 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -622,11 +622,6 @@ impl Deref for Box { } } -#[lang = "exchange_malloc"] -unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { - unsafe { libc::malloc(size) } -} - #[lang = "drop"] pub trait Drop { fn drop(&mut self); @@ -744,43 +739,43 @@ unsafe extern "C" { pub struct VaList<'a>(&'a mut VaListImpl); #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro stringify($($t:tt)*) { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro file() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro line() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro cfg() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro asm() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro global_asm() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro naked_asm() { /* compiler built-in */ } diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs index c569ef0ef829..33db75f0943a 100644 --- a/compiler/rustc_codegen_cranelift/example/std_example.rs +++ b/compiler/rustc_codegen_cranelift/example/std_example.rs @@ -259,6 +259,9 @@ unsafe fn test_simd() { test_mm_cvttps_epi32(); test_mm_cvtsi128_si64(); + #[cfg(not(jit))] + test_mm_cvtps_ph(); + test_mm_extract_epi8(); test_mm_insert_epi16(); test_mm_shuffle_epi8(); @@ -558,6 +561,21 @@ unsafe fn test_mm_cvttps_epi32() { } } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "f16c")] +#[cfg(not(jit))] +unsafe fn test_mm_cvtps_ph() { + const F16_ONE: i16 = 0x3c00; + const F16_TWO: i16 = 0x4000; + const F16_THREE: i16 = 0x4200; + const F16_FOUR: i16 = 0x4400; + + let a = _mm_set_ps(1.0, 2.0, 3.0, 4.0); + let r = _mm_cvtps_ph::<_MM_FROUND_CUR_DIRECTION>(a); + let e = _mm_set_epi16(0, 0, 0, 0, F16_ONE, F16_TWO, F16_THREE, F16_FOUR); + assert_eq_m128i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch b/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch deleted file mode 100644 index b1fd6224632b..000000000000 --- a/compiler/rustc_codegen_cranelift/patches/0001-portable-simd-Disable-broken-reduce_sum-test.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5489384bc265e9e6fc2efaa63d93a4d51ebec2f5 Mon Sep 17 00:00:00 2001 -From: bjorn3 <17426603+bjorn3@users.noreply.github.com> -Date: Thu, 22 Aug 2024 19:22:58 +0000 -Subject: [PATCH] Disable broken reduce_sum test - -It was broken by an upstream change to the .sum() implementation on -float iterators. ---- - crates/core_simd/tests/ops_macros.rs | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs -index aa565a1..5e6ac41 100644 ---- a/crates/core_simd/tests/ops_macros.rs -+++ b/crates/core_simd/tests/ops_macros.rs -@@ -646,6 +646,7 @@ macro_rules! impl_float_tests { - } - - fn reduce_sum() { -+ return; - test_helpers::test_1(&|x| { - test_helpers::prop_assert_biteq! ( - Vector::::from_array(x).reduce_sum(), --- -2.34.1 - diff --git a/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch index f3d1d5c43ea1..6ed0b17f679c 100644 --- a/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch +++ b/compiler/rustc_codegen_cranelift/patches/0027-sysroot_tests-128bit-atomic-operations.patch @@ -14,11 +14,10 @@ diff --git a/coretests/tests/lib.rs b/coretests/tests/lib.rs index 1e336bf..35e6f54 100644 --- a/coretests/tests/lib.rs +++ b/coretests/tests/lib.rs -@@ -2,5 +2,4 @@ +@@ -2,4 +2,3 @@ // tidy-alphabetical-start -#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))] #![cfg_attr(test, feature(cfg_select))] - #![feature(alloc_layout_extra)] #![feature(array_ptr_get)] diff --git a/coretests/tests/atomic.rs b/coretests/tests/atomic.rs index b735957..ea728b6 100644 diff --git a/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-disable-f16-math.patch b/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-disable-f16-math.patch new file mode 100644 index 000000000000..6a0244cfde3f --- /dev/null +++ b/compiler/rustc_codegen_cranelift/patches/0029-sysroot_tests-disable-f16-math.patch @@ -0,0 +1,133 @@ +From 285d5716fcfa6d43a3516d899b73bc85da322c25 Mon Sep 17 00:00:00 2001 +From: xonx <119700621+xonx4l@users.noreply.github.com> +Date: Sun, 15 Feb 2026 14:06:49 +0000 +Subject: [PATCH] Disable f16 math tests for cranelift + +--- + coretests/tests/floats/mod.rs | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/coretests/tests/floats/mod.rs b/coretests/tests/floats/mod.rs +index c61961f8584..d7b4fa20322 100644 +--- a/coretests/tests/floats/mod.rs ++++ b/coretests/tests/floats/mod.rs +@@ -1534,7 +1534,7 @@ fn s_nan() -> Float { + name: powf, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1557,7 +1557,7 @@ fn s_nan() -> Float { + name: exp, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1578,7 +1578,7 @@ fn s_nan() -> Float { + name: exp2, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1598,7 +1598,7 @@ fn s_nan() -> Float { + name: ln, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1620,7 +1620,7 @@ fn s_nan() -> Float { + name: log, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1645,7 +1645,7 @@ fn s_nan() -> Float { + name: log2, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1668,7 +1668,7 @@ fn s_nan() -> Float { + name: log10, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1692,7 +1692,7 @@ fn s_nan() -> Float { + name: asinh, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1725,7 +1725,7 @@ fn s_nan() -> Float { + name: acosh, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1753,7 +1753,7 @@ fn s_nan() -> Float { + name: atanh, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1779,7 +1779,7 @@ fn s_nan() -> Float { + name: gamma, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -1814,7 +1814,7 @@ fn s_nan() -> Float { + name: ln_gamma, + attrs: { + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +@@ -2027,7 +2027,7 @@ fn s_nan() -> Float { + attrs: { + // FIXME(f16_f128): add math tests when available + const: #[cfg(false)], +- f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], ++ f16: #[cfg(false)], // FIXME(rust-lang/rustc_codegen_cranelift#1622) + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], + }, + test { +-- +2.50.1 + diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain deleted file mode 100644 index 17c2cc5ac660..000000000000 --- a/compiler/rustc_codegen_cranelift/rust-toolchain +++ /dev/null @@ -1,4 +0,0 @@ -[toolchain] -channel = "nightly-2025-11-08" -components = ["rust-src", "rustc-dev", "llvm-tools"] -profile = "minimal" diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain.toml b/compiler/rustc_codegen_cranelift/rust-toolchain.toml new file mode 100644 index 000000000000..b157c5879ba7 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2025-12-23" +components = ["rust-src", "rustc-dev", "llvm-tools", "rustfmt"] +profile = "minimal" diff --git a/compiler/rustc_codegen_cranelift/scripts/rustup.sh b/compiler/rustc_codegen_cranelift/scripts/rustup.sh index fdfd03029b16..e26be307328f 100755 --- a/compiler/rustc_codegen_cranelift/scripts/rustup.sh +++ b/compiler/rustc_codegen_cranelift/scripts/rustup.sh @@ -22,8 +22,7 @@ case $1 in "prepare") echo "=> Installing new nightly" rustup toolchain install --profile minimal "nightly-${TOOLCHAIN}" # Sanity check to see if the nightly exists - sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain - rustup component add rustfmt || true + sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain.toml echo "=> Uninstalling all old nightlies" for nightly in $(rustup toolchain list | grep nightly | grep -v "$TOOLCHAIN" | grep -v nightly-x86_64); do @@ -35,7 +34,7 @@ case $1 in ./y.sh prepare ;; "commit") - git add rust-toolchain + git add rust-toolchain.toml git commit -m "Rustup to $(rustc -V)" ;; "push") @@ -43,7 +42,7 @@ case $1 in cg_clif=$(pwd) pushd ../rust - git pull origin master + git pull origin main branch=sync_cg_clif-$(date +%Y-%m-%d) git checkout -b "$branch" "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main @@ -63,7 +62,7 @@ case $1 in cg_clif=$(pwd) pushd ../rust - git fetch origin master + git fetch origin main git -c advice.detachedHead=false checkout "$RUST_VERS" "$cg_clif/git-fixed-subtree.sh" push --prefix=compiler/rustc_codegen_cranelift/ "$cg_clif" sync_from_rust popd diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index b5af585a732e..b25269d1430a 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -35,6 +35,7 @@ git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.round.ps rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funnel_{shl,shr} +rm -r tests/ui/scalable-vectors # scalable vectors are unsupported # exotic linkages rm tests/incremental/hashes/function_interfaces.rs @@ -53,23 +54,29 @@ rm tests/ui/sanitizer/kcfi-c-variadic.rs # same rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported rm tests/ui/delegation/fn-header.rs +# inline assembly features +rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly +rm tests/ui/asm/global-asm-mono-sym-fn.rs # same +rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same +rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported +rm tests/ui/asm/label-operand.rs # same +rm tests/ui/asm/may_unwind.rs # asm unwinding not supported +rm tests/ui/asm/aarch64/may_unwind.rs # same + # misc unimplemented things rm tests/ui/target-feature/missing-plusminus.rs # error not implemented rm -r tests/run-make/repr128-dwarf # debuginfo test rm -r tests/run-make/split-debuginfo # same rm -r tests/run-make/target-specs # i686 not supported by Cranelift rm -r tests/run-make/mismatching-target-triples # same -rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly -rm tests/ui/asm/global-asm-mono-sym-fn.rs # same -rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same -rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported -rm tests/ui/asm/label-operand.rs # same rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported rm -r tests/ui/explicit-tail-calls # tail calls rm -r tests/run-make/pointer-auth-link-with-c # pointer auth +rm -r tests/ui/eii # EII not yet implemented +rm -r tests/run-make/forced-unwind-terminate-pof # forced unwinding doesn't take precedence # requires LTO rm -r tests/run-make/cdylib @@ -78,6 +85,7 @@ rm -r tests/run-make/lto-* rm -r tests/run-make/reproducible-build-2 rm -r tests/run-make/no-builtins-lto rm -r tests/run-make/reachable-extern-fn-available-lto +rm -r tests/run-make/no-builtins-linker-plugin-lto # coverage instrumentation rm tests/ui/consts/precise-drop-with-coverage.rs @@ -87,6 +95,7 @@ rm -r tests/ui/instrument-coverage/ # ================== rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations rm tests/ui/codegen/init-large-type.rs # same +rm tests/ui/codegen/StackColoring-not-blowup-stack-issue-40883.rs # same rm tests/ui/statics/const_generics.rs # tests an optimization rm tests/ui/linking/executable-no-mangle-strip.rs # requires --gc-sections to work for statics @@ -143,6 +152,15 @@ rm tests/ui/errors/remap-path-prefix-sysroot.rs # different sysroot source path rm -r tests/run-make/export/extern-opt # something about rustc version mismatches rm -r tests/run-make/export # same rm -r tests/ui/compiletest-self-test/compile-flags-incremental.rs # needs compiletest compiled with panic=unwind +rm tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs # something going wrong with stdlib source remapping +rm tests/ui/consts/miri_unleashed/drop.rs # same +rm tests/ui/error-emitter/multiline-removal-suggestion.rs # same +rm tests/ui/lint/lint-const-item-mutation.rs # same +rm tests/ui/lint/use-redundant/use-redundant-issue-71450.rs # same +rm tests/ui/lint/use-redundant/use-redundant-prelude-rust-2021.rs # same +rm tests/ui/specialization/const_trait_impl.rs # same +rm tests/ui/thir-print/offset_of.rs # same +rm tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs # same # genuine bugs # ============ @@ -157,6 +175,7 @@ rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493) rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables rm -r tests/run-make-cargo/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug +rm -r tests/incremental/extern_static/issue-49153.rs # assumes reference to undefined static gets optimized away rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd rm tests/ui/process/process-panic-after-fork.rs # same diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 09d71f5dd557..5a46f79e2ba0 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -56,6 +56,9 @@ pub(crate) fn conv_to_call_conv( CanonAbi::Rust | CanonAbi::C => default_call_conv, CanonAbi::RustCold => CallConv::Cold, + // Cranelift doesn't currently have anything for this. + CanonAbi::RustPreserveNone => default_call_conv, + // Functions with this calling convention can only be called from assembly, but it is // possible to declare an `extern "custom"` block, so the backend still needs a calling // convention for declaring foreign functions. diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 67b89114356b..4a9b0c0952ff 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -6,7 +6,6 @@ use rustc_ast::expand::allocator::{ AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents}; -use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; use crate::prelude::*; @@ -15,16 +14,11 @@ use crate::prelude::*; pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; let methods = allocator_shim_contents(tcx, kind); - codegen_inner(tcx, module, &methods, tcx.sess.opts.unstable_opts.oom); + codegen_inner(tcx, module, &methods); true } -fn codegen_inner( - tcx: TyCtxt<'_>, - module: &mut dyn Module, - methods: &[AllocatorMethod], - oom_strategy: OomStrategy, -) { +fn codegen_inner(tcx: TyCtxt<'_>, module: &mut dyn Module, methods: &[AllocatorMethod]) { let usize_ty = module.target_config().pointer_type(); for method in methods { @@ -65,35 +59,6 @@ fn codegen_inner( ); } - { - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![], - returns: vec![AbiParam::new(types::I8)], - }; - let func_id = module - .declare_function( - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - Linkage::Export, - &sig, - ) - .unwrap(); - let mut ctx = Context::new(); - ctx.func.signature = sig; - { - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); - - let block = bcx.create_block(); - bcx.switch_to_block(block); - let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64); - bcx.ins().return_(&[value]); - bcx.seal_all_blocks(); - bcx.finalize(); - } - module.define_function(func_id, &mut ctx).unwrap(); - } - { let sig = Signature { call_conv: module.target_config().default_call_conv, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index a0bee4e18214..e4865ece63b6 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -10,7 +10,7 @@ use rustc_data_structures::profiling::SelfProfilerRef; use rustc_index::IndexVec; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv}; +use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_session::config::OutputFilenames; use rustc_span::Symbol; @@ -167,7 +167,7 @@ pub(crate) fn compile_fn( context.clear(); context.func = codegened_func.func; - #[cfg(any())] // This is never true + #[cfg(false)] let _clif_guard = { use std::fmt::Write; @@ -853,17 +853,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: fx.bcx.ins().nop(); } } - Rvalue::NullaryOp(ref null_op) => { - assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env())); - let val = match null_op { - NullOp::RuntimeChecks(kind) => kind.value(fx.tcx.sess), - }; - let val = CValue::by_val( - fx.bcx.ins().iconst(types::I8, i64::from(val)), - fx.layout_of(fx.tcx.types.bool), - ); - lval.write_cvalue(fx, val); - } Rvalue::Aggregate(ref kind, ref operands) if matches!(**kind, AggregateKind::RawPtr(..)) => { @@ -913,7 +902,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: lval.write_cvalue_transmute(fx, operand); } Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), - Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), } } StatementKind::StorageLive(_) @@ -1050,6 +1038,11 @@ pub(crate) fn codegen_operand<'tcx>( cplace.to_cvalue(fx) } Operand::Constant(const_) => crate::constant::codegen_constant_operand(fx, const_), + Operand::RuntimeChecks(checks) => { + let val = checks.value(fx.tcx.sess); + let layout = fx.layout_of(fx.tcx.types.bool); + return CValue::const_val(fx, layout, val.into()); + } } } diff --git a/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs b/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs index 86bff32dc623..d8977657e305 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs @@ -208,7 +208,7 @@ pub(crate) fn codegen_cast( let ret_ty = if to_ty.bits() < 32 { types::I32 } else { to_ty }; let name = format!( "__fix{sign}tf{size}i", - sign = if from_signed { "" } else { "un" }, + sign = if to_signed { "" } else { "uns" }, size = match ret_ty { types::I32 => 's', types::I64 => 'd', diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 38676eaac3d5..b11f42408f58 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -377,26 +377,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { size.is_multiple_of(align), "size must be a multiple of alignment (size={size}, align={align})" ); + debug_assert!(align.is_power_of_two(), "alignment must be a power of two (align={align})"); let abi_align = if self.tcx.sess.target.arch == Arch::S390x { 8 } else { 16 }; + // Cranelift can only guarantee alignment up to the ABI alignment provided by the target. + // If the requested alignment is less than the abi_align it can be used directly. if align <= abi_align { let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, - // FIXME Don't force the size to a multiple of bytes once Cranelift gets - // a way to specify stack slot alignment. - size: size.div_ceil(abi_align) * abi_align, - align_shift: 4, + size, + // The maximum value of ilog2 is 31 which will always fit in a u8. + align_shift: align.ilog2().try_into().unwrap(), + key: None, }); Pointer::stack_slot(stack_slot) } else { - // Alignment is too big to handle using the above hack. Dynamically realign a stack slot + // Alignment is larger than the ABI alignment guaranteed. Dynamically realign a stack slot // instead. This wastes some space for the realignment. let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, - // FIXME Don't force the size to a multiple of bytes once Cranelift gets - // a way to specify stack slot alignment. - size: (size + align) / abi_align * abi_align, - align_shift: 4, + size: size + align, + align_shift: abi_align.ilog2().try_into().unwrap(), + key: None, }); let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0); let misalign_offset = self.bcx.ins().band_imm(base_ptr, i64::from(align - 1)); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 2b65b8290681..ff8e6744bd32 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -540,6 +540,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( operand: &Operand<'tcx>, ) -> Option { match operand { + Operand::RuntimeChecks(checks) => Some(checks.value(fx.tcx.sess).into()), Operand::Constant(const_) => eval_mir_constant(fx, const_).0.try_to_scalar_int(), // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored // inside a temporary before being passed to the intrinsic requiring the const argument. diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs index 6fe22f5c6dd9..12b0d5ec4963 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs @@ -5,8 +5,11 @@ use std::path::{Component, Path}; use cranelift_codegen::MachSrcLoc; use cranelift_codegen::binemit::CodeOffset; -use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; -use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene}; +use gimli::write::{FileId, FileInfo, LineProgram, LineString, LineStringTable}; +use rustc_span::{ + FileName, Pos, RemapPathScopeComponents, SourceFile, SourceFileAndLine, + SourceFileHashAlgorithm, hygiene, +}; use crate::debuginfo::FunctionDebugContext; use crate::debuginfo::emit::address_for_func; @@ -95,7 +98,7 @@ impl DebugContext { match &source_file.name { FileName::Real(path) => { let (dir_path, file_name) = - split_path_dir_and_file(path.to_path(self.filename_display_preference)); + split_path_dir_and_file(path.path(RemapPathScopeComponents::DEBUGINFO)); let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); let file_name = osstr_as_utf8_bytes(file_name); @@ -117,8 +120,7 @@ impl DebugContext { } filename => { // For anonymous sources, create an empty directory instead of using the default - let empty_dir = LineString::new(b"", line_program.encoding(), line_strings); - let dir_id = line_program.add_directory(empty_dir); + let dir_id = line_program.default_directory(); let dummy_file_name = LineString::new( filename.prefer_remapped_unconditionally().to_string().into_bytes(), @@ -176,10 +178,6 @@ impl FunctionDebugContext { assert_ne!(func_end, 0); - let entry = debug_context.dwarf.unit.get_mut(self.entry_id); - entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); - entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end))); - func_end } } diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 494002f525c8..756f86a7d011 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -21,7 +21,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; use rustc_session::config::DebugInfo; -use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId}; +use rustc_span::{RemapPathScopeComponents, SourceFileHash, StableSourceFileId}; use rustc_target::callconv::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; @@ -42,14 +42,13 @@ pub(crate) struct DebugContext { created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>, stack_pointer_register: Register, namespace_map: DefIdMap, - array_size_type: UnitEntryId, + array_size_type: Option, - filename_display_preference: FileNameDisplayPreference, embed_source: bool, } pub(crate) struct FunctionDebugContext { - entry_id: UnitEntryId, + entry_id: Option, function_source_loc: (FileId, u64, u64), source_loc_set: IndexSet<(FileId, u64, u64)>, } @@ -102,18 +101,18 @@ impl DebugContext { let mut dwarf = DwarfUnit::new(encoding); - use rustc_session::config::RemapPathScopeComponents; - - let filename_display_preference = - tcx.sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO); - let producer = producer(tcx.sess); - let comp_dir = - tcx.sess.opts.working_dir.to_string_lossy(filename_display_preference).to_string(); + let comp_dir = tcx + .sess + .source_map() + .working_dir() + .path(RemapPathScopeComponents::DEBUGINFO) + .to_string_lossy(); let (name, file_info) = match tcx.sess.local_crate_source_file() { Some(path) => { - let name = path.to_string_lossy(filename_display_preference).to_string(); + let name = + path.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy().into_owned(); (name, None) } None => (tcx.crate_name(LOCAL_CRATE).to_string(), None), @@ -137,7 +136,7 @@ impl DebugContext { { let name = dwarf.strings.add(format!("{name}/@/{cgu_name}")); - let comp_dir = dwarf.strings.add(comp_dir); + let comp_dir = dwarf.strings.add(&*comp_dir); let root = dwarf.unit.root(); let root = dwarf.unit.get_mut(root); @@ -154,18 +153,23 @@ impl DebugContext { root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } - let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); - let array_size_type_entry = dwarf.unit.get_mut(array_size_type); - array_size_type_entry.set( - gimli::DW_AT_name, - AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), - ); - array_size_type_entry - .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); - array_size_type_entry.set( - gimli::DW_AT_byte_size, - AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), - ); + let array_size_type = if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + None + } else { + let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); + let array_size_type_entry = dwarf.unit.get_mut(array_size_type); + array_size_type_entry.set( + gimli::DW_AT_name, + AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), + ); + array_size_type_entry + .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); + array_size_type_entry.set( + gimli::DW_AT_byte_size, + AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), + ); + Some(array_size_type) + }; Some(DebugContext { endian, @@ -175,7 +179,6 @@ impl DebugContext { stack_pointer_register, namespace_map: DefIdMap::default(), array_size_type, - filename_display_preference, embed_source, }) } @@ -217,6 +220,14 @@ impl DebugContext { ) -> FunctionDebugContext { let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span); + if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + return FunctionDebugContext { + entry_id: None, + function_source_loc: (file_id, line, column), + source_loc_set: IndexSet::new(), + }; + } + let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); let mut name = String::new(); @@ -231,7 +242,7 @@ impl DebugContext { let generics = tcx.generics_of(enclosing_fn_def_id); let args = instance.args.truncate_to(tcx, generics); - type_names::push_generic_params( + type_names::push_generic_args( tcx, tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), args), &mut name, @@ -274,7 +285,7 @@ impl DebugContext { } FunctionDebugContext { - entry_id, + entry_id: Some(entry_id), function_source_loc: (file_id, line, column), source_loc_set: IndexSet::new(), } @@ -288,6 +299,10 @@ impl DebugContext { def_id: DefId, data_id: DataId, ) { + if tcx.sess.opts.debuginfo == DebugInfo::LineTablesOnly { + return; + } + let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; if nested { return; @@ -353,10 +368,12 @@ impl FunctionDebugContext { .0 .push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) }); - let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id); - // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. - func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); - // Using Udata for DW_AT_high_pc requires at least DWARF4 - func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); + if let Some(entry_id) = self.entry_id { + let entry = debug_context.dwarf.unit.get_mut(entry_id); + // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. + entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); + // Using Udata for DW_AT_high_pc requires at least DWARF4 + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); + } } } diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs index a292429cdfad..18a0632a0939 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs @@ -109,7 +109,8 @@ impl DebugContext { let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type); let subrange_entry = self.dwarf.unit.get_mut(subrange_id); - subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type)); + subrange_entry + .set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type.unwrap())); subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0)); subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(len)); diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs index ecaf88a26259..33ffe4cc4e9c 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs @@ -130,11 +130,9 @@ impl UnwindContext { return; } - let unwind_info = if let Some(unwind_info) = + let Some(unwind_info) = context.compiled_code().unwrap().create_unwind_info(module.isa()).unwrap() - { - unwind_info - } else { + else { return; }; diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 760e23f2171b..fc5c634d9570 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -2,29 +2,26 @@ //! standalone executable. use std::env; -use std::fs::{self, File}; +use std::fs::File; use std::io::BufWriter; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::Arc; use std::thread::JoinHandle; use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; -use rustc_codegen_ssa::back::link::ensure_removed; +use rustc_codegen_ssa::back::write::{CompiledModules, produce_final_output_artifacts}; use rustc_codegen_ssa::base::determine_cgu_reuse; -use rustc_codegen_ssa::{ - CodegenResults, CompiledModule, CrateInfo, ModuleKind, errors as ssa_errors, -}; +use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; use rustc_hir::attrs::Linkage as RLinkage; -use rustc_metadata::fs::copy_to_stdout; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{CodegenUnit, MonoItem, MonoItemData, Visibility}; use rustc_session::Session; -use rustc_session::config::{OutFileName, OutputFilenames, OutputType}; +use rustc_session::config::{OutputFilenames, OutputType}; use crate::base::CodegenedFunction; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; @@ -125,203 +122,22 @@ impl OngoingCodegen { sess.dcx().abort_if_errors(); - let codegen_results = CodegenResults { - modules, - allocator_module: self.allocator_module, - crate_info: self.crate_info, - }; + let compiled_modules = CompiledModules { modules, allocator_module: self.allocator_module }; - produce_final_output_artifacts(sess, &codegen_results, outputs); + produce_final_output_artifacts(sess, &compiled_modules, outputs); - (codegen_results, work_products) + ( + CodegenResults { + crate_info: self.crate_info, + + modules: compiled_modules.modules, + allocator_module: compiled_modules.allocator_module, + }, + work_products, + ) } } -// Adapted from https://github.com/rust-lang/rust/blob/73476d49904751f8d90ce904e16dfbc278083d2c/compiler/rustc_codegen_ssa/src/back/write.rs#L547C1-L706C2 -fn produce_final_output_artifacts( - sess: &Session, - codegen_results: &CodegenResults, - crate_output: &OutputFilenames, -) { - let user_wants_bitcode = false; - let mut user_wants_objects = false; - - // Produce final compile outputs. - let copy_gracefully = |from: &Path, to: &OutFileName| match to { - OutFileName::Stdout => { - if let Err(e) = copy_to_stdout(from) { - sess.dcx().emit_err(ssa_errors::CopyPath::new(from, to.as_path(), e)); - } - } - OutFileName::Real(path) => { - if let Err(e) = fs::copy(from, path) { - sess.dcx().emit_err(ssa_errors::CopyPath::new(from, path, e)); - } - } - }; - - let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { - if codegen_results.modules.len() == 1 { - // 1) Only one codegen unit. In this case it's no difficulty - // to copy `foo.0.x` to `foo.x`. - let path = crate_output.temp_path_for_cgu( - output_type, - &codegen_results.modules[0].name, - sess.invocation_temp.as_deref(), - ); - let output = crate_output.path(output_type); - if !output_type.is_text_output() && output.is_tty() { - sess.dcx() - .emit_err(ssa_errors::BinaryOutputToTty { shorthand: output_type.shorthand() }); - } else { - copy_gracefully(&path, &output); - } - if !sess.opts.cg.save_temps && !keep_numbered { - // The user just wants `foo.x`, not `foo.#module-name#.x`. - ensure_removed(sess.dcx(), &path); - } - } else { - if crate_output.outputs.contains_explicit_name(&output_type) { - // 2) Multiple codegen units, with `--emit foo=some_name`. We have - // no good solution for this case, so warn the user. - sess.dcx() - .emit_warn(ssa_errors::IgnoringEmitPath { extension: output_type.extension() }); - } else if crate_output.single_output_file.is_some() { - // 3) Multiple codegen units, with `-o some_name`. We have - // no good solution for this case, so warn the user. - sess.dcx() - .emit_warn(ssa_errors::IgnoringOutput { extension: output_type.extension() }); - } else { - // 4) Multiple codegen units, but no explicit name. We - // just leave the `foo.0.x` files in place. - // (We don't have to do any work in this case.) - } - } - }; - - // Flag to indicate whether the user explicitly requested bitcode. - // Otherwise, we produced it only as a temporary output, and will need - // to get rid of it. - for output_type in crate_output.outputs.keys() { - match *output_type { - OutputType::Bitcode | OutputType::ThinLinkBitcode => { - // Cranelift doesn't have bitcode - // user_wants_bitcode = true; - // // Copy to .bc, but always keep the .0.bc. There is a later - // // check to figure out if we should delete .0.bc files, or keep - // // them for making an rlib. - // copy_if_one_unit(OutputType::Bitcode, true); - } - OutputType::LlvmAssembly => { - // Cranelift IR text already emitted during codegen - // copy_if_one_unit(OutputType::LlvmAssembly, false); - } - OutputType::Assembly => { - // Currently no support for emitting raw assembly files - // copy_if_one_unit(OutputType::Assembly, false); - } - OutputType::Object => { - user_wants_objects = true; - copy_if_one_unit(OutputType::Object, true); - } - OutputType::Mir | OutputType::Metadata | OutputType::Exe | OutputType::DepInfo => {} - } - } - - // Clean up unwanted temporary files. - - // We create the following files by default: - // - #crate#.#module-name#.bc - // - #crate#.#module-name#.o - // - #crate#.crate.metadata.bc - // - #crate#.crate.metadata.o - // - #crate#.o (linked from crate.##.o) - // - #crate#.bc (copied from crate.##.bc) - // We may create additional files if requested by the user (through - // `-C save-temps` or `--emit=` flags). - - if !sess.opts.cg.save_temps { - // Remove the temporary .#module-name#.o objects. If the user didn't - // explicitly request bitcode (with --emit=bc), and the bitcode is not - // needed for building an rlib, then we must remove .#module-name#.bc as - // well. - - // Specific rules for keeping .#module-name#.bc: - // - If the user requested bitcode (`user_wants_bitcode`), and - // codegen_units > 1, then keep it. - // - If the user requested bitcode but codegen_units == 1, then we - // can toss .#module-name#.bc because we copied it to .bc earlier. - // - If we're not building an rlib and the user didn't request - // bitcode, then delete .#module-name#.bc. - // If you change how this works, also update back::link::link_rlib, - // where .#module-name#.bc files are (maybe) deleted after making an - // rlib. - let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe); - - let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units().as_usize() > 1; - - let keep_numbered_objects = - needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1); - - for module in codegen_results.modules.iter() { - if let Some(ref path) = module.object { - if !keep_numbered_objects { - ensure_removed(sess.dcx(), path); - } - } - - if let Some(ref path) = module.dwarf_object { - if !keep_numbered_objects { - ensure_removed(sess.dcx(), path); - } - } - - if let Some(ref path) = module.bytecode { - if !keep_numbered_bitcode { - ensure_removed(sess.dcx(), path); - } - } - } - - if !user_wants_bitcode { - if let Some(ref allocator_module) = codegen_results.allocator_module { - if let Some(ref path) = allocator_module.bytecode { - ensure_removed(sess.dcx(), path); - } - } - } - } - - if sess.opts.json_artifact_notifications { - if codegen_results.modules.len() == 1 { - codegen_results.modules[0].for_each_output(|_path, ty| { - if sess.opts.output_types.contains_key(&ty) { - let descr = ty.shorthand(); - // for single cgu file is renamed to drop cgu specific suffix - // so we regenerate it the same way - let path = crate_output.path(ty); - sess.dcx().emit_artifact_notification(path.as_path(), descr); - } - }); - } else { - for module in &codegen_results.modules { - module.for_each_output(|path, ty| { - if sess.opts.output_types.contains_key(&ty) { - let descr = ty.shorthand(); - sess.dcx().emit_artifact_notification(path, descr); - } - }); - } - } - } - - // We leave the following files around by default: - // - #crate#.o - // - #crate#.crate.metadata.o - // - #crate#.bc - // These are used in linking steps and will be cleaned up afterward. -} - fn make_module(sess: &Session, name: String) -> UnwindModule { let isa = crate::build_isa(sess, false); diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 9dba46363936..3a8ca25a5fc0 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -190,7 +190,7 @@ fn dep_symbol_lookup_fn( diag.emit(); } Linkage::Dynamic => { - dylib_paths.push(src.dylib.as_ref().unwrap().0.clone()); + dylib_paths.push(src.dylib.as_ref().unwrap().clone()); } } } diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 8d8cdb14dbc6..1daf428acf76 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -106,6 +106,7 @@ fn codegen_global_asm_inner<'tcx>( match *piece { InlineAsmTemplatePiece::String(ref s) => global_asm.push_str(s), InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => { + use rustc_codegen_ssa::back::symbol_export::escape_symbol_name; match operands[operand_idx] { GlobalAsmOperandRef::Const { ref string } => { global_asm.push_str(string); @@ -121,7 +122,7 @@ fn codegen_global_asm_inner<'tcx>( let symbol = tcx.symbol_name(instance); // FIXME handle the case where the function was made private to the // current codegen unit - global_asm.push_str(symbol.name); + global_asm.push_str(&escape_symbol_name(tcx, symbol.name, span)); } GlobalAsmOperandRef::SymStatic { def_id } => { if cfg!(not(feature = "inline_asm_sym")) { @@ -133,7 +134,7 @@ fn codegen_global_asm_inner<'tcx>( let instance = Instance::mono(tcx, def_id); let symbol = tcx.symbol_name(instance); - global_asm.push_str(symbol.name); + global_asm.push_str(&escape_symbol_name(tcx, symbol.name, span)); } } } @@ -233,7 +234,7 @@ pub(crate) fn compile_global_asm( #![allow(internal_features)] #![no_core] #[rustc_builtin_macro] - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro global_asm() { /* compiler built-in */ } global_asm!(r###" "####, diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 08cabe9d695c..ac0da06cbb8e 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -857,19 +857,9 @@ fn call_inline_asm<'tcx>( fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { match ty.kind() { - // Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151 + // Adapted from https://github.com/rust-lang/rust/blob/df44a57fd29fca899ce473f85ed64efd0708dd7c/compiler/rustc_hir_typeck/src/inline_asm.rs#L180-L183 ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { - let fields = &adt.non_enum_variant().fields; - let ty = fields[FieldIdx::ONE].ty(fx.tcx, args); - let ty::Adt(ty, args) = ty.kind() else { - unreachable!("expected first field of `MaybeUninit` to be an ADT") - }; - assert!( - ty.is_manually_drop(), - "expected first field of `MaybeUninit` to be `ManuallyDrop`" - ); - let fields = &ty.non_enum_variant().fields; - let ty = fields[FieldIdx::ZERO].ty(fx.tcx, args); + let ty = args.type_at(0); fx.clif_type(ty) } _ => fx.clif_type(ty), diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 37fbe4be1b0f..61f48fa97743 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -1313,6 +1313,35 @@ pub(super) fn codegen_x86_llvm_intrinsic_call<'tcx>( ret.write_cvalue_transmute(fx, res); } + "llvm.x86.vcvtps2ph.128" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cvtps_ph + intrinsic_args!(fx, args => (a, _imm8); intrinsic); + let a = a.load_scalar(fx); + + let imm8 = + if let Some(imm8) = crate::constant::mir_operand_get_const_val(fx, &args[1].node) { + imm8 + } else { + fx.tcx + .dcx() + .span_fatal(span, "Index argument for `_mm_cvtps_ph` is not a constant"); + }; + + let imm8 = imm8.to_u32(); + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String(format!("vcvtps2ph xmm0, xmm0, {imm8}").into())], + &[CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)), + _late: true, + in_value: a, + out_place: Some(ret), + }], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + _ => { fx.tcx .dcx() diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index a78c6e0a4e7a..ab9a11305baa 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -1506,7 +1506,7 @@ fn codegen_regular_intrinsic_call<'tcx>( } // FIXME implement variadics in cranelift - sym::va_copy | sym::va_arg | sym::va_end => { + sym::va_arg | sym::va_end => { fx.tcx.dcx().span_fatal( source_info.span, "Defining variadic functions is not yet supported by Cranelift", diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 0bce31beb8b8..200cedf0f6ae 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -130,7 +130,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; } - let idx = generic_args[2].expect_const().to_value().valtree.unwrap_branch(); + let idx = generic_args[2].expect_const().to_branch(); assert_eq!(x.layout(), y.layout()); let layout = x.layout(); @@ -143,7 +143,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let total_len = lane_count * 2; - let indexes = idx.iter().map(|idx| idx.unwrap_leaf().to_u32()).collect::>(); + let indexes = idx.iter().map(|idx| idx.to_leaf().to_u32()).collect::>(); for &idx in &indexes { assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); @@ -348,6 +348,31 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( ret.write_cvalue(fx, ret_lane); } + sym::simd_splat => { + intrinsic_args!(fx, args => (value); intrinsic); + + if !ret.layout().ty.is_simd() { + report_simd_type_validation_error(fx, intrinsic, span, ret.layout().ty); + return; + } + let (lane_count, lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx); + + if value.layout().ty != lane_ty { + fx.tcx.dcx().span_fatal( + span, + format!( + "[simd_splat] expected element type {lane_ty:?}, got {got:?}", + got = value.layout().ty + ), + ); + } + + for i in 0..lane_count { + let ret_lane = ret.place_lane(fx, i.into()); + ret_lane.write_cvalue(fx, value); + } + } + sym::simd_neg | sym::simd_bswap | sym::simd_bitreverse @@ -961,9 +986,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ptr_val = ptr.load_scalar(fx); - let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); let memflags = match alignment { SimdAlign::Unaligned => MemFlags::new().with_notrap(), @@ -1006,15 +1030,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap(); let ret_lane_layout = fx.layout_of(ret_lane_ty); - let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); - - let memflags = match alignment { - SimdAlign::Unaligned => MemFlags::new().with_notrap(), - _ => MemFlags::trusted(), - }; - for lane_idx in 0..ptr_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let ptr_lane = ptr.value_lane(fx, lane_idx).load_scalar(fx); @@ -1030,7 +1045,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.seal_block(if_disabled); fx.bcx.switch_to_block(if_enabled); - let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_lane, 0); + let res = fx.bcx.ins().load(lane_clif_ty, MemFlags::trusted(), ptr_lane, 0); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); @@ -1059,9 +1074,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let ret_lane_layout = fx.layout_of(ret_lane_ty); let ptr_val = ptr.load_scalar(fx); - let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); let memflags = match alignment { SimdAlign::Unaligned => MemFlags::new().with_notrap(), diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 5fdecd014ac0..7bab07def63d 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -1,11 +1,9 @@ // tidy-alphabetical-start -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::untranslatable_diagnostic)] // Note: please avoid adding other feature gates where possible #![feature(rustc_private)] // Only used to define intrinsics in `compiler_builtins.rs`. -#![feature(f16)] -#![feature(f128)] +#![cfg_attr(feature = "jit", feature(f16))] +#![cfg_attr(feature = "jit", feature(f128))] // Note: please avoid adding other feature gates where possible #![warn(rust_2018_idioms)] #![warn(unreachable_pub)] @@ -25,7 +23,6 @@ extern crate rustc_hir; extern crate rustc_incremental; extern crate rustc_index; extern crate rustc_log; -extern crate rustc_metadata; extern crate rustc_session; extern crate rustc_span; extern crate rustc_symbol_mangling; @@ -127,11 +124,6 @@ pub struct CraneliftCodegenBackend { } impl CodegenBackend for CraneliftCodegenBackend { - fn locale_resource(&self) -> &'static str { - // FIXME(rust-lang/rust#100717) - cranelift codegen backend is not yet translated - "" - } - fn name(&self) -> &'static str { "cranelift" } @@ -188,6 +180,10 @@ impl CodegenBackend for CraneliftCodegenBackend { && sess.target.env == Env::Gnu && sess.target.abi != Abi::Llvm); + // FIXME(f128): f128 math operations need f128 math symbols, which currently aren't always + // filled in by compiler-builtins. The only libc that provides these currently is glibc. + let has_reliable_f128_math = has_reliable_f16_f128 && sess.target.env == Env::Gnu; + TargetConfig { target_features, unstable_target_features, @@ -196,7 +192,7 @@ impl CodegenBackend for CraneliftCodegenBackend { has_reliable_f16: has_reliable_f16_f128, has_reliable_f16_math: has_reliable_f16_f128, has_reliable_f128: has_reliable_f16_f128, - has_reliable_f128_math: has_reliable_f16_f128, + has_reliable_f128_math, } } diff --git a/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs index c93fe9352103..f38c1f96e6ed 100644 --- a/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs +++ b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs @@ -29,11 +29,7 @@ pub(crate) fn maybe_known_branch_taken( arg: Value, test_zero: bool, ) -> Option { - let arg_inst = if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { - arg_inst - } else { - return None; - }; + let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) else { return None }; match bcx.func.dfg.insts[arg_inst] { InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => { diff --git a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs index 2878fa7aa298..65779b38ad1c 100644 --- a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs +++ b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs @@ -10,7 +10,7 @@ //! function u0:22(i64) -> i8, i8 system_v { //! ; symbol _ZN97_$LT$example..IsNotEmpty$u20$as$u20$mini_core..FnOnce$LT$$LP$$RF$$RF$$u5b$u16$u5d$$C$$RP$$GT$$GT$9call_once17hd361e9f5c3d1c4deE //! ; instance Instance { def: Item(DefId(0:42 ~ example[3895]::{impl#0}::call_once)), args: ['{erased}, '{erased}] } -//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: Memory { sized: true }, fields: Arbitrary { offsets: [], memory_index: [] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 12266848898570219025 } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } +//! ; abi FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: IsNotEmpty, layout: Layout { size: Size(0 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: Memory { sized: true }, fields: Arbitrary { offsets: [], in_memory_order: [] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 12266848898570219025 } }, mode: Ignore }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], in_memory_order: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } //! //! ; kind loc.idx param pass mode ty //! ; ssa _0 (u8, u8) 2b 1 var=(0, 1) @@ -41,7 +41,7 @@ //! ; //! ; _0 = >::call_mut(move _3, copy _2) //! v2 = stack_load.i64 ss0 -//! ; abi: FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: &mut IsNotEmpty, layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(1 bytes)) }) }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], memory_index: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } +//! ; abi: FnAbi { args: [ArgAbi { layout: TyAndLayout { ty: &mut IsNotEmpty, layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(1 bytes)) }) }, ArgAbi { layout: TyAndLayout { ty: &&[u16], layout: Layout { size: Size(8 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, backend_repr: Scalar(Initialized { value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), fields: Primitive, largest_niche: Some(Niche { offset: Size(0 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: 281492156579847 } }, mode: Direct(ArgAttributes { regular: NonNull | NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: Some(Align(8 bytes)) }) }], ret: ArgAbi { layout: TyAndLayout { ty: (u8, u8), layout: Layout { size: Size(2 bytes), align: AbiAndPrefAlign { abi: Align(1 bytes), pref: Align(8 bytes) }, backend_repr: ScalarPair(Initialized { value: Int(I8, false), valid_range: 0..=255 }, Initialized { value: Int(I8, false), valid_range: 0..=255 }), fields: Arbitrary { offsets: [Size(0 bytes), Size(1 bytes)], in_memory_order: [0, 1] }, largest_niche: None, uninhabited: false, variants: Single { index: 0 }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: 71776127651151873 } }, mode: Pair(ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }, ArgAttributes { regular: NoUndef, arg_ext: None, pointee_size: Size(0 bytes), pointee_align: None }) }, c_variadic: false, fixed_count: 1, conv: Rust, can_unwind: false } //! v3, v4 = call fn0(v1, v2) ; v1 = 1 //! v5 -> v3 //! v6 -> v4 diff --git a/compiler/rustc_codegen_cranelift/triagebot.toml b/compiler/rustc_codegen_cranelift/triagebot.toml index 13da0a87def3..eb0c7b011f60 100644 --- a/compiler/rustc_codegen_cranelift/triagebot.toml +++ b/compiler/rustc_codegen_cranelift/triagebot.toml @@ -2,6 +2,3 @@ # Prevents un-canonicalized issue links (to avoid wrong issues being linked in r-l/rust) [issue-links] - -# Prevents mentions in commits to avoid users being spammed -[no-mentions] diff --git a/compiler/rustc_codegen_gcc/.cspell.json b/compiler/rustc_codegen_gcc/.cspell.json index 388ccce2b091..556432d69a41 100644 --- a/compiler/rustc_codegen_gcc/.cspell.json +++ b/compiler/rustc_codegen_gcc/.cspell.json @@ -18,6 +18,7 @@ ], "ignorePaths": [ "src/intrinsic/archs.rs", + "src/intrinsic/old_archs.rs", "src/intrinsic/llvm.rs" ], "ignoreRegExpList": [ diff --git a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml index 5c8e7d628169..840c09409bba 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml @@ -113,6 +113,10 @@ jobs: git config --global user.name "User" ./y.sh prepare + - name: Add more failing tests for GCC without 128-bit integers support + if: ${{ matrix.libgccjit_version.gcc == 'gcc-15-without-int128.deb' }} + run: cat tests/failing-ui-tests-without-128bit-integers.txt >> tests/failing-ui-tests.txt + - name: Run tests run: | ./y.sh test --release --clean --build-sysroot ${{ matrix.commands }} diff --git a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml index e49c62d6c931..11bc88e67d2d 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml @@ -83,7 +83,7 @@ jobs: run: | ./y.sh prepare --only-libcore --cross ./y.sh build --sysroot --target-triple m68k-unknown-linux-gnu --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json - CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ./y.sh cargo build --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json + CG_RUSTFLAGS="-Clinker=m68k-unknown-linux-gnu-gcc" ./y.sh cargo build -Zjson-target-spec --manifest-path=./tests/hello-world/Cargo.toml --target ${{ github.workspace }}/target_specs/m68k-unknown-linux-gnu.json ./y.sh clean all - name: Build diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index dea1207b05da..a283ea4cb0b0 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -56,18 +56,18 @@ dependencies = [ [[package]] name = "gccjit" -version = "3.1.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff80f4d6d0749eab3a69122210b3a1fdd52edb6162781aadd7c4842e26983683" +checksum = "26b73d18b642ce16378af78f89664841d7eeafa113682ff5d14573424eb0232a" dependencies = [ "gccjit_sys", ] [[package]] name = "gccjit_sys" -version = "1.1.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f81d901767ddba371a619fa9bba657066a4d3c5607ee69bbb557c1c5ba9bf85" +checksum = "ee689456c013616942d5aef9a84d613cefcc3b335340d036f3650fc1a7459e15" dependencies = [ "libc", ] diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml index 18847f50d46a..29af6a1fc434 100644 --- a/compiler/rustc_codegen_gcc/Cargo.toml +++ b/compiler/rustc_codegen_gcc/Cargo.toml @@ -24,7 +24,7 @@ default = ["master"] [dependencies] object = { version = "0.37.0", default-features = false, features = ["std", "read"] } tempfile = "3.20" -gccjit = { version = "3.1.1", features = ["dlopen"] } +gccjit = { version = "3.3.0", features = ["dlopen"] } #gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] } # Local copy. diff --git a/compiler/rustc_codegen_gcc/Readme.md b/compiler/rustc_codegen_gcc/Readme.md index cd6aeae4b42e..ce5ee1e4adee 100644 --- a/compiler/rustc_codegen_gcc/Readme.md +++ b/compiler/rustc_codegen_gcc/Readme.md @@ -45,12 +45,12 @@ The default configuration (see below in the [Quick start](#quick-start) section) ./y.sh test --release ``` -If don't need to test GCC patches you wrote in our GCC fork, then the default configuration should +If you don't need to test GCC patches you wrote in our GCC fork, then the default configuration should be all you need. You can update the `rustc_codegen_gcc` without worrying about GCC. ### Building with your own GCC version -If you wrote a patch for GCC and want to test it without this backend, you will need +If you wrote a patch for GCC and want to test it with this backend, you will need to do a few more things. To build it (most of these instructions come from [here](https://gcc.gnu.org/onlinedocs/jit/internals/index.html), so don't hesitate to take a look there if you encounter an issue): @@ -127,7 +127,7 @@ You have to run these commands, in the corresponding order: $ ./y.sh prepare $ ./y.sh build --sysroot ``` -To check if all is working correctly, run: +To check if all is working correctly, run: ```bash $ ./y.sh cargo build --manifest-path tests/hello-world/Cargo.toml diff --git a/compiler/rustc_codegen_gcc/_typos.toml b/compiler/rustc_codegen_gcc/_typos.toml index 4a6a506a981a..c4918b114621 100644 --- a/compiler/rustc_codegen_gcc/_typos.toml +++ b/compiler/rustc_codegen_gcc/_typos.toml @@ -6,4 +6,4 @@ seh = "seh" typ = "typ" [files] -extend-exclude = ["src/intrinsic/archs.rs"] +extend-exclude = ["src/intrinsic/archs.rs", "src/intrinsic/old_archs.rs"] diff --git a/compiler/rustc_codegen_gcc/build_system/src/build.rs b/compiler/rustc_codegen_gcc/build_system/src/build.rs index 27476465d740..839c762fed74 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/build.rs +++ b/compiler/rustc_codegen_gcc/build_system/src/build.rs @@ -111,14 +111,20 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu // Symlink libgccjit.so to sysroot. let lib_path = start_dir.join("sysroot").join("lib"); + let rustlib_target_path = lib_path + .join("rustlib") + .join(&config.host_triple) + .join("codegen-backends") + .join("lib") + .join(&config.target_triple); let libgccjit_path = PathBuf::from(config.gcc_path.as_ref().expect("libgccjit should be set by this point")) .join("libgccjit.so"); - let libgccjit_in_sysroot_path = lib_path.join("libgccjit.so"); + let libgccjit_in_sysroot_path = rustlib_target_path.join("libgccjit.so"); // First remove the file to be able to create the symlink even when the file already exists. let _ = fs::remove_file(&libgccjit_in_sysroot_path); - create_dir(&lib_path)?; - symlink(libgccjit_path, libgccjit_in_sysroot_path) + create_dir(&rustlib_target_path)?; + symlink(libgccjit_path, &libgccjit_in_sysroot_path) .map_err(|error| format!("Cannot create symlink for libgccjit.so: {}", error))?; let library_dir = start_dir.join("sysroot_src").join("library"); @@ -135,6 +141,10 @@ pub fn build_sysroot(env: &HashMap, config: &ConfigInfo) -> Resu } let mut args: Vec<&dyn AsRef> = vec![&"cargo", &"build", &"--target", &config.target]; + if config.target.ends_with(".json") { + args.push(&"-Zjson-target-spec"); + } + for feature in &config.features { args.push(&"--features"); args.push(feature); diff --git a/compiler/rustc_codegen_gcc/build_system/src/test.rs b/compiler/rustc_codegen_gcc/build_system/src/test.rs index ca2a2a7dc2de..096f8c98376c 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/test.rs +++ b/compiler/rustc_codegen_gcc/build_system/src/test.rs @@ -679,10 +679,10 @@ fn test_projects(env: &Env, args: &TestArg) -> Result<(), String> { create_dir(projects_path)?; let nb_parts = args.nb_parts.unwrap_or(0); - if nb_parts > 0 { + if let Some(count) = projects.len().checked_div(nb_parts) { // We increment the number of tests by one because if this is an odd number, we would skip // one test. - let count = projects.len() / nb_parts + 1; + let count = count + 1; let current_part = args.current_part.unwrap(); let start = current_part * count; // We remove the projects we don't want to test. diff --git a/compiler/rustc_codegen_gcc/doc/debugging.md b/compiler/rustc_codegen_gcc/doc/debugging.md index 6ff4edf8877c..853852271708 100644 --- a/compiler/rustc_codegen_gcc/doc/debugging.md +++ b/compiler/rustc_codegen_gcc/doc/debugging.md @@ -2,9 +2,9 @@ ## How to debug GCC LTO -Run do the command with `-v -save-temps` and then extract the `lto1` line from the output and run that under the debugger. +Run the command with `-v -save-temps` and then extract the `lto1` line from the output and run that under the debugger. -## How to debug stdarch tests that cannot be ran locally +## How to debug stdarch tests that cannot be run locally First, run the tests normally: diff --git a/compiler/rustc_codegen_gcc/doc/errors.md b/compiler/rustc_codegen_gcc/doc/errors.md index 5727b0ff7c86..81621d49b4f1 100644 --- a/compiler/rustc_codegen_gcc/doc/errors.md +++ b/compiler/rustc_codegen_gcc/doc/errors.md @@ -15,7 +15,7 @@ That can be caused by the fact that you try to compile with `lto = "fat"`, but y ### ld: cannot find crtbegin.o -When compiling an executable with libgccijt, if setting the `*LIBRARY_PATH` variables to the install directory, you will get the following errors: +When compiling an executable with libgccjit, if setting the `*LIBRARY_PATH` variables to the install directory, you will get the following errors: ``` ld: cannot find crtbegin.o: No such file or directory diff --git a/compiler/rustc_codegen_gcc/doc/gimple.md b/compiler/rustc_codegen_gcc/doc/gimple.md index 145c4eda3c1c..bd298d65ed26 100644 --- a/compiler/rustc_codegen_gcc/doc/gimple.md +++ b/compiler/rustc_codegen_gcc/doc/gimple.md @@ -3,7 +3,7 @@ You can see the full documentation about what GIMPLE is [here](https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html). In this document we will explain how to generate it. First, we'll copy the content from `gcc/gcc/testsuite/jit.dg/test-const-attribute.c` into a -file named `local.c` and remove the content we're not interested into: +file named `local.c` and remove the content we're not interested in: ```diff - /* { dg-do compile { target x86_64-*-* } } */ diff --git a/compiler/rustc_codegen_gcc/doc/tips.md b/compiler/rustc_codegen_gcc/doc/tips.md index 38bc98c02d92..ff92566d4a1a 100644 --- a/compiler/rustc_codegen_gcc/doc/tips.md +++ b/compiler/rustc_codegen_gcc/doc/tips.md @@ -53,7 +53,7 @@ If you wish to build a custom sysroot, pass the path of your sysroot source to ` ### How to use [mem-trace](https://github.com/antoyo/mem-trace) -`rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't a chance to intercept the calls to `malloc`. +`rustc` needs to be built without `jemalloc` so that `mem-trace` can overload `malloc` since `jemalloc` is linked statically, so a `LD_PRELOAD`-ed library won't have a chance to intercept the calls to `malloc`. ### How to generate GIMPLE diff --git a/compiler/rustc_codegen_gcc/example/alloc_system.rs b/compiler/rustc_codegen_gcc/example/alloc_system.rs index 4d70122496b7..31457185f1a8 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_system.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_system.rs @@ -1,6 +1,3 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -// SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org) - #![no_std] #![feature(allocator_api, rustc_private)] diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 64a5b431bd07..2e165cc3c129 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -628,11 +628,6 @@ impl Deref for Box { } } -#[lang = "exchange_malloc"] -unsafe fn allocate(size: usize, _align: usize) -> *mut u8 { - libc::malloc(size) -} - #[lang = "drop"] pub trait Drop { fn drop(&mut self); @@ -748,25 +743,25 @@ extern "C" { pub struct VaList<'a>(&'a mut VaListImpl); #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro stringify($($t:tt)*) { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro file() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro line() { /* compiler built-in */ } #[rustc_builtin_macro] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] pub macro cfg() { /* compiler built-in */ } diff --git a/compiler/rustc_codegen_gcc/libgccjit.version b/compiler/rustc_codegen_gcc/libgccjit.version index bab62f642365..abc967702fb0 100644 --- a/compiler/rustc_codegen_gcc/libgccjit.version +++ b/compiler/rustc_codegen_gcc/libgccjit.version @@ -1 +1 @@ -0081ca6631abdfa02bf42bc85aaf507b8a0e6beb +efdd0a7290c22f5438d7c5380105d353ee3e8518 diff --git a/compiler/rustc_codegen_gcc/messages.ftl b/compiler/rustc_codegen_gcc/messages.ftl deleted file mode 100644 index b9b77b7d18c6..000000000000 --- a/compiler/rustc_codegen_gcc/messages.ftl +++ /dev/null @@ -1,8 +0,0 @@ -codegen_gcc_unwinding_inline_asm = - GCC backend does not support unwinding from inline asm - -codegen_gcc_copy_bitcode = failed to copy bitcode to object file: {$err} - -codegen_gcc_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$gcc_err}) - -codegen_gcc_explicit_tail_calls_unsupported = explicit tail calls with the 'become' keyword are not implemented in the GCC backend diff --git a/compiler/rustc_codegen_gcc/rust-toolchain b/compiler/rustc_codegen_gcc/rust-toolchain index f9645451e964..655fa6abbab2 100644 --- a/compiler/rustc_codegen_gcc/rust-toolchain +++ b/compiler/rustc_codegen_gcc/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2025-11-24" +channel = "nightly-2026-02-14" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index cc2c9fca94df..56ed7c01ed20 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -243,6 +243,8 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { pub fn conv_to_fn_attribute<'gcc>(conv: CanonAbi, arch: &Arch) -> Option> { let attribute = match conv { CanonAbi::C | CanonAbi::Rust => return None, + // gcc/gccjit does not have anything for this. + CanonAbi::RustPreserveNone => return None, CanonAbi::RustCold => FnAttribute::Cold, // Functions with this calling convention can only be called from assembly, but it is // possible to declare an `extern "custom"` block, so the backend still needs a calling diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 647569694b04..1f464d7e1226 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -1,12 +1,11 @@ #[cfg(feature = "master")] use gccjit::FnAttribute; -use gccjit::{Context, FunctionType, RValue, ToRValue, Type}; +use gccjit::{Context, FunctionType, ToRValue, Type}; use rustc_ast::expand::allocator::{ AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; -use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; use crate::GccContext; @@ -59,14 +58,6 @@ pub(crate) unsafe fn codegen( create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); } - create_const_value_function( - tcx, - context, - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - i8, - context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32), - ); - create_wrapper_function( tcx, context, @@ -77,34 +68,6 @@ pub(crate) unsafe fn codegen( ); } -fn create_const_value_function( - tcx: TyCtxt<'_>, - context: &Context<'_>, - name: &str, - output: Type<'_>, - value: RValue<'_>, -) { - let func = context.new_function(None, FunctionType::Exported, output, &[], name, false); - - #[cfg(feature = "master")] - { - func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc( - tcx.sess.default_visibility(), - ))); - - // FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using - // it here will causes linking errors when using LTO. - func.add_attribute(FnAttribute::Inline); - } - - if tcx.sess.must_emit_unwind_tables() { - // TODO(antoyo): emit unwind tables. - } - - let block = func.new_block("entry"); - block.end_with_return(None, value); -} - fn create_wrapper_function( tcx: TyCtxt<'_>, context: &Context<'_>, diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index ceb3dd3ffedf..319f3d327873 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -575,9 +575,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } if dest.is_none() && options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); - let builtin_unreachable: RValue<'gcc> = - unsafe { std::mem::transmute(builtin_unreachable) }; - self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None); + self.llbb().add_eval(None, self.context.new_call(None, builtin_unreachable, &[])); } // Write results to outputs. diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index 840f51c0685d..a08e3dc0df87 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -17,30 +17,26 @@ // /usr/bin/ld: warning: type of symbol `_RNvNvNvNvNtNtNtCsAj5i4SGTR7_3std4sync4mpmc5waker17current_thread_id5DUMMY7___getit5___KEY' changed from 1 to 6 in /tmp/ccKeUSiR.ltrans0.ltrans.o // /usr/bin/ld: warning: incremental linking of LTO and non-LTO objects; using -flinker-output=nolto-rel which will bypass whole program optimization // cSpell:enable -use std::ffi::{CStr, CString}; +use std::ffi::CString; use std::fs::{self, File}; use std::path::{Path, PathBuf}; -use std::sync::Arc; -use std::sync::atomic::Ordering; -use gccjit::{Context, OutputKind}; +use gccjit::OutputKind; use object::read::archive::ArchiveFile; -use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared}; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; +use rustc_codegen_ssa::back::lto::SerializedModule; +use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, SharedEmitter}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::memmap::Mmap; -use rustc_errors::DiagCtxtHandle; +use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_log::tracing::info; -use rustc_middle::bug; -use rustc_middle::dep_graph::WorkProduct; use rustc_session::config::Lto; -use rustc_target::spec::RelocModel; use tempfile::{TempDir, tempdir}; use crate::back::write::save_temp_bitcode; use crate::errors::LtoBitcodeFromRlib; -use crate::{GccCodegenBackend, GccContext, LTO_SUPPORTED, LtoMode, SyncContext, to_gcc_opt_level}; +use crate::{GccCodegenBackend, GccContext, LtoMode, to_gcc_opt_level}; struct LtoData { // TODO(antoyo): use symbols_below_threshold. @@ -50,7 +46,7 @@ struct LtoData { } fn prepare_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, each_linked_rlib_for_lto: &[PathBuf], dcx: DiagCtxtHandle<'_>, ) -> LtoData { @@ -111,17 +107,20 @@ fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> { /// Performs fat LTO by merging all modules into a single one and returning it /// for further optimization. pub(crate) fn run_fat( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); /*let symbols_below_threshold = lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>();*/ fat_lto( cgcx, + prof, dcx, modules, lto_data.upstream_modules, @@ -131,14 +130,15 @@ pub(crate) fn run_fat( } fn fat_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, _dcx: DiagCtxtHandle<'_>, modules: Vec>, mut serialized_modules: Vec<(SerializedModule, CString)>, tmp_path: TempDir, //symbols_below_threshold: &[String], ) -> ModuleCodegen { - let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module"); + let _timer = prof.generic_activity("GCC_fat_lto_build_monolithic_module"); info!("going for a fat lto"); // Sort out all our lists of incoming modules into two lists. @@ -222,8 +222,7 @@ fn fat_lto( // We add the object files and save in should_combine_object_files that we should combine // them into a single object file when compiling later. for (bc_decoded, name) in serialized_modules { - let _timer = cgcx - .prof + let _timer = prof .generic_activity_with_arg_recorder("GCC_fat_lto_link_module", |recorder| { recorder.record_arg(format!("{:?}", name)) }); @@ -277,387 +276,3 @@ impl ModuleBufferMethods for ModuleBuffer { &[] } } - -/// Performs thin LTO by performing necessary global analysis and returning two -/// lists, one of the modules that need optimization and another for modules that -/// can simply be copied over from the incr. comp. cache. -pub(crate) fn run_thin( - cgcx: &CodegenContext, - each_linked_rlib_for_lto: &[PathBuf], - modules: Vec<(String, ThinBuffer)>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, -) -> (Vec>, Vec) { - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); - let lto_data = prepare_lto(cgcx, each_linked_rlib_for_lto, dcx); - if cgcx.opts.cg.linker_plugin_lto.enabled() { - unreachable!( - "We should never reach this case if the LTO step \ - is deferred to the linker" - ); - } - thin_lto( - cgcx, - dcx, - modules, - lto_data.upstream_modules, - lto_data.tmp_path, - cached_modules, - //<o_data.symbols_below_threshold, - ) -} - -pub(crate) fn prepare_thin(module: ModuleCodegen) -> (String, ThinBuffer) { - let name = module.name; - //let buffer = ThinBuffer::new(module.module_llvm.context, true); - let buffer = ThinBuffer::new(&module.module_llvm.context); - (name, buffer) -} - -/// Prepare "thin" LTO to get run on these modules. -/// -/// The general structure of ThinLTO is quite different from the structure of -/// "fat" LTO above. With "fat" LTO all LLVM modules in question are merged into -/// one giant LLVM module, and then we run more optimization passes over this -/// big module after internalizing most symbols. Thin LTO, on the other hand, -/// avoid this large bottleneck through more targeted optimization. -/// -/// At a high level Thin LTO looks like: -/// -/// 1. Prepare a "summary" of each LLVM module in question which describes -/// the values inside, cost of the values, etc. -/// 2. Merge the summaries of all modules in question into one "index" -/// 3. Perform some global analysis on this index -/// 4. For each module, use the index and analysis calculated previously to -/// perform local transformations on the module, for example inlining -/// small functions from other modules. -/// 5. Run thin-specific optimization passes over each module, and then code -/// generate everything at the end. -/// -/// The summary for each module is intended to be quite cheap, and the global -/// index is relatively quite cheap to create as well. As a result, the goal of -/// ThinLTO is to reduce the bottleneck on LTO and enable LTO to be used in more -/// situations. For example one cheap optimization is that we can parallelize -/// all codegen modules, easily making use of all the cores on a machine. -/// -/// With all that in mind, the function here is designed at specifically just -/// calculating the *index* for ThinLTO. This index will then be shared amongst -/// all of the `LtoModuleCodegen` units returned below and destroyed once -/// they all go out of scope. -fn thin_lto( - cgcx: &CodegenContext, - _dcx: DiagCtxtHandle<'_>, - modules: Vec<(String, ThinBuffer)>, - serialized_modules: Vec<(SerializedModule, CString)>, - tmp_path: TempDir, - cached_modules: Vec<(SerializedModule, WorkProduct)>, - //_symbols_below_threshold: &[String], -) -> (Vec>, Vec) { - let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis"); - info!("going for that thin, thin LTO"); - - /*let green_modules: FxHashMap<_, _> = - cached_modules.iter().map(|(_, wp)| (wp.cgu_name.clone(), wp.clone())).collect();*/ - - let full_scope_len = modules.len() + serialized_modules.len() + cached_modules.len(); - let mut thin_buffers = Vec::with_capacity(modules.len()); - let mut module_names = Vec::with_capacity(full_scope_len); - //let mut thin_modules = Vec::with_capacity(full_scope_len); - - for (i, (name, buffer)) in modules.into_iter().enumerate() { - info!("local module: {} - {}", i, name); - let cname = CString::new(name.as_bytes()).unwrap(); - /*thin_modules.push(llvm::ThinLTOModule { - identifier: cname.as_ptr(), - data: buffer.data().as_ptr(), - len: buffer.data().len(), - });*/ - thin_buffers.push(buffer); - module_names.push(cname); - } - - // FIXME: All upstream crates are deserialized internally in the - // function below to extract their summary and modules. Note that - // unlike the loop above we *must* decode and/or read something - // here as these are all just serialized files on disk. An - // improvement, however, to make here would be to store the - // module summary separately from the actual module itself. Right - // now this is store in one large bitcode file, and the entire - // file is deflate-compressed. We could try to bypass some of the - // decompression by storing the index uncompressed and only - // lazily decompressing the bytecode if necessary. - // - // Note that truly taking advantage of this optimization will - // likely be further down the road. We'd have to implement - // incremental ThinLTO first where we could actually avoid - // looking at upstream modules entirely sometimes (the contents, - // we must always unconditionally look at the index). - let mut serialized = Vec::with_capacity(serialized_modules.len() + cached_modules.len()); - - let cached_modules = - cached_modules.into_iter().map(|(sm, wp)| (sm, CString::new(wp.cgu_name).unwrap())); - - for (module, name) in serialized_modules.into_iter().chain(cached_modules) { - info!("upstream or cached module {:?}", name); - /*thin_modules.push(llvm::ThinLTOModule { - identifier: name.as_ptr(), - data: module.data().as_ptr(), - len: module.data().len(), - });*/ - - match module { - SerializedModule::Local(_) => { - //let path = module_buffer.0.to_str().expect("path"); - //let my_path = PathBuf::from(path); - //let exists = my_path.exists(); - /*module.module_llvm.should_combine_object_files = true; - module - .module_llvm - .context - .add_driver_option(module_buffer.0.to_str().expect("path"));*/ - } - SerializedModule::FromRlib(_) => unimplemented!("from rlib"), - SerializedModule::FromUncompressedFile(_) => { - unimplemented!("from uncompressed file") - } - } - - serialized.push(module); - module_names.push(name); - } - - // Sanity check - //assert_eq!(thin_modules.len(), module_names.len()); - - // Delegate to the C++ bindings to create some data here. Once this is a - // tried-and-true interface we may wish to try to upstream some of this - // to LLVM itself, right now we reimplement a lot of what they do - // upstream... - /*let data = llvm::LLVMRustCreateThinLTOData( - thin_modules.as_ptr(), - thin_modules.len() as u32, - symbols_below_threshold.as_ptr(), - symbols_below_threshold.len() as u32, - ) - .ok_or_else(|| write::llvm_err(dcx, LlvmError::PrepareThinLtoContext))?; - */ - - let data = ThinData; //(Arc::new(tmp_path))/*(data)*/; - - info!("thin LTO data created"); - - /*let (key_map_path, prev_key_map, curr_key_map) = - if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir { - let path = incr_comp_session_dir.join(THIN_LTO_KEYS_INCR_COMP_FILE_NAME); - // If the previous file was deleted, or we get an IO error - // reading the file, then we'll just use `None` as the - // prev_key_map, which will force the code to be recompiled. - let prev = - if path.exists() { ThinLTOKeysMap::load_from_file(&path).ok() } else { None }; - let curr = ThinLTOKeysMap::from_thin_lto_modules(&data, &thin_modules, &module_names); - (Some(path), prev, curr) - } - else { - // If we don't compile incrementally, we don't need to load the - // import data from LLVM. - assert!(green_modules.is_empty()); - let curr = ThinLTOKeysMap::default(); - (None, None, curr) - }; - info!("thin LTO cache key map loaded"); - info!("prev_key_map: {:#?}", prev_key_map); - info!("curr_key_map: {:#?}", curr_key_map);*/ - - // Throw our data in an `Arc` as we'll be sharing it across threads. We - // also put all memory referenced by the C++ data (buffers, ids, etc) - // into the arc as well. After this we'll create a thin module - // codegen per module in this data. - let shared = - Arc::new(ThinShared { data, thin_buffers, serialized_modules: serialized, module_names }); - - let copy_jobs = vec![]; - let mut opt_jobs = vec![]; - - info!("checking which modules can be-reused and which have to be re-optimized."); - for (module_index, module_name) in shared.module_names.iter().enumerate() { - let module_name = module_name_to_str(module_name); - /*if let (Some(prev_key_map), true) = - (prev_key_map.as_ref(), green_modules.contains_key(module_name)) - { - assert!(cgcx.incr_comp_session_dir.is_some()); - - // If a module exists in both the current and the previous session, - // and has the same LTO cache key in both sessions, then we can re-use it - if prev_key_map.keys.get(module_name) == curr_key_map.keys.get(module_name) { - let work_product = green_modules[module_name].clone(); - copy_jobs.push(work_product); - info!(" - {}: re-used", module_name); - assert!(cgcx.incr_comp_session_dir.is_some()); - continue; - } - }*/ - - info!(" - {}: re-compiled", module_name); - opt_jobs.push(ThinModule { shared: shared.clone(), idx: module_index }); - } - - // Save the current ThinLTO import information for the next compilation - // session, overwriting the previous serialized data (if any). - /*if let Some(path) = key_map_path { - if let Err(err) = curr_key_map.save_to_file(&path) { - return Err(write::llvm_err(dcx, LlvmError::WriteThinLtoKey { err })); - } - }*/ - - // NOTE: save the temporary directory used by LTO so that it gets deleted after linking instead - // of now. - //module.module_llvm.temp_dir = Some(tmp_path); - // TODO: save the directory so that it gets deleted later. - std::mem::forget(tmp_path); - - (opt_jobs, copy_jobs) -} - -pub fn optimize_thin_module( - thin_module: ThinModule, - _cgcx: &CodegenContext, -) -> ModuleCodegen { - //let dcx = cgcx.create_dcx(); - - //let module_name = &thin_module.shared.module_names[thin_module.idx]; - /*let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, module_name.to_str().unwrap()); - let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&dcx, e))?;*/ - - // Right now the implementation we've got only works over serialized - // modules, so we create a fresh new LLVM context and parse the module - // into that context. One day, however, we may do this for upstream - // crates but for locally codegened modules we may be able to reuse - // that LLVM Context and Module. - //let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); - //let llmod_raw = parse_module(llcx, module_name, thin_module.data(), &dcx)? as *const _; - let mut lto_mode = LtoMode::None; - let context = match thin_module.shared.thin_buffers.get(thin_module.idx) { - Some(thin_buffer) => Arc::clone(&thin_buffer.context), - None => { - let context = Context::default(); - let len = thin_module.shared.thin_buffers.len(); - let module = &thin_module.shared.serialized_modules[thin_module.idx - len]; - match *module { - SerializedModule::Local(ref module_buffer) => { - let path = module_buffer.0.to_str().expect("path"); - context.add_driver_option(path); - lto_mode = LtoMode::Thin; - /*module.module_llvm.should_combine_object_files = true; - module - .module_llvm - .context - .add_driver_option(module_buffer.0.to_str().expect("path"));*/ - } - SerializedModule::FromRlib(_) => unimplemented!("from rlib"), - SerializedModule::FromUncompressedFile(_) => { - unimplemented!("from uncompressed file") - } - } - Arc::new(SyncContext::new(context)) - } - }; - let lto_supported = LTO_SUPPORTED.load(Ordering::SeqCst); - let module = ModuleCodegen::new_regular( - thin_module.name().to_string(), - GccContext { - context, - lto_mode, - lto_supported, - // TODO(antoyo): use the correct relocation model here. - relocation_model: RelocModel::Pic, - temp_dir: None, - }, - ); - /*{ - let target = &*module.module_llvm.tm; - let llmod = module.module_llvm.llmod(); - save_temp_bitcode(cgcx, &module, "thin-lto-input"); - - // Up next comes the per-module local analyses that we do for Thin LTO. - // Each of these functions is basically copied from the LLVM - // implementation and then tailored to suit this implementation. Ideally - // each of these would be supported by upstream LLVM but that's perhaps - // a patch for another day! - // - // You can find some more comments about these functions in the LLVM - // bindings we've got (currently `PassWrapper.cpp`) - { - let _timer = - cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name()); - unsafe { llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) }; - save_temp_bitcode(cgcx, &module, "thin-lto-after-rename"); - } - - { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name()); - if !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) { - return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule)); - } - save_temp_bitcode(cgcx, &module, "thin-lto-after-resolve"); - } - - { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name()); - if !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) { - return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule)); - } - save_temp_bitcode(cgcx, &module, "thin-lto-after-internalize"); - } - - { - let _timer = - cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name()); - if !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target) { - return Err(write::llvm_err(&dcx, LlvmError::PrepareThinLtoModule)); - } - save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); - } - - // Alright now that we've done everything related to the ThinLTO - // analysis it's time to run some optimizations! Here we use the same - // `run_pass_manager` as the "fat" LTO above except that we tell it to - // populate a thin-specific pass manager, which presumably LLVM treats a - // little differently. - { - info!("running thin lto passes over {}", module.name); - run_pass_manager(cgcx, &dcx, &mut module, true)?; - save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); - } - }*/ - // FIXME: switch to #[expect] when the clippy bug is fixed. - #[allow(clippy::let_and_return)] - module -} - -pub struct ThinBuffer { - context: Arc, -} - -impl ThinBuffer { - pub(crate) fn new(context: &Arc) -> Self { - Self { context: Arc::clone(context) } - } -} - -impl ThinBufferMethods for ThinBuffer { - fn data(&self) -> &[u8] { - &[] - } -} - -pub struct ThinData; //(Arc); - -fn module_name_to_str(c_str: &CStr) -> &str { - c_str.to_str().unwrap_or_else(|e| { - bug!("Encountered non-utf8 GCC module name `{}`: {}", c_str.to_string_lossy(), e) - }) -} diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs index eae0f2aa00f6..ddf13558027b 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -2,8 +2,12 @@ use std::{env, fs}; use gccjit::{Context, OutputKind}; use rustc_codegen_ssa::back::link::ensure_removed; -use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; +use rustc_codegen_ssa::back::write::{ + BitcodeSection, CodegenContext, EmitObj, ModuleConfig, SharedEmitter, +}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; +use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_errors::DiagCtxt; use rustc_fs_util::link_or_copy; use rustc_log::tracing::debug; use rustc_session::config::OutputType; @@ -11,17 +15,19 @@ use rustc_target::spec::SplitDebuginfo; use crate::base::add_pic_option; use crate::errors::CopyBitcode; -use crate::{GccCodegenBackend, GccContext, LtoMode}; +use crate::{GccContext, LtoMode}; pub(crate) fn codegen( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); - let _timer = cgcx.prof.generic_activity_with_arg("GCC_module_codegen", &*module.name); + let _timer = prof.generic_activity_with_arg("GCC_module_codegen", &*module.name); { let context = &module.module_llvm.context; @@ -40,9 +46,8 @@ pub(crate) fn codegen( ); if config.bitcode_needed() { - let _timer = cgcx - .prof - .generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); + let _timer = + prof.generic_activity_with_arg("GCC_module_codegen_make_bitcode", &*module.name); // TODO(antoyo) /*if let Some(bitcode_filename) = bc_out.file_name() { @@ -54,8 +59,7 @@ pub(crate) fn codegen( }*/ if config.emit_bc || config.emit_obj == EmitObj::Bitcode { - let _timer = cgcx - .prof + let _timer = prof .generic_activity_with_arg("GCC_module_codegen_emit_bitcode", &*module.name); if lto_supported { context.add_command_line_option("-flto=auto"); @@ -66,8 +70,7 @@ pub(crate) fn codegen( } if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { - let _timer = cgcx - .prof + let _timer = prof .generic_activity_with_arg("GCC_module_codegen_embed_bitcode", &*module.name); if lto_supported { // TODO(antoyo): maybe we should call embed_bitcode to have the proper iOS fixes? @@ -94,7 +97,7 @@ pub(crate) fn codegen( if config.emit_asm { let _timer = - cgcx.prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name); + prof.generic_activity_with_arg("GCC_module_codegen_emit_asm", &*module.name); let path = cgcx.output_filenames.temp_path_for_cgu( OutputType::Assembly, &module.name, @@ -105,9 +108,8 @@ pub(crate) fn codegen( match config.emit_obj { EmitObj::ObjectCode(_) => { - let _timer = cgcx - .prof - .generic_activity_with_arg("GCC_module_codegen_emit_obj", &*module.name); + let _timer = + prof.generic_activity_with_arg("GCC_module_codegen_emit_obj", &*module.name); if env::var("CG_GCCJIT_DUMP_MODULE_NAMES").as_deref() == Ok("1") { println!("Module {}", module.name); } @@ -223,7 +225,7 @@ pub(crate) fn codegen( } pub(crate) fn save_temp_bitcode( - cgcx: &CodegenContext, + cgcx: &CodegenContext, _module: &ModuleCodegen, _name: &str, ) { diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 1787415b72e6..e1937f5c11eb 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -314,14 +314,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.block.get_function() } - fn function_call( + pub fn function_call( &mut self, - func: RValue<'gcc>, + func: Function<'gcc>, args: &[RValue<'gcc>], _funclet: Option<&Funclet>, ) -> RValue<'gcc> { - // TODO(antoyo): remove when the API supports a different type for functions. - let func: Function<'gcc> = self.cx.rvalue_as_function(func); let args = self.check_call("call", func, args); // gccjit requires to use the result of functions, even when it's not used. @@ -500,11 +498,11 @@ impl<'gcc, 'tcx> BackendTypes for Builder<'_, 'gcc, 'tcx> { } fn set_rvalue_location<'a, 'gcc, 'tcx>( - bx: &mut Builder<'a, 'gcc, 'tcx>, + _bx: &mut Builder<'a, 'gcc, 'tcx>, rvalue: RValue<'gcc>, ) -> RValue<'gcc> { - if let Some(location) = bx.location { - #[cfg(feature = "master")] + #[cfg(feature = "master")] + if let Some(location) = _bx.location { rvalue.set_location(location); } rvalue @@ -514,6 +512,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { type CodegenCx = CodegenCx<'gcc, 'tcx>; fn build(cx: &'a CodegenCx<'gcc, 'tcx>, block: Block<'gcc>) -> Builder<'a, 'gcc, 'tcx> { + *cx.current_func.borrow_mut() = Some(block.get_function()); Builder::with_cx(cx, block) } @@ -943,6 +942,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { .get_address(self.location) } + fn scalable_alloca(&mut self, _elt: u64, _align: Align, _element_ty: Ty<'_>) -> RValue<'gcc> { + todo!() + } + fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> { let block = self.llbb(); let function = block.get_function(); @@ -1492,6 +1495,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { #[cfg(not(feature = "master"))] fn extract_element(&mut self, vec: RValue<'gcc>, idx: RValue<'gcc>) -> RValue<'gcc> { + use crate::context::new_array_type; + let vector_type = vec .get_type() .unqualified() @@ -1500,7 +1505,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { let element_type = vector_type.get_element_type(); let vec_num_units = vector_type.get_num_units(); let array_type = - self.context.new_array_type(self.location, element_type, vec_num_units as u64); + new_array_type(self.context, self.location, element_type, vec_num_units as u64); let array = self.context.new_bitcast(self.location, vec, array_type).to_rvalue(); self.context.new_array_access(self.location, array, idx).to_rvalue() } @@ -1761,6 +1766,8 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // FIXME(antoyo): remove when having a proper API. let gcc_func = unsafe { std::mem::transmute::, Function<'gcc>>(func) }; let call = if self.functions.borrow().values().any(|value| *value == gcc_func) { + // TODO(antoyo): remove when the API supports a different type for functions. + let func: Function<'gcc> = self.cx.rvalue_as_function(func); self.function_call(func, args, funclet) } else { // If it's a not function that was defined, it's a function pointer. @@ -1866,32 +1873,31 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { // On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because // we're rounding towards zero, we just get float_ty::MAX (which is always an integer). // This already happens today with u128::MAX = 2^128 - 1 > f32::MAX. - let int_max = |signed: bool, int_width: u64| -> u128 { + fn int_max(signed: bool, int_width: u64) -> u128 { let shift_amount = 128 - int_width; if signed { i128::MAX as u128 >> shift_amount } else { u128::MAX >> shift_amount } - }; - let int_min = |signed: bool, int_width: u64| -> i128 { + } + fn int_min(signed: bool, int_width: u64) -> i128 { if signed { i128::MIN >> (128 - int_width) } else { 0 } - }; + } - let compute_clamp_bounds_single = |signed: bool, int_width: u64| -> (u128, u128) { + // TODO: rewrite using a generic function with . + let compute_clamp_bounds_half = |signed: bool, int_width: u64| -> (u128, u128) { let rounded_min = - ieee::Single::from_i128_r(int_min(signed, int_width), Round::TowardZero); - assert_eq!(rounded_min.status, Status::OK); + ieee::Half::from_i128_r(int_min(signed, int_width), Round::TowardZero); + //assert_eq!(rounded_min.status, Status::OK); let rounded_max = - ieee::Single::from_u128_r(int_max(signed, int_width), Round::TowardZero); + ieee::Half::from_u128_r(int_max(signed, int_width), Round::TowardZero); assert!(rounded_max.value.is_finite()); (rounded_min.value.to_bits(), rounded_max.value.to_bits()) }; - let compute_clamp_bounds_double = |signed: bool, int_width: u64| -> (u128, u128) { - let rounded_min = - ieee::Double::from_i128_r(int_min(signed, int_width), Round::TowardZero); + fn compute_clamp_bounds(signed: bool, int_width: u64) -> (u128, u128) { + let rounded_min = F::from_i128_r(int_min(signed, int_width), Round::TowardZero); assert_eq!(rounded_min.status, Status::OK); - let rounded_max = - ieee::Double::from_u128_r(int_max(signed, int_width), Round::TowardZero); + let rounded_max = F::from_u128_r(int_max(signed, int_width), Round::TowardZero); assert!(rounded_max.value.is_finite()); (rounded_min.value.to_bits(), rounded_max.value.to_bits()) - }; + } // To implement saturation, we perform the following steps: // // 1. Cast val to an integer with fpto[su]i. This may result in undef. @@ -1921,15 +1927,19 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { let float_bits_to_llval = |bx: &mut Self, bits| { let bits_llval = match float_width { + 16 => bx.cx().const_u16(bits as u16), 32 => bx.cx().const_u32(bits as u32), 64 => bx.cx().const_u64(bits as u64), + 128 => bx.cx().const_u128(bits), n => bug!("unsupported float width {}", n), }; bx.bitcast(bits_llval, float_ty) }; let (f_min, f_max) = match float_width { - 32 => compute_clamp_bounds_single(signed, int_width), - 64 => compute_clamp_bounds_double(signed, int_width), + 16 => compute_clamp_bounds_half(signed, int_width), + 32 => compute_clamp_bounds::(signed, int_width), + 64 => compute_clamp_bounds::(signed, int_width), + 128 => compute_clamp_bounds::(signed, int_width), n => bug!("unsupported float width {}", n), }; let f_min = float_bits_to_llval(self, f_min); diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 7c2969e58718..86a4eeac89d5 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::Mutability; use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar}; use rustc_middle::ty::layout::LayoutOf; -use crate::context::CodegenCx; +use crate::context::{CodegenCx, new_array_type}; use crate::type_of::LayoutGccExt; impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { @@ -20,6 +20,10 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { bytes_in_context(self, bytes) } + pub fn const_u16(&self, i: u16) -> RValue<'gcc> { + self.const_uint(self.type_u16(), i as u64) + } + fn global_string(&self, string: &str) -> LValue<'gcc> { // TODO(antoyo): handle non-null-terminated strings. let string = self.context.new_string_literal(string); @@ -55,7 +59,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> 0 => { let context = &cx.context; let byte_type = context.new_type::(); - let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 8); + let typ = new_array_type(context, None, byte_type, bytes.len() as u64 / 8); let elements: Vec<_> = bytes .chunks_exact(8) .map(|arr| { @@ -76,7 +80,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> 4 => { let context = &cx.context; let byte_type = context.new_type::(); - let typ = context.new_array_type(None, byte_type, bytes.len() as u64 / 4); + let typ = new_array_type(context, None, byte_type, bytes.len() as u64 / 4); let elements: Vec<_> = bytes .chunks_exact(4) .map(|arr| { @@ -95,7 +99,7 @@ pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> _ => { let context = cx.context; let byte_type = context.new_type::(); - let typ = context.new_array_type(None, byte_type, bytes.len() as u64); + let typ = new_array_type(context, None, byte_type, bytes.len() as u64); let elements: Vec<_> = bytes .iter() .map(|&byte| context.new_rvalue_from_int(byte_type, byte as i32)) diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index dbb89a4ff7db..03f207f45724 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -19,6 +19,8 @@ use rustc_middle::ty::layout::{ }; use rustc_middle::ty::{self, ExistentialTraitRef, Instance, Ty, TyCtxt}; use rustc_session::Session; +#[cfg(feature = "master")] +use rustc_session::config::DebugInfo; use rustc_span::source_map::respan; use rustc_span::{DUMMY_SP, Span}; use rustc_target::spec::{HasTargetSpec, HasX86AbiOpt, Target, TlsModel, X86Abi}; @@ -92,6 +94,8 @@ pub struct CodegenCx<'gcc, 'tcx> { pub instances: RefCell, LValue<'gcc>>>, /// Cache function instances of monomorphic and polymorphic items pub function_instances: RefCell, Function<'gcc>>>, + /// Cache function instances of intrinsics + pub intrinsic_instances: RefCell, Function<'gcc>>>, /// Cache generated vtables pub vtables: RefCell, Option>), RValue<'gcc>>>, @@ -143,6 +147,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { supports_f64_type: bool, supports_f128_type: bool, ) -> Self { + #[cfg(feature = "master")] + if tcx.sess.opts.debuginfo != DebugInfo::None { + context.set_filename(codegen_unit.name().as_str()); + } + let create_type = |ctype, rust_type| { let layout = tcx .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type)) @@ -192,8 +201,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { // TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in // gcc_jit_context_new_array_constructor (it should not use reinterpret_cast). - let i128_type = context.new_array_type(None, i64_type, 2)/*.get_aligned(i128_align)*/; - let u128_type = context.new_array_type(None, u64_type, 2)/*.get_aligned(u128_align)*/; + let i128_type = new_array_type(context, None, i64_type, 2)/*.get_aligned(i128_align)*/; + let u128_type = new_array_type(context, None, u64_type, 2)/*.get_aligned(u128_align)*/; (i128_type, u128_type) }; @@ -280,6 +289,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { linkage: Cell::new(FunctionType::Internal), instances: Default::default(), function_instances: Default::default(), + intrinsic_instances: Default::default(), on_stack_params: Default::default(), on_stack_function_params: Default::default(), vtables: Default::default(), @@ -391,17 +401,13 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn get_fn(&self, instance: Instance<'tcx>) -> Function<'gcc> { - let func = get_fn(self, instance); - *self.current_func.borrow_mut() = Some(func); - func + get_fn(self, instance) } fn get_fn_addr(&self, instance: Instance<'tcx>) -> RValue<'gcc> { let func_name = self.tcx.symbol_name(instance).name; - let func = if self.intrinsics.borrow().contains_key(func_name) { - self.intrinsics.borrow()[func_name] - } else if let Some(variable) = self.get_declared_value(func_name) { + let func = if let Some(variable) = self.get_declared_value(func_name) { return variable; } else { get_fn(self, instance) @@ -602,3 +608,17 @@ fn to_gcc_tls_mode(tls_model: TlsModel) -> gccjit::TlsModel { TlsModel::Emulated => gccjit::TlsModel::GlobalDynamic, } } + +pub fn new_array_type<'gcc>( + context: &'gcc Context<'gcc>, + location: Option>, + typ: Type<'gcc>, + size: u64, +) -> Type<'gcc> { + #[cfg(feature = "master")] + { + context.new_array_type_u64(location, typ, size) + } + #[cfg(not(feature = "master"))] + context.new_array_type(location, typ, size) +} diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 3979f62987f2..53d3670c1524 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -297,29 +297,11 @@ impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let pos = span.lo(); let DebugLoc { file, line, col } = self.lookup_debug_loc(pos); match file.name { - rustc_span::FileName::Real(ref name) => match *name { - rustc_span::RealFileName::LocalPath(ref name) => { - if let Some(name) = name.to_str() { - self.context.new_location(name, line as i32, col as i32) - } else { - Location::null() - } - } - rustc_span::RealFileName::Remapped { - ref local_path, - virtual_name: ref _unused, - } => { - if let Some(name) = local_path.as_ref() { - if let Some(name) = name.to_str() { - self.context.new_location(name, line as i32, col as i32) - } else { - Location::null() - } - } else { - Location::null() - } - } - }, + rustc_span::FileName::Real(ref name) => self.context.new_location( + name.path(rustc_span::RemapPathScopeComponents::DEBUGINFO).to_string_lossy(), + line as i32, + col as i32, + ), _ => Location::null(), } } diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs index 42d6fb17a88b..6450e2d4039c 100644 --- a/compiler/rustc_codegen_gcc/src/declare.rs +++ b/compiler/rustc_codegen_gcc/src/declare.rs @@ -8,7 +8,6 @@ use rustc_target::callconv::FnAbi; use crate::abi::{FnAbiGcc, FnAbiGccExt}; use crate::context::CodegenCx; -use crate::intrinsic::llvm; impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { pub fn get_or_insert_global( @@ -100,18 +99,14 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let return_type = self.type_i32(); let variadic = false; self.linkage.set(FunctionType::Exported); - let func = declare_raw_fn( + declare_raw_fn( self, name, callconv, return_type, &[self.type_i32(), const_string], variadic, - ); - // NOTE: it is needed to set the current_func here as well, because get_fn() is not called - // for the main function. - *self.current_func.borrow_mut() = Some(func); - func + ) } pub fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Function<'gcc> { @@ -156,7 +151,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. -#[expect(clippy::let_and_return)] fn declare_raw_fn<'gcc>( cx: &CodegenCx<'gcc, '_>, name: &str, @@ -166,19 +160,6 @@ fn declare_raw_fn<'gcc>( param_types: &[Type<'gcc>], variadic: bool, ) -> Function<'gcc> { - if name.starts_with("llvm.") { - let intrinsic = match name { - "llvm.fma.f16" => { - // fma is not a target builtin, but a normal builtin, so we handle it differently - // here. - cx.context.get_builtin_function("fma") - } - _ => llvm::intrinsic(name, cx), - }; - - cx.intrinsics.borrow_mut().insert(name.to_string(), intrinsic); - return intrinsic; - } let func = if cx.functions.borrow().contains_key(name) { cx.functions.borrow()[name] } else { diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs index b252c39c0c05..f5815e723392 100644 --- a/compiler/rustc_codegen_gcc/src/errors.rs +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -2,24 +2,24 @@ use rustc_macros::Diagnostic; use rustc_span::Span; #[derive(Diagnostic)] -#[diag(codegen_gcc_unwinding_inline_asm)] +#[diag("GCC backend does not support unwinding from inline asm")] pub(crate) struct UnwindingInlineAsm { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(codegen_gcc_copy_bitcode)] +#[diag("failed to copy bitcode to object file: {$err}")] pub(crate) struct CopyBitcode { pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_gcc_lto_bitcode_from_rlib)] +#[diag("failed to get bitcode from object file for LTO ({$gcc_err})")] pub(crate) struct LtoBitcodeFromRlib { pub gcc_err: String, } #[derive(Diagnostic)] -#[diag(codegen_gcc_explicit_tail_calls_unsupported)] +#[diag("explicit tail calls with the 'become' keyword are not implemented in the GCC backend")] pub(crate) struct ExplicitTailCallsUnsupported; diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs index 49de0b490e88..51612d604c8f 100644 --- a/compiler/rustc_codegen_gcc/src/int.rs +++ b/compiler/rustc_codegen_gcc/src/int.rs @@ -942,7 +942,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { fn float_to_int_cast( &self, signed: bool, - value: RValue<'gcc>, + mut value: RValue<'gcc>, dest_typ: Type<'gcc>, ) -> RValue<'gcc> { let value_type = value.get_type(); @@ -951,16 +951,22 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { } debug_assert!(dest_typ.dyncast_array().is_some()); + let (dest_type, param_type) = match self.type_kind(value_type) { + TypeKind::Half => (Some(self.float_type), self.float_type), + _ => (None, value_type), + }; let name_suffix = match self.type_kind(value_type) { // cSpell:disable - TypeKind::Float => "sfti", + // Since we will cast Half to a float, we use sfti for both. + TypeKind::Half | TypeKind::Float => "sfti", TypeKind::Double => "dfti", + TypeKind::FP128 => "tfti", // cSpell:enable kind => panic!("cannot cast a {:?} to non-native integer", kind), }; let sign = if signed { "" } else { "uns" }; let func_name = format!("__fix{}{}", sign, name_suffix); - let param = self.context.new_parameter(None, value_type, "n"); + let param = self.context.new_parameter(None, param_type, "n"); let func = self.context.new_function( None, FunctionType::Extern, @@ -969,6 +975,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { func_name, false, ); + if let Some(dest_type) = dest_type { + value = self.context.new_cast(None, value, dest_type); + } self.context.new_call(None, func, &[value]) } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs b/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs index bb8bcbf66f38..3c1698df6dec 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/archs.rs @@ -6,47 +6,13 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) }; let Some((arch, name)) = name.split_once('.') else { - unimplemented!("***** unsupported LLVM intrinsic {}", name) + unimplemented!("***** unsupported LLVM intrinsic llvm.{}", name) }; + let old_arch_res = old_archs(arch, name); + if let ArchCheckResult::Ok(res) = old_arch_res { + return res; + } match arch { - "AMDGPU" => { - #[expect(non_snake_case)] - fn AMDGPU(name: &str, full_name: &str) -> &'static str { - match name { - // AMDGPU - "div.fixup.f32" => "__builtin_amdgpu_div_fixup", - "div.fixup.f64" => "__builtin_amdgpu_div_fixup", - "div.fixup.v2f64" => "__builtin_amdgpu_div_fixup", - "div.fixup.v4f32" => "__builtin_amdgpu_div_fixup", - "div.fmas.f32" => "__builtin_amdgpu_div_fmas", - "div.fmas.f64" => "__builtin_amdgpu_div_fmas", - "div.fmas.v2f64" => "__builtin_amdgpu_div_fmas", - "div.fmas.v4f32" => "__builtin_amdgpu_div_fmas", - "ldexp.f32" => "__builtin_amdgpu_ldexp", - "ldexp.f64" => "__builtin_amdgpu_ldexp", - "ldexp.v2f64" => "__builtin_amdgpu_ldexp", - "ldexp.v4f32" => "__builtin_amdgpu_ldexp", - "rcp.f32" => "__builtin_amdgpu_rcp", - "rcp.f64" => "__builtin_amdgpu_rcp", - "rcp.v2f64" => "__builtin_amdgpu_rcp", - "rcp.v4f32" => "__builtin_amdgpu_rcp", - "rsq.clamped.f32" => "__builtin_amdgpu_rsq_clamped", - "rsq.clamped.f64" => "__builtin_amdgpu_rsq_clamped", - "rsq.clamped.v2f64" => "__builtin_amdgpu_rsq_clamped", - "rsq.clamped.v4f32" => "__builtin_amdgpu_rsq_clamped", - "rsq.f32" => "__builtin_amdgpu_rsq", - "rsq.f64" => "__builtin_amdgpu_rsq", - "rsq.v2f64" => "__builtin_amdgpu_rsq", - "rsq.v4f32" => "__builtin_amdgpu_rsq", - "trig.preop.f32" => "__builtin_amdgpu_trig_preop", - "trig.preop.f64" => "__builtin_amdgpu_trig_preop", - "trig.preop.v2f64" => "__builtin_amdgpu_trig_preop", - "trig.preop.v4f32" => "__builtin_amdgpu_trig_preop", - _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), - } - } - AMDGPU(name, full_name) - } "aarch64" => { fn aarch64(name: &str, full_name: &str) -> &'static str { match name { @@ -58,6 +24,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "gcsss" => "__builtin_arm_gcsss", "isb" => "__builtin_arm_isb", "prefetch" => "__builtin_arm_prefetch", + "range.prefetch" => "__builtin_arm_range_prefetch", "sme.in.streaming.mode" => "__builtin_arm_in_streaming_mode", "sve.aesd" => "__builtin_sve_svaesd_u8", "sve.aese" => "__builtin_sve_svaese_u8", @@ -70,10 +37,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sve.sm4e" => "__builtin_sve_svsm4e_u32", "sve.sm4ekey" => "__builtin_sve_svsm4ekey_u32", "sve.wrffr" => "__builtin_sve_svwrffr", - "tcancel" => "__builtin_arm_tcancel", - "tcommit" => "__builtin_arm_tcommit", - "tstart" => "__builtin_arm_tstart", - "ttest" => "__builtin_arm_ttest", _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), } } @@ -452,6 +415,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "s.wait.event.export.ready" => "__builtin_amdgcn_s_wait_event_export_ready", "s.wait.tensorcnt" => "__builtin_amdgcn_s_wait_tensorcnt", "s.waitcnt" => "__builtin_amdgcn_s_waitcnt", + "s.wakeup.barrier" => "__builtin_amdgcn_s_wakeup_barrier", "sad.hi.u8" => "__builtin_amdgcn_sad_hi_u8", "sad.u16" => "__builtin_amdgcn_sad_u16", "sad.u8" => "__builtin_amdgcn_sad_u8", @@ -541,8 +505,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ldcl" => "__builtin_arm_ldcl", "mcr" => "__builtin_arm_mcr", "mcr2" => "__builtin_arm_mcr2", - "mcrr" => "__builtin_arm_mcrr", - "mcrr2" => "__builtin_arm_mcrr2", "mrc" => "__builtin_arm_mrc", "mrc2" => "__builtin_arm_mrc2", "qadd" => "__builtin_arm_qadd", @@ -599,7 +561,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "stcl" => "__builtin_arm_stcl", "sxtab16" => "__builtin_arm_sxtab16", "sxtb16" => "__builtin_arm_sxtb16", - "thread.pointer" => "__builtin_thread_pointer", "uadd16" => "__builtin_arm_uadd16", "uadd8" => "__builtin_arm_uadd8", "uasx" => "__builtin_arm_uasx", @@ -650,16 +611,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } bpf(name, full_name) } - "cuda" => { - fn cuda(name: &str, full_name: &str) -> &'static str { - match name { - // cuda - "syncthreads" => "__syncthreads", - _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), - } - } - cuda(name, full_name) - } "hexagon" => { fn hexagon(name: &str, full_name: &str) -> &'static str { match name { @@ -963,19 +914,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "F2.dfcmpge" => "__builtin_HEXAGON_F2_dfcmpge", "F2.dfcmpgt" => "__builtin_HEXAGON_F2_dfcmpgt", "F2.dfcmpuo" => "__builtin_HEXAGON_F2_dfcmpuo", - "F2.dffixupd" => "__builtin_HEXAGON_F2_dffixupd", - "F2.dffixupn" => "__builtin_HEXAGON_F2_dffixupn", - "F2.dffixupr" => "__builtin_HEXAGON_F2_dffixupr", - "F2.dffma" => "__builtin_HEXAGON_F2_dffma", - "F2.dffma.lib" => "__builtin_HEXAGON_F2_dffma_lib", - "F2.dffma.sc" => "__builtin_HEXAGON_F2_dffma_sc", - "F2.dffms" => "__builtin_HEXAGON_F2_dffms", - "F2.dffms.lib" => "__builtin_HEXAGON_F2_dffms_lib", "F2.dfimm.n" => "__builtin_HEXAGON_F2_dfimm_n", "F2.dfimm.p" => "__builtin_HEXAGON_F2_dfimm_p", "F2.dfmax" => "__builtin_HEXAGON_F2_dfmax", "F2.dfmin" => "__builtin_HEXAGON_F2_dfmin", - "F2.dfmpy" => "__builtin_HEXAGON_F2_dfmpy", "F2.dfmpyfix" => "__builtin_HEXAGON_F2_dfmpyfix", "F2.dfmpyhh" => "__builtin_HEXAGON_F2_dfmpyhh", "F2.dfmpylh" => "__builtin_HEXAGON_F2_dfmpylh", @@ -1402,7 +1344,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "S2.asr.r.vw" => "__builtin_HEXAGON_S2_asr_r_vw", "S2.brev" => "__builtin_HEXAGON_S2_brev", "S2.brevp" => "__builtin_HEXAGON_S2_brevp", - "S2.cabacencbin" => "__builtin_HEXAGON_S2_cabacencbin", "S2.cl0" => "__builtin_HEXAGON_S2_cl0", "S2.cl0p" => "__builtin_HEXAGON_S2_cl0p", "S2.cl1" => "__builtin_HEXAGON_S2_cl1", @@ -1573,7 +1514,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "S6.vsplatrbp" => "__builtin_HEXAGON_S6_vsplatrbp", "S6.vtrunehb.ppp" => "__builtin_HEXAGON_S6_vtrunehb_ppp", "S6.vtrunohb.ppp" => "__builtin_HEXAGON_S6_vtrunohb_ppp", - "SI.to.SXTHI.asrh" => "__builtin_SI_to_SXTHI_asrh", "V6.extractw" => "__builtin_HEXAGON_V6_extractw", "V6.extractw.128B" => "__builtin_HEXAGON_V6_extractw_128B", "V6.get.qfext" => "__builtin_HEXAGON_V6_get_qfext", @@ -1632,6 +1572,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vabs.f8.128B" => "__builtin_HEXAGON_V6_vabs_f8_128B", "V6.vabs.hf" => "__builtin_HEXAGON_V6_vabs_hf", "V6.vabs.hf.128B" => "__builtin_HEXAGON_V6_vabs_hf_128B", + "V6.vabs.qf16.hf" => "__builtin_HEXAGON_V6_vabs_qf16_hf", + "V6.vabs.qf16.hf.128B" => "__builtin_HEXAGON_V6_vabs_qf16_hf_128B", + "V6.vabs.qf16.qf16" => "__builtin_HEXAGON_V6_vabs_qf16_qf16", + "V6.vabs.qf16.qf16.128B" => "__builtin_HEXAGON_V6_vabs_qf16_qf16_128B", + "V6.vabs.qf32.qf32" => "__builtin_HEXAGON_V6_vabs_qf32_qf32", + "V6.vabs.qf32.qf32.128B" => "__builtin_HEXAGON_V6_vabs_qf32_qf32_128B", + "V6.vabs.qf32.sf" => "__builtin_HEXAGON_V6_vabs_qf32_sf", + "V6.vabs.qf32.sf.128B" => "__builtin_HEXAGON_V6_vabs_qf32_sf_128B", "V6.vabs.sf" => "__builtin_HEXAGON_V6_vabs_sf", "V6.vabs.sf.128B" => "__builtin_HEXAGON_V6_vabs_sf_128B", "V6.vabsb" => "__builtin_HEXAGON_V6_vabsb", @@ -1744,6 +1692,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vaddwsat.128B" => "__builtin_HEXAGON_V6_vaddwsat_128B", "V6.vaddwsat.dv" => "__builtin_HEXAGON_V6_vaddwsat_dv", "V6.vaddwsat.dv.128B" => "__builtin_HEXAGON_V6_vaddwsat_dv_128B", + "V6.valign4" => "__builtin_HEXAGON_V6_valign4", + "V6.valign4.128B" => "__builtin_HEXAGON_V6_valign4_128B", "V6.valignb" => "__builtin_HEXAGON_V6_valignb", "V6.valignb.128B" => "__builtin_HEXAGON_V6_valignb_128B", "V6.valignbi" => "__builtin_HEXAGON_V6_valignbi", @@ -1862,14 +1812,30 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vcl0w.128B" => "__builtin_HEXAGON_V6_vcl0w_128B", "V6.vcombine" => "__builtin_HEXAGON_V6_vcombine", "V6.vcombine.128B" => "__builtin_HEXAGON_V6_vcombine_128B", + "V6.vconv.bf.qf32" => "__builtin_HEXAGON_V6_vconv_bf_qf32", + "V6.vconv.bf.qf32.128B" => "__builtin_HEXAGON_V6_vconv_bf_qf32_128B", + "V6.vconv.f8.qf16" => "__builtin_HEXAGON_V6_vconv_f8_qf16", + "V6.vconv.f8.qf16.128B" => "__builtin_HEXAGON_V6_vconv_f8_qf16_128B", "V6.vconv.h.hf" => "__builtin_HEXAGON_V6_vconv_h_hf", "V6.vconv.h.hf.128B" => "__builtin_HEXAGON_V6_vconv_h_hf_128B", + "V6.vconv.h.hf.rnd" => "__builtin_HEXAGON_V6_vconv_h_hf_rnd", + "V6.vconv.h.hf.rnd.128B" => "__builtin_HEXAGON_V6_vconv_h_hf_rnd_128B", "V6.vconv.hf.h" => "__builtin_HEXAGON_V6_vconv_hf_h", "V6.vconv.hf.h.128B" => "__builtin_HEXAGON_V6_vconv_hf_h_128B", "V6.vconv.hf.qf16" => "__builtin_HEXAGON_V6_vconv_hf_qf16", "V6.vconv.hf.qf16.128B" => "__builtin_HEXAGON_V6_vconv_hf_qf16_128B", "V6.vconv.hf.qf32" => "__builtin_HEXAGON_V6_vconv_hf_qf32", "V6.vconv.hf.qf32.128B" => "__builtin_HEXAGON_V6_vconv_hf_qf32_128B", + "V6.vconv.qf16.f8" => "__builtin_HEXAGON_V6_vconv_qf16_f8", + "V6.vconv.qf16.f8.128B" => "__builtin_HEXAGON_V6_vconv_qf16_f8_128B", + "V6.vconv.qf16.hf" => "__builtin_HEXAGON_V6_vconv_qf16_hf", + "V6.vconv.qf16.hf.128B" => "__builtin_HEXAGON_V6_vconv_qf16_hf_128B", + "V6.vconv.qf16.qf16" => "__builtin_HEXAGON_V6_vconv_qf16_qf16", + "V6.vconv.qf16.qf16.128B" => "__builtin_HEXAGON_V6_vconv_qf16_qf16_128B", + "V6.vconv.qf32.qf32" => "__builtin_HEXAGON_V6_vconv_qf32_qf32", + "V6.vconv.qf32.qf32.128B" => "__builtin_HEXAGON_V6_vconv_qf32_qf32_128B", + "V6.vconv.qf32.sf" => "__builtin_HEXAGON_V6_vconv_qf32_sf", + "V6.vconv.qf32.sf.128B" => "__builtin_HEXAGON_V6_vconv_qf32_sf_128B", "V6.vconv.sf.qf32" => "__builtin_HEXAGON_V6_vconv_sf_qf32", "V6.vconv.sf.qf32.128B" => "__builtin_HEXAGON_V6_vconv_sf_qf32_128B", "V6.vconv.sf.w" => "__builtin_HEXAGON_V6_vconv_sf_w", @@ -1984,6 +1950,22 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.veqh.or.128B" => "__builtin_HEXAGON_V6_veqh_or_128B", "V6.veqh.xor" => "__builtin_HEXAGON_V6_veqh_xor", "V6.veqh.xor.128B" => "__builtin_HEXAGON_V6_veqh_xor_128B", + "V6.veqhf" => "__builtin_HEXAGON_V6_veqhf", + "V6.veqhf.128B" => "__builtin_HEXAGON_V6_veqhf_128B", + "V6.veqhf.and" => "__builtin_HEXAGON_V6_veqhf_and", + "V6.veqhf.and.128B" => "__builtin_HEXAGON_V6_veqhf_and_128B", + "V6.veqhf.or" => "__builtin_HEXAGON_V6_veqhf_or", + "V6.veqhf.or.128B" => "__builtin_HEXAGON_V6_veqhf_or_128B", + "V6.veqhf.xor" => "__builtin_HEXAGON_V6_veqhf_xor", + "V6.veqhf.xor.128B" => "__builtin_HEXAGON_V6_veqhf_xor_128B", + "V6.veqsf" => "__builtin_HEXAGON_V6_veqsf", + "V6.veqsf.128B" => "__builtin_HEXAGON_V6_veqsf_128B", + "V6.veqsf.and" => "__builtin_HEXAGON_V6_veqsf_and", + "V6.veqsf.and.128B" => "__builtin_HEXAGON_V6_veqsf_and_128B", + "V6.veqsf.or" => "__builtin_HEXAGON_V6_veqsf_or", + "V6.veqsf.or.128B" => "__builtin_HEXAGON_V6_veqsf_or_128B", + "V6.veqsf.xor" => "__builtin_HEXAGON_V6_veqsf_xor", + "V6.veqsf.xor.128B" => "__builtin_HEXAGON_V6_veqsf_xor_128B", "V6.veqw" => "__builtin_HEXAGON_V6_veqw", "V6.veqw.128B" => "__builtin_HEXAGON_V6_veqw_128B", "V6.veqw.and" => "__builtin_HEXAGON_V6_veqw_and", @@ -2096,6 +2078,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vgtw.or.128B" => "__builtin_HEXAGON_V6_vgtw_or_128B", "V6.vgtw.xor" => "__builtin_HEXAGON_V6_vgtw_xor", "V6.vgtw.xor.128B" => "__builtin_HEXAGON_V6_vgtw_xor_128B", + "V6.vilog2.hf" => "__builtin_HEXAGON_V6_vilog2_hf", + "V6.vilog2.hf.128B" => "__builtin_HEXAGON_V6_vilog2_hf_128B", + "V6.vilog2.qf16" => "__builtin_HEXAGON_V6_vilog2_qf16", + "V6.vilog2.qf16.128B" => "__builtin_HEXAGON_V6_vilog2_qf16_128B", + "V6.vilog2.qf32" => "__builtin_HEXAGON_V6_vilog2_qf32", + "V6.vilog2.qf32.128B" => "__builtin_HEXAGON_V6_vilog2_qf32_128B", + "V6.vilog2.sf" => "__builtin_HEXAGON_V6_vilog2_sf", + "V6.vilog2.sf.128B" => "__builtin_HEXAGON_V6_vilog2_sf_128B", "V6.vinsertwr" => "__builtin_HEXAGON_V6_vinsertwr", "V6.vinsertwr.128B" => "__builtin_HEXAGON_V6_vinsertwr_128B", "V6.vlalignb" => "__builtin_HEXAGON_V6_vlalignb", @@ -2114,14 +2104,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vlsrwv.128B" => "__builtin_HEXAGON_V6_vlsrwv_128B", "V6.vlut4" => "__builtin_HEXAGON_V6_vlut4", "V6.vlut4.128B" => "__builtin_HEXAGON_V6_vlut4_128B", - "V6.vlutb" => "__builtin_HEXAGON_V6_vlutb", - "V6.vlutb.128B" => "__builtin_HEXAGON_V6_vlutb_128B", - "V6.vlutb.acc" => "__builtin_HEXAGON_V6_vlutb_acc", - "V6.vlutb.acc.128B" => "__builtin_HEXAGON_V6_vlutb_acc_128B", - "V6.vlutb.dv" => "__builtin_HEXAGON_V6_vlutb_dv", - "V6.vlutb.dv.128B" => "__builtin_HEXAGON_V6_vlutb_dv_128B", - "V6.vlutb.dv.acc" => "__builtin_HEXAGON_V6_vlutb_dv_acc", - "V6.vlutb.dv.acc.128B" => "__builtin_HEXAGON_V6_vlutb_dv_acc_128B", "V6.vlutvvb" => "__builtin_HEXAGON_V6_vlutvvb", "V6.vlutvvb.128B" => "__builtin_HEXAGON_V6_vlutvvb_128B", "V6.vlutvvb.nm" => "__builtin_HEXAGON_V6_vlutvvb_nm", @@ -2350,6 +2332,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "V6.vnavgub.128B" => "__builtin_HEXAGON_V6_vnavgub_128B", "V6.vnavgw" => "__builtin_HEXAGON_V6_vnavgw", "V6.vnavgw.128B" => "__builtin_HEXAGON_V6_vnavgw_128B", + "V6.vneg.qf16.hf" => "__builtin_HEXAGON_V6_vneg_qf16_hf", + "V6.vneg.qf16.hf.128B" => "__builtin_HEXAGON_V6_vneg_qf16_hf_128B", + "V6.vneg.qf16.qf16" => "__builtin_HEXAGON_V6_vneg_qf16_qf16", + "V6.vneg.qf16.qf16.128B" => "__builtin_HEXAGON_V6_vneg_qf16_qf16_128B", + "V6.vneg.qf32.qf32" => "__builtin_HEXAGON_V6_vneg_qf32_qf32", + "V6.vneg.qf32.qf32.128B" => "__builtin_HEXAGON_V6_vneg_qf32_qf32_128B", + "V6.vneg.qf32.sf" => "__builtin_HEXAGON_V6_vneg_qf32_sf", + "V6.vneg.qf32.sf.128B" => "__builtin_HEXAGON_V6_vneg_qf32_sf_128B", "V6.vnormamth" => "__builtin_HEXAGON_V6_vnormamth", "V6.vnormamth.128B" => "__builtin_HEXAGON_V6_vnormamth_128B", "V6.vnormamtw" => "__builtin_HEXAGON_V6_vnormamtw", @@ -2615,17 +2605,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "Y6.dmresume" => "__builtin_HEXAGON_Y6_dmresume", "Y6.dmstart" => "__builtin_HEXAGON_Y6_dmstart", "Y6.dmwait" => "__builtin_HEXAGON_Y6_dmwait", - "brev.ldb" => "__builtin_brev_ldb", - "brev.ldd" => "__builtin_brev_ldd", - "brev.ldh" => "__builtin_brev_ldh", - "brev.ldub" => "__builtin_brev_ldub", - "brev.lduh" => "__builtin_brev_lduh", - "brev.ldw" => "__builtin_brev_ldw", - "brev.stb" => "__builtin_brev_stb", - "brev.std" => "__builtin_brev_std", - "brev.sth" => "__builtin_brev_sth", - "brev.sthhi" => "__builtin_brev_sthhi", - "brev.stw" => "__builtin_brev_stw", "circ.ldb" => "__builtin_circ_ldb", "circ.ldd" => "__builtin_circ_ldd", "circ.ldh" => "__builtin_circ_ldh", @@ -2637,7 +2616,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "circ.sth" => "__builtin_circ_sth", "circ.sthhi" => "__builtin_circ_sthhi", "circ.stw" => "__builtin_circ_stw", - "mm256i.vaddw" => "__builtin__mm256i_vaddw", "prefetch" => "__builtin_HEXAGON_prefetch", "vmemcpy" => "__builtin_hexagon_vmemcpy", "vmemset" => "__builtin_hexagon_vmemset", @@ -2684,6 +2662,24 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "iocsrwr.d" => "__builtin_loongarch_iocsrwr_d", "iocsrwr.h" => "__builtin_loongarch_iocsrwr_h", "iocsrwr.w" => "__builtin_loongarch_iocsrwr_w", + "lasx.cast.128" => "__builtin_lasx_cast_128", + "lasx.cast.128.d" => "__builtin_lasx_cast_128_d", + "lasx.cast.128.s" => "__builtin_lasx_cast_128_s", + "lasx.concat.128" => "__builtin_lasx_concat_128", + "lasx.concat.128.d" => "__builtin_lasx_concat_128_d", + "lasx.concat.128.s" => "__builtin_lasx_concat_128_s", + "lasx.extract.128.hi" => "__builtin_lasx_extract_128_hi", + "lasx.extract.128.hi.d" => "__builtin_lasx_extract_128_hi_d", + "lasx.extract.128.hi.s" => "__builtin_lasx_extract_128_hi_s", + "lasx.extract.128.lo" => "__builtin_lasx_extract_128_lo", + "lasx.extract.128.lo.d" => "__builtin_lasx_extract_128_lo_d", + "lasx.extract.128.lo.s" => "__builtin_lasx_extract_128_lo_s", + "lasx.insert.128.hi" => "__builtin_lasx_insert_128_hi", + "lasx.insert.128.hi.d" => "__builtin_lasx_insert_128_hi_d", + "lasx.insert.128.hi.s" => "__builtin_lasx_insert_128_hi_s", + "lasx.insert.128.lo" => "__builtin_lasx_insert_128_lo", + "lasx.insert.128.lo.d" => "__builtin_lasx_insert_128_lo_d", + "lasx.insert.128.lo.s" => "__builtin_lasx_insert_128_lo_s", "lasx.vext2xv.d.b" => "__builtin_lasx_vext2xv_d_b", "lasx.vext2xv.d.h" => "__builtin_lasx_vext2xv_d_h", "lasx.vext2xv.d.w" => "__builtin_lasx_vext2xv_d_w", @@ -4838,45 +4834,37 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { fn nvvm(name: &str, full_name: &str) -> &'static str { match name { // nvvm - "abs.i" => "__nvvm_abs_i", - "abs.ll" => "__nvvm_abs_ll", "activemask" => "__nvvm_activemask", "add.rm.d" => "__nvvm_add_rm_d", "add.rm.f" => "__nvvm_add_rm_f", "add.rm.ftz.f" => "__nvvm_add_rm_ftz_f", + "add.rm.ftz.sat.f" => "__nvvm_add_rm_ftz_sat_f", + "add.rm.sat.f" => "__nvvm_add_rm_sat_f", "add.rn.d" => "__nvvm_add_rn_d", "add.rn.f" => "__nvvm_add_rn_f", "add.rn.ftz.f" => "__nvvm_add_rn_ftz_f", + "add.rn.ftz.sat.f" => "__nvvm_add_rn_ftz_sat_f", + "add.rn.sat.f" => "__nvvm_add_rn_sat_f", "add.rp.d" => "__nvvm_add_rp_d", "add.rp.f" => "__nvvm_add_rp_f", "add.rp.ftz.f" => "__nvvm_add_rp_ftz_f", + "add.rp.ftz.sat.f" => "__nvvm_add_rp_ftz_sat_f", + "add.rp.sat.f" => "__nvvm_add_rp_sat_f", "add.rz.d" => "__nvvm_add_rz_d", "add.rz.f" => "__nvvm_add_rz_f", "add.rz.ftz.f" => "__nvvm_add_rz_ftz_f", - "bar.sync" => "__nvvm_bar_sync", + "add.rz.ftz.sat.f" => "__nvvm_add_rz_ftz_sat_f", + "add.rz.sat.f" => "__nvvm_add_rz_sat_f", "bar.warp.sync" => "__nvvm_bar_warp_sync", - "barrier0" => "__nvvm_bar0", - // [DUPLICATE]: "barrier0" => "__syncthreads", - "barrier0.and" => "__nvvm_bar0_and", - "barrier0.or" => "__nvvm_bar0_or", - "barrier0.popc" => "__nvvm_bar0_popc", "bf16x2.to.ue8m0x2.rp" => "__nvvm_bf16x2_to_ue8m0x2_rp", "bf16x2.to.ue8m0x2.rp.satfinite" => "__nvvm_bf16x2_to_ue8m0x2_rp_satfinite", "bf16x2.to.ue8m0x2.rz" => "__nvvm_bf16x2_to_ue8m0x2_rz", "bf16x2.to.ue8m0x2.rz.satfinite" => "__nvvm_bf16x2_to_ue8m0x2_rz_satfinite", "bf2h.rn" => "__nvvm_bf2h_rn", "bf2h.rn.ftz" => "__nvvm_bf2h_rn_ftz", - "bitcast.d2ll" => "__nvvm_bitcast_d2ll", - "bitcast.f2i" => "__nvvm_bitcast_f2i", - "bitcast.i2f" => "__nvvm_bitcast_i2f", - "bitcast.ll2d" => "__nvvm_bitcast_ll2d", - "brev32" => "__nvvm_brev32", - "brev64" => "__nvvm_brev64", "ceil.d" => "__nvvm_ceil_d", "ceil.f" => "__nvvm_ceil_f", "ceil.ftz.f" => "__nvvm_ceil_ftz_f", - "clz.i" => "__nvvm_clz_i", - "clz.ll" => "__nvvm_clz_ll", "cos.approx.f" => "__nvvm_cos_approx_f", "cos.approx.ftz.f" => "__nvvm_cos_approx_ftz_f", "cp.async.commit.group" => "__nvvm_cp_async_commit_group", @@ -4940,9 +4928,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "e4m3x2.to.f16x2.rn.relu" => "__nvvm_e4m3x2_to_f16x2_rn_relu", "e5m2x2.to.f16x2.rn" => "__nvvm_e5m2x2_to_f16x2_rn", "e5m2x2.to.f16x2.rn.relu" => "__nvvm_e5m2x2_to_f16x2_rn_relu", - "ex2.approx.d" => "__nvvm_ex2_approx_d", - "ex2.approx.f" => "__nvvm_ex2_approx_f", - "ex2.approx.ftz.f" => "__nvvm_ex2_approx_ftz_f", "exit" => "__nvvm_exit", "f16x2.to.e4m3x2.rn" => "__nvvm_f16x2_to_e4m3x2_rn", "f16x2.to.e4m3x2.rn.relu" => "__nvvm_f16x2_to_e4m3x2_rn_relu", @@ -4950,8 +4935,20 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "f16x2.to.e5m2x2.rn.relu" => "__nvvm_f16x2_to_e5m2x2_rn_relu", "f2bf16.rn" => "__nvvm_f2bf16_rn", "f2bf16.rn.relu" => "__nvvm_f2bf16_rn_relu", + "f2bf16.rn.relu.satfinite" => "__nvvm_f2bf16_rn_relu_satfinite", + "f2bf16.rn.satfinite" => "__nvvm_f2bf16_rn_satfinite", "f2bf16.rz" => "__nvvm_f2bf16_rz", "f2bf16.rz.relu" => "__nvvm_f2bf16_rz_relu", + "f2bf16.rz.relu.satfinite" => "__nvvm_f2bf16_rz_relu_satfinite", + "f2bf16.rz.satfinite" => "__nvvm_f2bf16_rz_satfinite", + "f2f16.rn" => "__nvvm_f2f16_rn", + "f2f16.rn.relu" => "__nvvm_f2f16_rn_relu", + "f2f16.rn.relu.satfinite" => "__nvvm_f2f16_rn_relu_satfinite", + "f2f16.rn.satfinite" => "__nvvm_f2f16_rn_satfinite", + "f2f16.rz" => "__nvvm_f2f16_rz", + "f2f16.rz.relu" => "__nvvm_f2f16_rz_relu", + "f2f16.rz.relu.satfinite" => "__nvvm_f2f16_rz_relu_satfinite", + "f2f16.rz.satfinite" => "__nvvm_f2f16_rz_satfinite", "f2h.rn" => "__nvvm_f2h_rn", "f2h.rn.ftz" => "__nvvm_f2h_rn_ftz", "f2i.rm" => "__nvvm_f2i_rm", @@ -5016,9 +5013,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "__nvvm_f32x4_to_e5m2x4_rs_relu_satfinite" } "f32x4.to.e5m2x4.rs.satfinite" => "__nvvm_f32x4_to_e5m2x4_rs_satfinite", - "fabs.d" => "__nvvm_fabs_d", - "fabs.f" => "__nvvm_fabs_f", - "fabs.ftz.f" => "__nvvm_fabs_ftz_f", "ff.to.e2m1x2.rn.relu.satfinite" => "__nvvm_ff_to_e2m1x2_rn_relu_satfinite", "ff.to.e2m1x2.rn.satfinite" => "__nvvm_ff_to_e2m1x2_rn_satfinite", "ff.to.e2m3x2.rn.relu.satfinite" => "__nvvm_ff_to_e2m3x2_rn_relu_satfinite", @@ -5035,26 +5029,36 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ff.to.ue8m0x2.rz.satfinite" => "__nvvm_ff_to_ue8m0x2_rz_satfinite", "ff2bf16x2.rn" => "__nvvm_ff2bf16x2_rn", "ff2bf16x2.rn.relu" => "__nvvm_ff2bf16x2_rn_relu", + "ff2bf16x2.rn.relu.satfinite" => "__nvvm_ff2bf16x2_rn_relu_satfinite", + "ff2bf16x2.rn.satfinite" => "__nvvm_ff2bf16x2_rn_satfinite", "ff2bf16x2.rs" => "__nvvm_ff2bf16x2_rs", "ff2bf16x2.rs.relu" => "__nvvm_ff2bf16x2_rs_relu", "ff2bf16x2.rs.relu.satfinite" => "__nvvm_ff2bf16x2_rs_relu_satfinite", "ff2bf16x2.rs.satfinite" => "__nvvm_ff2bf16x2_rs_satfinite", "ff2bf16x2.rz" => "__nvvm_ff2bf16x2_rz", "ff2bf16x2.rz.relu" => "__nvvm_ff2bf16x2_rz_relu", + "ff2bf16x2.rz.relu.satfinite" => "__nvvm_ff2bf16x2_rz_relu_satfinite", + "ff2bf16x2.rz.satfinite" => "__nvvm_ff2bf16x2_rz_satfinite", "ff2f16x2.rn" => "__nvvm_ff2f16x2_rn", "ff2f16x2.rn.relu" => "__nvvm_ff2f16x2_rn_relu", + "ff2f16x2.rn.relu.satfinite" => "__nvvm_ff2f16x2_rn_relu_satfinite", + "ff2f16x2.rn.satfinite" => "__nvvm_ff2f16x2_rn_satfinite", "ff2f16x2.rs" => "__nvvm_ff2f16x2_rs", "ff2f16x2.rs.relu" => "__nvvm_ff2f16x2_rs_relu", "ff2f16x2.rs.relu.satfinite" => "__nvvm_ff2f16x2_rs_relu_satfinite", "ff2f16x2.rs.satfinite" => "__nvvm_ff2f16x2_rs_satfinite", "ff2f16x2.rz" => "__nvvm_ff2f16x2_rz", "ff2f16x2.rz.relu" => "__nvvm_ff2f16x2_rz_relu", + "ff2f16x2.rz.relu.satfinite" => "__nvvm_ff2f16x2_rz_relu_satfinite", + "ff2f16x2.rz.satfinite" => "__nvvm_ff2f16x2_rz_satfinite", "floor.d" => "__nvvm_floor_d", "floor.f" => "__nvvm_floor_f", "floor.ftz.f" => "__nvvm_floor_ftz_f", "fma.rm.d" => "__nvvm_fma_rm_d", "fma.rm.f" => "__nvvm_fma_rm_f", "fma.rm.ftz.f" => "__nvvm_fma_rm_ftz_f", + "fma.rm.ftz.sat.f" => "__nvvm_fma_rm_ftz_sat_f", + "fma.rm.sat.f" => "__nvvm_fma_rm_sat_f", "fma.rn.bf16" => "__nvvm_fma_rn_bf16", "fma.rn.bf16x2" => "__nvvm_fma_rn_bf16x2", "fma.rn.d" => "__nvvm_fma_rn_d", @@ -5066,16 +5070,22 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "fma.rn.ftz.relu.bf16x2" => "__nvvm_fma_rn_ftz_relu_bf16x2", "fma.rn.ftz.sat.bf16" => "__nvvm_fma_rn_ftz_sat_bf16", "fma.rn.ftz.sat.bf16x2" => "__nvvm_fma_rn_ftz_sat_bf16x2", + "fma.rn.ftz.sat.f" => "__nvvm_fma_rn_ftz_sat_f", "fma.rn.relu.bf16" => "__nvvm_fma_rn_relu_bf16", "fma.rn.relu.bf16x2" => "__nvvm_fma_rn_relu_bf16x2", "fma.rn.sat.bf16" => "__nvvm_fma_rn_sat_bf16", "fma.rn.sat.bf16x2" => "__nvvm_fma_rn_sat_bf16x2", + "fma.rn.sat.f" => "__nvvm_fma_rn_sat_f", "fma.rp.d" => "__nvvm_fma_rp_d", "fma.rp.f" => "__nvvm_fma_rp_f", "fma.rp.ftz.f" => "__nvvm_fma_rp_ftz_f", + "fma.rp.ftz.sat.f" => "__nvvm_fma_rp_ftz_sat_f", + "fma.rp.sat.f" => "__nvvm_fma_rp_sat_f", "fma.rz.d" => "__nvvm_fma_rz_d", "fma.rz.f" => "__nvvm_fma_rz_f", "fma.rz.ftz.f" => "__nvvm_fma_rz_ftz_f", + "fma.rz.ftz.sat.f" => "__nvvm_fma_rz_ftz_sat_f", + "fma.rz.sat.f" => "__nvvm_fma_rz_sat_f", "fmax.bf16" => "__nvvm_fmax_bf16", "fmax.bf16x2" => "__nvvm_fmax_bf16x2", "fmax.d" => "__nvvm_fmax_d", @@ -5127,7 +5137,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "fmin.xorsign.abs.bf16x2" => "__nvvm_fmin_xorsign_abs_bf16x2", "fmin.xorsign.abs.f" => "__nvvm_fmin_xorsign_abs_f", "fns" => "__nvvm_fns", - "h2f" => "__nvvm_h2f", "i2d.rm" => "__nvvm_i2d_rm", "i2d.rn" => "__nvvm_i2d_rn", "i2d.rp" => "__nvvm_i2d_rp", @@ -5158,10 +5167,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "lohi.i2d" => "__nvvm_lohi_i2d", "match.any.sync.i32" => "__nvvm_match_any_sync_i32", "match.any.sync.i64" => "__nvvm_match_any_sync_i64", - "max.i" => "__nvvm_max_i", - "max.ll" => "__nvvm_max_ll", - "max.ui" => "__nvvm_max_ui", - "max.ull" => "__nvvm_max_ull", "mbarrier.arrive" => "__nvvm_mbarrier_arrive", "mbarrier.arrive.drop" => "__nvvm_mbarrier_arrive_drop", "mbarrier.arrive.drop.noComplete" => "__nvvm_mbarrier_arrive_drop_noComplete", @@ -5184,10 +5189,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "membar.cta" => "__nvvm_membar_cta", "membar.gl" => "__nvvm_membar_gl", "membar.sys" => "__nvvm_membar_sys", - "min.i" => "__nvvm_min_i", - "min.ll" => "__nvvm_min_ll", - "min.ui" => "__nvvm_min_ui", - "min.ull" => "__nvvm_min_ull", "mul.rm.d" => "__nvvm_mul_rm_d", "mul.rm.f" => "__nvvm_mul_rm_f", "mul.rm.ftz.f" => "__nvvm_mul_rm_ftz_f", @@ -5212,8 +5213,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "neg.bf16" => "__nvvm_neg_bf16", "neg.bf16x2" => "__nvvm_neg_bf16x2", "pm.event.mask" => "__nvvm_pm_event_mask", - "popc.i" => "__nvvm_popc_i", - "popc.ll" => "__nvvm_popc_ll", "prmt" => "__nvvm_prmt", "rcp.approx.ftz.d" => "__nvvm_rcp_approx_ftz_d", "rcp.approx.ftz.f" => "__nvvm_rcp_approx_ftz_f", @@ -5230,9 +5229,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "rcp.rz.f" => "__nvvm_rcp_rz_f", "rcp.rz.ftz.f" => "__nvvm_rcp_rz_ftz_f", "read.ptx.sreg.clock" => "__nvvm_read_ptx_sreg_clock", - // [DUPLICATE]: "read.ptx.sreg.clock" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.clock64" => "__nvvm_read_ptx_sreg_clock64", - // [DUPLICATE]: "read.ptx.sreg.clock64" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.ctaid.w" => "__nvvm_read_ptx_sreg_ctaid_w", "read.ptx.sreg.ctaid.x" => "__nvvm_read_ptx_sreg_ctaid_x", "read.ptx.sreg.ctaid.y" => "__nvvm_read_ptx_sreg_ctaid_y", @@ -5272,49 +5269,34 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "read.ptx.sreg.globaltimer" => "__nvvm_read_ptx_sreg_globaltimer", "read.ptx.sreg.globaltimer.lo" => "__nvvm_read_ptx_sreg_globaltimer_lo", "read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_gridid", - // [DUPLICATE]: "read.ptx.sreg.gridid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.laneid" => "__nvvm_read_ptx_sreg_laneid", - // [DUPLICATE]: "read.ptx.sreg.laneid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.eq" => "__nvvm_read_ptx_sreg_lanemask_eq", - // [DUPLICATE]: "read.ptx.sreg.lanemask.eq" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.ge" => "__nvvm_read_ptx_sreg_lanemask_ge", - // [DUPLICATE]: "read.ptx.sreg.lanemask.ge" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.gt" => "__nvvm_read_ptx_sreg_lanemask_gt", - // [DUPLICATE]: "read.ptx.sreg.lanemask.gt" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.le" => "__nvvm_read_ptx_sreg_lanemask_le", - // [DUPLICATE]: "read.ptx.sreg.lanemask.le" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.lanemask.lt" => "__nvvm_read_ptx_sreg_lanemask_lt", - // [DUPLICATE]: "read.ptx.sreg.lanemask.lt" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.nctaid.w" => "__nvvm_read_ptx_sreg_nctaid_w", "read.ptx.sreg.nctaid.x" => "__nvvm_read_ptx_sreg_nctaid_x", "read.ptx.sreg.nctaid.y" => "__nvvm_read_ptx_sreg_nctaid_y", "read.ptx.sreg.nctaid.z" => "__nvvm_read_ptx_sreg_nctaid_z", "read.ptx.sreg.nsmid" => "__nvvm_read_ptx_sreg_nsmid", - // [DUPLICATE]: "read.ptx.sreg.nsmid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.ntid.w" => "__nvvm_read_ptx_sreg_ntid_w", "read.ptx.sreg.ntid.x" => "__nvvm_read_ptx_sreg_ntid_x", "read.ptx.sreg.ntid.y" => "__nvvm_read_ptx_sreg_ntid_y", "read.ptx.sreg.ntid.z" => "__nvvm_read_ptx_sreg_ntid_z", "read.ptx.sreg.nwarpid" => "__nvvm_read_ptx_sreg_nwarpid", - // [DUPLICATE]: "read.ptx.sreg.nwarpid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm0" => "__nvvm_read_ptx_sreg_pm0", - // [DUPLICATE]: "read.ptx.sreg.pm0" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm1" => "__nvvm_read_ptx_sreg_pm1", - // [DUPLICATE]: "read.ptx.sreg.pm1" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm2" => "__nvvm_read_ptx_sreg_pm2", - // [DUPLICATE]: "read.ptx.sreg.pm2" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.pm3" => "__nvvm_read_ptx_sreg_pm3", - // [DUPLICATE]: "read.ptx.sreg.pm3" => "__nvvm_read_ptx_sreg_", + "read.ptx.sreg.pm4" => "__nvvm_read_ptx_sreg_pm4", "read.ptx.sreg.smid" => "__nvvm_read_ptx_sreg_smid", - // [DUPLICATE]: "read.ptx.sreg.smid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.tid.w" => "__nvvm_read_ptx_sreg_tid_w", "read.ptx.sreg.tid.x" => "__nvvm_read_ptx_sreg_tid_x", "read.ptx.sreg.tid.y" => "__nvvm_read_ptx_sreg_tid_y", "read.ptx.sreg.tid.z" => "__nvvm_read_ptx_sreg_tid_z", "read.ptx.sreg.warpid" => "__nvvm_read_ptx_sreg_warpid", - // [DUPLICATE]: "read.ptx.sreg.warpid" => "__nvvm_read_ptx_sreg_", "read.ptx.sreg.warpsize" => "__nvvm_read_ptx_sreg_warpsize", - // [DUPLICATE]: "read.ptx.sreg.warpsize" => "__nvvm_read_ptx_sreg_", "redux.sync.add" => "__nvvm_redux_sync_add", "redux.sync.and" => "__nvvm_redux_sync_and", "redux.sync.fmax" => "__nvvm_redux_sync_fmax", @@ -5332,9 +5314,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "redux.sync.umin" => "__nvvm_redux_sync_umin", "redux.sync.xor" => "__nvvm_redux_sync_xor", "reflect" => "__nvvm_reflect", - "rotate.b32" => "__nvvm_rotate_b32", - "rotate.b64" => "__nvvm_rotate_b64", - "rotate.right.b64" => "__nvvm_rotate_right_b64", "round.d" => "__nvvm_round_d", "round.f" => "__nvvm_round_f", "round.ftz.f" => "__nvvm_round_ftz_f", @@ -5600,7 +5579,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sust.p.3d.v4i16.trap" => "__nvvm_sust_p_3d_v4i16_trap", "sust.p.3d.v4i32.trap" => "__nvvm_sust_p_3d_v4i32_trap", "sust.p.3d.v4i8.trap" => "__nvvm_sust_p_3d_v4i8_trap", - "swap.lo.hi.b64" => "__nvvm_swap_lo_hi_b64", "trunc.d" => "__nvvm_trunc_d", "trunc.f" => "__nvvm_trunc_f", "trunc.ftz.f" => "__nvvm_trunc_ftz_f", @@ -5942,6 +5920,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "altivec.vupklsb" => "__builtin_altivec_vupklsb", "altivec.vupklsh" => "__builtin_altivec_vupklsh", "altivec.vupklsw" => "__builtin_altivec_vupklsw", + "amo.ldat" => "__builtin_amo_ldat", + "amo.lwat" => "__builtin_amo_lwat", "bcdadd" => "__builtin_ppc_bcdadd", "bcdadd.p" => "__builtin_ppc_bcdadd_p", "bcdcopysign" => "__builtin_ppc_bcdcopysign", @@ -6038,89 +6018,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "packed2zoned" => "__builtin_ppc_packed2zoned", "pdepd" => "__builtin_pdepd", "pextd" => "__builtin_pextd", - "qpx.qvfabs" => "__builtin_qpx_qvfabs", - "qpx.qvfadd" => "__builtin_qpx_qvfadd", - "qpx.qvfadds" => "__builtin_qpx_qvfadds", - "qpx.qvfcfid" => "__builtin_qpx_qvfcfid", - "qpx.qvfcfids" => "__builtin_qpx_qvfcfids", - "qpx.qvfcfidu" => "__builtin_qpx_qvfcfidu", - "qpx.qvfcfidus" => "__builtin_qpx_qvfcfidus", - "qpx.qvfcmpeq" => "__builtin_qpx_qvfcmpeq", - "qpx.qvfcmpgt" => "__builtin_qpx_qvfcmpgt", - "qpx.qvfcmplt" => "__builtin_qpx_qvfcmplt", - "qpx.qvfcpsgn" => "__builtin_qpx_qvfcpsgn", - "qpx.qvfctid" => "__builtin_qpx_qvfctid", - "qpx.qvfctidu" => "__builtin_qpx_qvfctidu", - "qpx.qvfctiduz" => "__builtin_qpx_qvfctiduz", - "qpx.qvfctidz" => "__builtin_qpx_qvfctidz", - "qpx.qvfctiw" => "__builtin_qpx_qvfctiw", - "qpx.qvfctiwu" => "__builtin_qpx_qvfctiwu", - "qpx.qvfctiwuz" => "__builtin_qpx_qvfctiwuz", - "qpx.qvfctiwz" => "__builtin_qpx_qvfctiwz", - "qpx.qvflogical" => "__builtin_qpx_qvflogical", - "qpx.qvfmadd" => "__builtin_qpx_qvfmadd", - "qpx.qvfmadds" => "__builtin_qpx_qvfmadds", - "qpx.qvfmsub" => "__builtin_qpx_qvfmsub", - "qpx.qvfmsubs" => "__builtin_qpx_qvfmsubs", - "qpx.qvfmul" => "__builtin_qpx_qvfmul", - "qpx.qvfmuls" => "__builtin_qpx_qvfmuls", - "qpx.qvfnabs" => "__builtin_qpx_qvfnabs", - "qpx.qvfneg" => "__builtin_qpx_qvfneg", - "qpx.qvfnmadd" => "__builtin_qpx_qvfnmadd", - "qpx.qvfnmadds" => "__builtin_qpx_qvfnmadds", - "qpx.qvfnmsub" => "__builtin_qpx_qvfnmsub", - "qpx.qvfnmsubs" => "__builtin_qpx_qvfnmsubs", - "qpx.qvfperm" => "__builtin_qpx_qvfperm", - "qpx.qvfre" => "__builtin_qpx_qvfre", - "qpx.qvfres" => "__builtin_qpx_qvfres", - "qpx.qvfrim" => "__builtin_qpx_qvfrim", - "qpx.qvfrin" => "__builtin_qpx_qvfrin", - "qpx.qvfrip" => "__builtin_qpx_qvfrip", - "qpx.qvfriz" => "__builtin_qpx_qvfriz", - "qpx.qvfrsp" => "__builtin_qpx_qvfrsp", - "qpx.qvfrsqrte" => "__builtin_qpx_qvfrsqrte", - "qpx.qvfrsqrtes" => "__builtin_qpx_qvfrsqrtes", - "qpx.qvfsel" => "__builtin_qpx_qvfsel", - "qpx.qvfsub" => "__builtin_qpx_qvfsub", - "qpx.qvfsubs" => "__builtin_qpx_qvfsubs", - "qpx.qvftstnan" => "__builtin_qpx_qvftstnan", - "qpx.qvfxmadd" => "__builtin_qpx_qvfxmadd", - "qpx.qvfxmadds" => "__builtin_qpx_qvfxmadds", - "qpx.qvfxmul" => "__builtin_qpx_qvfxmul", - "qpx.qvfxmuls" => "__builtin_qpx_qvfxmuls", - "qpx.qvfxxcpnmadd" => "__builtin_qpx_qvfxxcpnmadd", - "qpx.qvfxxcpnmadds" => "__builtin_qpx_qvfxxcpnmadds", - "qpx.qvfxxmadd" => "__builtin_qpx_qvfxxmadd", - "qpx.qvfxxmadds" => "__builtin_qpx_qvfxxmadds", - "qpx.qvfxxnpmadd" => "__builtin_qpx_qvfxxnpmadd", - "qpx.qvfxxnpmadds" => "__builtin_qpx_qvfxxnpmadds", - "qpx.qvgpci" => "__builtin_qpx_qvgpci", - "qpx.qvlfcd" => "__builtin_qpx_qvlfcd", - "qpx.qvlfcda" => "__builtin_qpx_qvlfcda", - "qpx.qvlfcs" => "__builtin_qpx_qvlfcs", - "qpx.qvlfcsa" => "__builtin_qpx_qvlfcsa", - "qpx.qvlfd" => "__builtin_qpx_qvlfd", - "qpx.qvlfda" => "__builtin_qpx_qvlfda", - "qpx.qvlfiwa" => "__builtin_qpx_qvlfiwa", - "qpx.qvlfiwaa" => "__builtin_qpx_qvlfiwaa", - "qpx.qvlfiwz" => "__builtin_qpx_qvlfiwz", - "qpx.qvlfiwza" => "__builtin_qpx_qvlfiwza", - "qpx.qvlfs" => "__builtin_qpx_qvlfs", - "qpx.qvlfsa" => "__builtin_qpx_qvlfsa", - "qpx.qvlpcld" => "__builtin_qpx_qvlpcld", - "qpx.qvlpcls" => "__builtin_qpx_qvlpcls", - "qpx.qvlpcrd" => "__builtin_qpx_qvlpcrd", - "qpx.qvlpcrs" => "__builtin_qpx_qvlpcrs", - "qpx.qvstfcd" => "__builtin_qpx_qvstfcd", - "qpx.qvstfcda" => "__builtin_qpx_qvstfcda", - "qpx.qvstfcs" => "__builtin_qpx_qvstfcs", - "qpx.qvstfcsa" => "__builtin_qpx_qvstfcsa", - "qpx.qvstfd" => "__builtin_qpx_qvstfd", - "qpx.qvstfda" => "__builtin_qpx_qvstfda", - "qpx.qvstfiw" => "__builtin_qpx_qvstfiw", - "qpx.qvstfiwa" => "__builtin_qpx_qvstfiwa", - "qpx.qvstfs" => "__builtin_qpx_qvstfs", - "qpx.qvstfsa" => "__builtin_qpx_qvstfsa", "readflm" => "__builtin_readflm", "rlwimi" => "__builtin_ppc_rlwimi", "rlwnm" => "__builtin_ppc_rlwnm", @@ -6202,6 +6099,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "vsx.xvminsp" => "__builtin_vsx_xvminsp", "vsx.xvredp" => "__builtin_vsx_xvredp", "vsx.xvresp" => "__builtin_vsx_xvresp", + "vsx.xvrlw" => "__builtin_vsx_xvrlw", "vsx.xvrsqrtedp" => "__builtin_vsx_xvrsqrtedp", "vsx.xvrsqrtesp" => "__builtin_vsx_xvrsqrtesp", "vsx.xvtdivdp" => "__builtin_vsx_xvtdivdp", @@ -6234,33 +6132,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } ppc(name, full_name) } - "ptx" => { - fn ptx(name: &str, full_name: &str) -> &'static str { - match name { - // ptx - "bar.sync" => "__builtin_ptx_bar_sync", - "read.clock" => "__builtin_ptx_read_clock", - "read.clock64" => "__builtin_ptx_read_clock64", - "read.gridid" => "__builtin_ptx_read_gridid", - "read.laneid" => "__builtin_ptx_read_laneid", - "read.lanemask.eq" => "__builtin_ptx_read_lanemask_eq", - "read.lanemask.ge" => "__builtin_ptx_read_lanemask_ge", - "read.lanemask.gt" => "__builtin_ptx_read_lanemask_gt", - "read.lanemask.le" => "__builtin_ptx_read_lanemask_le", - "read.lanemask.lt" => "__builtin_ptx_read_lanemask_lt", - "read.nsmid" => "__builtin_ptx_read_nsmid", - "read.nwarpid" => "__builtin_ptx_read_nwarpid", - "read.pm0" => "__builtin_ptx_read_pm0", - "read.pm1" => "__builtin_ptx_read_pm1", - "read.pm2" => "__builtin_ptx_read_pm2", - "read.pm3" => "__builtin_ptx_read_pm3", - "read.smid" => "__builtin_ptx_read_smid", - "read.warpid" => "__builtin_ptx_read_warpid", - _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), - } - } - ptx(name, full_name) - } "r600" => { fn r600(name: &str, full_name: &str) -> &'static str { match name { @@ -6515,6 +6386,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { fn spv(name: &str, full_name: &str) -> &'static str { match name { // spv + "group.memory.barrier.with.group.sync" => "__builtin_spirv_group_barrier", "num.subgroups" => "__builtin_spirv_num_subgroups", "subgroup.id" => "__builtin_spirv_subgroup_id", "subgroup.local.invocation.id" => { @@ -6522,6 +6394,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } "subgroup.max.size" => "__builtin_spirv_subgroup_max_size", "subgroup.size" => "__builtin_spirv_subgroup_size", + "wave.ballot" => "__builtin_spirv_subgroup_ballot", _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), } } @@ -7807,10 +7680,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "aadd64" => "__builtin_ia32_aadd64", "aand32" => "__builtin_ia32_aand32", "aand64" => "__builtin_ia32_aand64", - "addcarry.u32" => "__builtin_ia32_addcarry_u32", - "addcarry.u64" => "__builtin_ia32_addcarry_u64", - "addcarryx.u32" => "__builtin_ia32_addcarryx_u32", - "addcarryx.u64" => "__builtin_ia32_addcarryx_u64", "aesni.aesdec" => "__builtin_ia32_aesdec128", "aesni.aesdec.256" => "__builtin_ia32_aesdec256", "aesni.aesdec.512" => "__builtin_ia32_aesdec512", @@ -7829,18 +7698,11 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "aor64" => "__builtin_ia32_aor64", "avx.addsub.pd.256" => "__builtin_ia32_addsubpd256", "avx.addsub.ps.256" => "__builtin_ia32_addsubps256", - "avx.blend.pd.256" => "__builtin_ia32_blendpd256", - "avx.blend.ps.256" => "__builtin_ia32_blendps256", "avx.blendv.pd.256" => "__builtin_ia32_blendvpd256", "avx.blendv.ps.256" => "__builtin_ia32_blendvps256", - "avx.cmp.pd.256" => "__builtin_ia32_cmppd256", - "avx.cmp.ps.256" => "__builtin_ia32_cmpps256", "avx.cvt.pd2.ps.256" => "__builtin_ia32_cvtpd2ps256", "avx.cvt.pd2dq.256" => "__builtin_ia32_cvtpd2dq256", - "avx.cvt.ps2.pd.256" => "__builtin_ia32_cvtps2pd256", "avx.cvt.ps2dq.256" => "__builtin_ia32_cvtps2dq256", - "avx.cvtdq2.pd.256" => "__builtin_ia32_cvtdq2pd256", - "avx.cvtdq2.ps.256" => "__builtin_ia32_cvtdq2ps256", "avx.cvtt.pd2dq.256" => "__builtin_ia32_cvttpd2dq256", "avx.cvtt.ps2dq.256" => "__builtin_ia32_cvttps2dq256", "avx.dp.ps.256" => "__builtin_ia32_dpps256", @@ -7867,25 +7729,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx.ptestnzc.256" => "__builtin_ia32_ptestnzc256", "avx.ptestz.256" => "__builtin_ia32_ptestz256", "avx.rcp.ps.256" => "__builtin_ia32_rcpps256", - "avx.round.pd.256" => "__builtin_ia32_roundpd256", - "avx.round.ps.256" => "__builtin_ia32_roundps256", "avx.rsqrt.ps.256" => "__builtin_ia32_rsqrtps256", - "avx.sqrt.pd.256" => "__builtin_ia32_sqrtpd256", - "avx.sqrt.ps.256" => "__builtin_ia32_sqrtps256", - "avx.storeu.dq.256" => "__builtin_ia32_storedqu256", - "avx.storeu.pd.256" => "__builtin_ia32_storeupd256", - "avx.storeu.ps.256" => "__builtin_ia32_storeups256", - "avx.vbroadcastf128.pd.256" => "__builtin_ia32_vbroadcastf128_pd256", - "avx.vbroadcastf128.ps.256" => "__builtin_ia32_vbroadcastf128_ps256", - "avx.vextractf128.pd.256" => "__builtin_ia32_vextractf128_pd256", - "avx.vextractf128.ps.256" => "__builtin_ia32_vextractf128_ps256", - "avx.vextractf128.si.256" => "__builtin_ia32_vextractf128_si256", - "avx.vinsertf128.pd.256" => "__builtin_ia32_vinsertf128_pd256", - "avx.vinsertf128.ps.256" => "__builtin_ia32_vinsertf128_ps256", - "avx.vinsertf128.si.256" => "__builtin_ia32_vinsertf128_si256", - "avx.vperm2f128.pd.256" => "__builtin_ia32_vperm2f128_pd256", - "avx.vperm2f128.ps.256" => "__builtin_ia32_vperm2f128_ps256", - "avx.vperm2f128.si.256" => "__builtin_ia32_vperm2f128_si256", "avx.vpermilvar.pd" => "__builtin_ia32_vpermilvarpd", "avx.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256", "avx.vpermilvar.ps" => "__builtin_ia32_vpermilvarps", @@ -8170,33 +8014,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.maskstore.d.256" => "__builtin_ia32_maskstored256", "avx2.maskstore.q" => "__builtin_ia32_maskstoreq", "avx2.maskstore.q.256" => "__builtin_ia32_maskstoreq256", - "avx2.movntdqa" => "__builtin_ia32_movntdqa256", "avx2.mpsadbw" => "__builtin_ia32_mpsadbw256", - "avx2.pabs.b" => "__builtin_ia32_pabsb256", - "avx2.pabs.d" => "__builtin_ia32_pabsd256", - "avx2.pabs.w" => "__builtin_ia32_pabsw256", "avx2.packssdw" => "__builtin_ia32_packssdw256", "avx2.packsswb" => "__builtin_ia32_packsswb256", "avx2.packusdw" => "__builtin_ia32_packusdw256", "avx2.packuswb" => "__builtin_ia32_packuswb256", - "avx2.padds.b" => "__builtin_ia32_paddsb256", - "avx2.padds.w" => "__builtin_ia32_paddsw256", - "avx2.paddus.b" => "__builtin_ia32_paddusb256", - "avx2.paddus.w" => "__builtin_ia32_paddusw256", "avx2.pavg.b" => "__builtin_ia32_pavgb256", "avx2.pavg.w" => "__builtin_ia32_pavgw256", - "avx2.pblendd.128" => "__builtin_ia32_pblendd128", - "avx2.pblendd.256" => "__builtin_ia32_pblendd256", "avx2.pblendvb" => "__builtin_ia32_pblendvb256", - "avx2.pblendw" => "__builtin_ia32_pblendw256", - "avx2.pbroadcastb.128" => "__builtin_ia32_pbroadcastb128", - "avx2.pbroadcastb.256" => "__builtin_ia32_pbroadcastb256", - "avx2.pbroadcastd.128" => "__builtin_ia32_pbroadcastd128", - "avx2.pbroadcastd.256" => "__builtin_ia32_pbroadcastd256", - "avx2.pbroadcastq.128" => "__builtin_ia32_pbroadcastq128", - "avx2.pbroadcastq.256" => "__builtin_ia32_pbroadcastq256", - "avx2.pbroadcastw.128" => "__builtin_ia32_pbroadcastw128", - "avx2.pbroadcastw.256" => "__builtin_ia32_pbroadcastw256", "avx2.permd" => "__builtin_ia32_permvarsi256", "avx2.permps" => "__builtin_ia32_permvarsf256", "avx2.phadd.d" => "__builtin_ia32_phaddd256", @@ -8207,44 +8032,16 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.phsub.w" => "__builtin_ia32_phsubw256", "avx2.pmadd.ub.sw" => "__builtin_ia32_pmaddubsw256", "avx2.pmadd.wd" => "__builtin_ia32_pmaddwd256", - "avx2.pmaxs.b" => "__builtin_ia32_pmaxsb256", - "avx2.pmaxs.d" => "__builtin_ia32_pmaxsd256", - "avx2.pmaxs.w" => "__builtin_ia32_pmaxsw256", - "avx2.pmaxu.b" => "__builtin_ia32_pmaxub256", - "avx2.pmaxu.d" => "__builtin_ia32_pmaxud256", - "avx2.pmaxu.w" => "__builtin_ia32_pmaxuw256", - "avx2.pmins.b" => "__builtin_ia32_pminsb256", - "avx2.pmins.d" => "__builtin_ia32_pminsd256", - "avx2.pmins.w" => "__builtin_ia32_pminsw256", - "avx2.pminu.b" => "__builtin_ia32_pminub256", - "avx2.pminu.d" => "__builtin_ia32_pminud256", - "avx2.pminu.w" => "__builtin_ia32_pminuw256", "avx2.pmovmskb" => "__builtin_ia32_pmovmskb256", - "avx2.pmovsxbd" => "__builtin_ia32_pmovsxbd256", - "avx2.pmovsxbq" => "__builtin_ia32_pmovsxbq256", - "avx2.pmovsxbw" => "__builtin_ia32_pmovsxbw256", - "avx2.pmovsxdq" => "__builtin_ia32_pmovsxdq256", - "avx2.pmovsxwd" => "__builtin_ia32_pmovsxwd256", - "avx2.pmovsxwq" => "__builtin_ia32_pmovsxwq256", - "avx2.pmovzxbd" => "__builtin_ia32_pmovzxbd256", - "avx2.pmovzxbq" => "__builtin_ia32_pmovzxbq256", - "avx2.pmovzxbw" => "__builtin_ia32_pmovzxbw256", - "avx2.pmovzxdq" => "__builtin_ia32_pmovzxdq256", - "avx2.pmovzxwd" => "__builtin_ia32_pmovzxwd256", - "avx2.pmovzxwq" => "__builtin_ia32_pmovzxwq256", - "avx2.pmul.dq" => "__builtin_ia32_pmuldq256", "avx2.pmul.hr.sw" => "__builtin_ia32_pmulhrsw256", "avx2.pmulh.w" => "__builtin_ia32_pmulhw256", "avx2.pmulhu.w" => "__builtin_ia32_pmulhuw256", - "avx2.pmulu.dq" => "__builtin_ia32_pmuludq256", "avx2.psad.bw" => "__builtin_ia32_psadbw256", "avx2.pshuf.b" => "__builtin_ia32_pshufb256", "avx2.psign.b" => "__builtin_ia32_psignb256", "avx2.psign.d" => "__builtin_ia32_psignd256", "avx2.psign.w" => "__builtin_ia32_psignw256", "avx2.psll.d" => "__builtin_ia32_pslld256", - "avx2.psll.dq" => "__builtin_ia32_pslldqi256", - "avx2.psll.dq.bs" => "__builtin_ia32_pslldqi256_byteshift", "avx2.psll.q" => "__builtin_ia32_psllq256", "avx2.psll.w" => "__builtin_ia32_psllw256", "avx2.pslli.d" => "__builtin_ia32_pslldi256", @@ -8261,8 +8058,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.psrav.d" => "__builtin_ia32_psrav4si", "avx2.psrav.d.256" => "__builtin_ia32_psrav8si", "avx2.psrl.d" => "__builtin_ia32_psrld256", - "avx2.psrl.dq" => "__builtin_ia32_psrldqi256", - "avx2.psrl.dq.bs" => "__builtin_ia32_psrldqi256_byteshift", "avx2.psrl.q" => "__builtin_ia32_psrlq256", "avx2.psrl.w" => "__builtin_ia32_psrlw256", "avx2.psrli.d" => "__builtin_ia32_psrldi256", @@ -8272,15 +8067,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.psrlv.d.256" => "__builtin_ia32_psrlv8si", "avx2.psrlv.q" => "__builtin_ia32_psrlv2di", "avx2.psrlv.q.256" => "__builtin_ia32_psrlv4di", - "avx2.psubs.b" => "__builtin_ia32_psubsb256", - "avx2.psubs.w" => "__builtin_ia32_psubsw256", - "avx2.psubus.b" => "__builtin_ia32_psubusb256", - "avx2.psubus.w" => "__builtin_ia32_psubusw256", - "avx2.vbroadcast.sd.pd.256" => "__builtin_ia32_vbroadcastsd_pd256", - "avx2.vbroadcast.ss.ps" => "__builtin_ia32_vbroadcastss_ps", - "avx2.vbroadcast.ss.ps.256" => "__builtin_ia32_vbroadcastss_ps256", - "avx2.vextracti128" => "__builtin_ia32_extract128i256", - "avx2.vinserti128" => "__builtin_ia32_insert128i256", "avx2.vpdpbssd.128" => "__builtin_ia32_vpdpbssd128", "avx2.vpdpbssd.256" => "__builtin_ia32_vpdpbssd256", "avx2.vpdpbssds.128" => "__builtin_ia32_vpdpbssds128", @@ -8305,7 +8091,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx2.vpdpwuud.256" => "__builtin_ia32_vpdpwuud256", "avx2.vpdpwuuds.128" => "__builtin_ia32_vpdpwuuds128", "avx2.vpdpwuuds.256" => "__builtin_ia32_vpdpwuuds256", - "avx2.vperm2i128" => "__builtin_ia32_permti256", "avx512.add.pd.512" => "__builtin_ia32_addpd512", "avx512.add.ps.512" => "__builtin_ia32_addps512", "avx512.broadcastmb.128" => "__builtin_ia32_broadcastmb128", @@ -8320,194 +8105,32 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.conflict.q.128" => "__builtin_ia32_vpconflictdi_128", "avx512.conflict.q.256" => "__builtin_ia32_vpconflictdi_256", "avx512.conflict.q.512" => "__builtin_ia32_vpconflictdi_512", - "avx512.cvtb2mask.128" => "__builtin_ia32_cvtb2mask128", - "avx512.cvtb2mask.256" => "__builtin_ia32_cvtb2mask256", - "avx512.cvtb2mask.512" => "__builtin_ia32_cvtb2mask512", - "avx512.cvtd2mask.128" => "__builtin_ia32_cvtd2mask128", - "avx512.cvtd2mask.256" => "__builtin_ia32_cvtd2mask256", - "avx512.cvtd2mask.512" => "__builtin_ia32_cvtd2mask512", - "avx512.cvtmask2b.128" => "__builtin_ia32_cvtmask2b128", - "avx512.cvtmask2b.256" => "__builtin_ia32_cvtmask2b256", - "avx512.cvtmask2b.512" => "__builtin_ia32_cvtmask2b512", - "avx512.cvtmask2d.128" => "__builtin_ia32_cvtmask2d128", - "avx512.cvtmask2d.256" => "__builtin_ia32_cvtmask2d256", - "avx512.cvtmask2d.512" => "__builtin_ia32_cvtmask2d512", - "avx512.cvtmask2q.128" => "__builtin_ia32_cvtmask2q128", - "avx512.cvtmask2q.256" => "__builtin_ia32_cvtmask2q256", - "avx512.cvtmask2q.512" => "__builtin_ia32_cvtmask2q512", - "avx512.cvtmask2w.128" => "__builtin_ia32_cvtmask2w128", - "avx512.cvtmask2w.256" => "__builtin_ia32_cvtmask2w256", - "avx512.cvtmask2w.512" => "__builtin_ia32_cvtmask2w512", - "avx512.cvtq2mask.128" => "__builtin_ia32_cvtq2mask128", - "avx512.cvtq2mask.256" => "__builtin_ia32_cvtq2mask256", - "avx512.cvtq2mask.512" => "__builtin_ia32_cvtq2mask512", - "avx512.cvtsd2usi" => "__builtin_ia32_cvtsd2usi", - "avx512.cvtsd2usi64" => "__builtin_ia32_cvtsd2usi64", - "avx512.cvtsi2sd32" => "__builtin_ia32_cvtsi2sd32", "avx512.cvtsi2sd64" => "__builtin_ia32_cvtsi2sd64", "avx512.cvtsi2ss32" => "__builtin_ia32_cvtsi2ss32", "avx512.cvtsi2ss64" => "__builtin_ia32_cvtsi2ss64", - "avx512.cvtss2usi" => "__builtin_ia32_cvtss2usi", - "avx512.cvtss2usi64" => "__builtin_ia32_cvtss2usi64", "avx512.cvttsd2si" => "__builtin_ia32_vcvttsd2si32", "avx512.cvttsd2si64" => "__builtin_ia32_vcvttsd2si64", "avx512.cvttsd2usi" => "__builtin_ia32_vcvttsd2usi32", - // [DUPLICATE]: "avx512.cvttsd2usi" => "__builtin_ia32_cvttsd2usi", "avx512.cvttsd2usi64" => "__builtin_ia32_vcvttsd2usi64", - // [DUPLICATE]: "avx512.cvttsd2usi64" => "__builtin_ia32_cvttsd2usi64", "avx512.cvttss2si" => "__builtin_ia32_vcvttss2si32", "avx512.cvttss2si64" => "__builtin_ia32_vcvttss2si64", "avx512.cvttss2usi" => "__builtin_ia32_vcvttss2usi32", - // [DUPLICATE]: "avx512.cvttss2usi" => "__builtin_ia32_cvttss2usi", "avx512.cvttss2usi64" => "__builtin_ia32_vcvttss2usi64", - // [DUPLICATE]: "avx512.cvttss2usi64" => "__builtin_ia32_cvttss2usi64", - "avx512.cvtusi2sd" => "__builtin_ia32_cvtusi2sd", - // [DUPLICATE]: "avx512.cvtusi2sd" => "__builtin_ia32_cvtusi2sd32", "avx512.cvtusi2ss" => "__builtin_ia32_cvtusi2ss32", - // [DUPLICATE]: "avx512.cvtusi2ss" => "__builtin_ia32_cvtusi2ss", "avx512.cvtusi642sd" => "__builtin_ia32_cvtusi2sd64", - // [DUPLICATE]: "avx512.cvtusi642sd" => "__builtin_ia32_cvtusi642sd", "avx512.cvtusi642ss" => "__builtin_ia32_cvtusi2ss64", - // [DUPLICATE]: "avx512.cvtusi642ss" => "__builtin_ia32_cvtusi642ss", - "avx512.cvtw2mask.128" => "__builtin_ia32_cvtw2mask128", - "avx512.cvtw2mask.256" => "__builtin_ia32_cvtw2mask256", - "avx512.cvtw2mask.512" => "__builtin_ia32_cvtw2mask512", "avx512.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128", "avx512.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256", "avx512.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512", "avx512.div.pd.512" => "__builtin_ia32_divpd512", "avx512.div.ps.512" => "__builtin_ia32_divps512", - "avx512.exp2.pd" => "__builtin_ia32_exp2pd_mask", - "avx512.exp2.ps" => "__builtin_ia32_exp2ps_mask", - "avx512.gather.dpd.512" => "__builtin_ia32_gathersiv8df", - "avx512.gather.dpi.512" => "__builtin_ia32_gathersiv16si", - "avx512.gather.dpq.512" => "__builtin_ia32_gathersiv8di", - "avx512.gather.dps.512" => "__builtin_ia32_gathersiv16sf", - "avx512.gather.qpd.512" => "__builtin_ia32_gatherdiv8df", - "avx512.gather.qpi.512" => "__builtin_ia32_gatherdiv16si", - "avx512.gather.qpq.512" => "__builtin_ia32_gatherdiv8di", - "avx512.gather.qps.512" => "__builtin_ia32_gatherdiv16sf", - "avx512.gather3div2.df" => "__builtin_ia32_gather3div2df", - "avx512.gather3div2.di" => "__builtin_ia32_gather3div2di", - "avx512.gather3div4.df" => "__builtin_ia32_gather3div4df", - "avx512.gather3div4.di" => "__builtin_ia32_gather3div4di", - "avx512.gather3div4.sf" => "__builtin_ia32_gather3div4sf", - "avx512.gather3div4.si" => "__builtin_ia32_gather3div4si", - "avx512.gather3div8.sf" => "__builtin_ia32_gather3div8sf", - "avx512.gather3div8.si" => "__builtin_ia32_gather3div8si", - "avx512.gather3siv2.df" => "__builtin_ia32_gather3siv2df", - "avx512.gather3siv2.di" => "__builtin_ia32_gather3siv2di", - "avx512.gather3siv4.df" => "__builtin_ia32_gather3siv4df", - "avx512.gather3siv4.di" => "__builtin_ia32_gather3siv4di", - "avx512.gather3siv4.sf" => "__builtin_ia32_gather3siv4sf", - "avx512.gather3siv4.si" => "__builtin_ia32_gather3siv4si", - "avx512.gather3siv8.sf" => "__builtin_ia32_gather3siv8sf", - "avx512.gather3siv8.si" => "__builtin_ia32_gather3siv8si", - "avx512.gatherpf.dpd.512" => "__builtin_ia32_gatherpfdpd", - "avx512.gatherpf.dps.512" => "__builtin_ia32_gatherpfdps", - "avx512.gatherpf.qpd.512" => "__builtin_ia32_gatherpfqpd", - "avx512.gatherpf.qps.512" => "__builtin_ia32_gatherpfqps", - "avx512.kand.w" => "__builtin_ia32_kandhi", - "avx512.kandn.w" => "__builtin_ia32_kandnhi", - "avx512.knot.w" => "__builtin_ia32_knothi", - "avx512.kor.w" => "__builtin_ia32_korhi", - "avx512.kortestc.w" => "__builtin_ia32_kortestchi", - "avx512.kortestz.w" => "__builtin_ia32_kortestzhi", - "avx512.kunpck.bw" => "__builtin_ia32_kunpckhi", - "avx512.kunpck.dq" => "__builtin_ia32_kunpckdi", - "avx512.kunpck.wd" => "__builtin_ia32_kunpcksi", - "avx512.kxnor.w" => "__builtin_ia32_kxnorhi", - "avx512.kxor.w" => "__builtin_ia32_kxorhi", - "avx512.mask.add.pd.128" => "__builtin_ia32_addpd128_mask", - "avx512.mask.add.pd.256" => "__builtin_ia32_addpd256_mask", - "avx512.mask.add.pd.512" => "__builtin_ia32_addpd512_mask", - "avx512.mask.add.ps.128" => "__builtin_ia32_addps128_mask", - "avx512.mask.add.ps.256" => "__builtin_ia32_addps256_mask", - "avx512.mask.add.ps.512" => "__builtin_ia32_addps512_mask", // [INVALID CONVERSION]: "avx512.mask.add.sd.round" => "__builtin_ia32_addsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.add.ss.round" => "__builtin_ia32_addss_round_mask", - "avx512.mask.and.pd.128" => "__builtin_ia32_andpd128_mask", - "avx512.mask.and.pd.256" => "__builtin_ia32_andpd256_mask", - "avx512.mask.and.pd.512" => "__builtin_ia32_andpd512_mask", - "avx512.mask.and.ps.128" => "__builtin_ia32_andps128_mask", - "avx512.mask.and.ps.256" => "__builtin_ia32_andps256_mask", - "avx512.mask.and.ps.512" => "__builtin_ia32_andps512_mask", - "avx512.mask.andn.pd.128" => "__builtin_ia32_andnpd128_mask", - "avx512.mask.andn.pd.256" => "__builtin_ia32_andnpd256_mask", - "avx512.mask.andn.pd.512" => "__builtin_ia32_andnpd512_mask", - "avx512.mask.andn.ps.128" => "__builtin_ia32_andnps128_mask", - "avx512.mask.andn.ps.256" => "__builtin_ia32_andnps256_mask", - "avx512.mask.andn.ps.512" => "__builtin_ia32_andnps512_mask", - "avx512.mask.blend.d.512" => "__builtin_ia32_blendmd_512_mask", - "avx512.mask.blend.pd.512" => "__builtin_ia32_blendmpd_512_mask", - "avx512.mask.blend.ps.512" => "__builtin_ia32_blendmps_512_mask", - "avx512.mask.blend.q.512" => "__builtin_ia32_blendmq_512_mask", - "avx512.mask.broadcastf32x2.256" => "__builtin_ia32_broadcastf32x2_256_mask", - "avx512.mask.broadcastf32x2.512" => "__builtin_ia32_broadcastf32x2_512_mask", - "avx512.mask.broadcastf32x4.256" => "__builtin_ia32_broadcastf32x4_256_mask", - "avx512.mask.broadcastf32x4.512" => "__builtin_ia32_broadcastf32x4_512", - "avx512.mask.broadcastf32x8.512" => "__builtin_ia32_broadcastf32x8_512_mask", - "avx512.mask.broadcastf64x2.256" => "__builtin_ia32_broadcastf64x2_256_mask", - "avx512.mask.broadcastf64x2.512" => "__builtin_ia32_broadcastf64x2_512_mask", - "avx512.mask.broadcastf64x4.512" => "__builtin_ia32_broadcastf64x4_512", - "avx512.mask.broadcasti32x2.128" => "__builtin_ia32_broadcasti32x2_128_mask", - "avx512.mask.broadcasti32x2.256" => "__builtin_ia32_broadcasti32x2_256_mask", - "avx512.mask.broadcasti32x2.512" => "__builtin_ia32_broadcasti32x2_512_mask", - "avx512.mask.broadcasti32x4.256" => "__builtin_ia32_broadcasti32x4_256_mask", - "avx512.mask.broadcasti32x4.512" => "__builtin_ia32_broadcasti32x4_512", - "avx512.mask.broadcasti32x8.512" => "__builtin_ia32_broadcasti32x8_512_mask", - "avx512.mask.broadcasti64x2.256" => "__builtin_ia32_broadcasti64x2_256_mask", - "avx512.mask.broadcasti64x2.512" => "__builtin_ia32_broadcasti64x2_512_mask", - "avx512.mask.broadcasti64x4.512" => "__builtin_ia32_broadcasti64x4_512", - "avx512.mask.cmp.pd.128" => "__builtin_ia32_cmppd128_mask", - "avx512.mask.cmp.pd.256" => "__builtin_ia32_cmppd256_mask", - "avx512.mask.cmp.pd.512" => "__builtin_ia32_cmppd512_mask", - "avx512.mask.cmp.ps.128" => "__builtin_ia32_cmpps128_mask", - "avx512.mask.cmp.ps.256" => "__builtin_ia32_cmpps256_mask", - "avx512.mask.cmp.ps.512" => "__builtin_ia32_cmpps512_mask", "avx512.mask.cmp.sd" => "__builtin_ia32_cmpsd_mask", "avx512.mask.cmp.ss" => "__builtin_ia32_cmpss_mask", - "avx512.mask.compress.d.128" => "__builtin_ia32_compresssi128_mask", - "avx512.mask.compress.d.256" => "__builtin_ia32_compresssi256_mask", - "avx512.mask.compress.d.512" => "__builtin_ia32_compresssi512_mask", - "avx512.mask.compress.pd.128" => "__builtin_ia32_compressdf128_mask", - "avx512.mask.compress.pd.256" => "__builtin_ia32_compressdf256_mask", - "avx512.mask.compress.pd.512" => "__builtin_ia32_compressdf512_mask", - "avx512.mask.compress.ps.128" => "__builtin_ia32_compresssf128_mask", - "avx512.mask.compress.ps.256" => "__builtin_ia32_compresssf256_mask", - "avx512.mask.compress.ps.512" => "__builtin_ia32_compresssf512_mask", - "avx512.mask.compress.q.128" => "__builtin_ia32_compressdi128_mask", - "avx512.mask.compress.q.256" => "__builtin_ia32_compressdi256_mask", - "avx512.mask.compress.q.512" => "__builtin_ia32_compressdi512_mask", - "avx512.mask.compress.store.d.128" => "__builtin_ia32_compressstoresi128_mask", - "avx512.mask.compress.store.d.256" => "__builtin_ia32_compressstoresi256_mask", - "avx512.mask.compress.store.d.512" => "__builtin_ia32_compressstoresi512_mask", - "avx512.mask.compress.store.pd.128" => "__builtin_ia32_compressstoredf128_mask", - "avx512.mask.compress.store.pd.256" => "__builtin_ia32_compressstoredf256_mask", - "avx512.mask.compress.store.pd.512" => "__builtin_ia32_compressstoredf512_mask", - "avx512.mask.compress.store.ps.128" => "__builtin_ia32_compressstoresf128_mask", - "avx512.mask.compress.store.ps.256" => "__builtin_ia32_compressstoresf256_mask", - "avx512.mask.compress.store.ps.512" => "__builtin_ia32_compressstoresf512_mask", - "avx512.mask.compress.store.q.128" => "__builtin_ia32_compressstoredi128_mask", - "avx512.mask.compress.store.q.256" => "__builtin_ia32_compressstoredi256_mask", - "avx512.mask.compress.store.q.512" => "__builtin_ia32_compressstoredi512_mask", - "avx512.mask.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask", - "avx512.mask.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask", - "avx512.mask.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask", - "avx512.mask.conflict.q.128" => "__builtin_ia32_vpconflictdi_128_mask", - "avx512.mask.conflict.q.256" => "__builtin_ia32_vpconflictdi_256_mask", - "avx512.mask.conflict.q.512" => "__builtin_ia32_vpconflictdi_512_mask", - "avx512.mask.cvtdq2pd.128" => "__builtin_ia32_cvtdq2pd128_mask", - "avx512.mask.cvtdq2pd.256" => "__builtin_ia32_cvtdq2pd256_mask", - "avx512.mask.cvtdq2pd.512" => "__builtin_ia32_cvtdq2pd512_mask", - "avx512.mask.cvtdq2ps.128" => "__builtin_ia32_cvtdq2ps128_mask", - "avx512.mask.cvtdq2ps.256" => "__builtin_ia32_cvtdq2ps256_mask", - "avx512.mask.cvtdq2ps.512" => "__builtin_ia32_cvtdq2ps512_mask", "avx512.mask.cvtpd2dq.128" => "__builtin_ia32_cvtpd2dq128_mask", - "avx512.mask.cvtpd2dq.256" => "__builtin_ia32_cvtpd2dq256_mask", "avx512.mask.cvtpd2dq.512" => "__builtin_ia32_cvtpd2dq512_mask", "avx512.mask.cvtpd2ps" => "__builtin_ia32_cvtpd2ps_mask", - "avx512.mask.cvtpd2ps.256" => "__builtin_ia32_cvtpd2ps256_mask", "avx512.mask.cvtpd2ps.512" => "__builtin_ia32_cvtpd2ps512_mask", "avx512.mask.cvtpd2qq.128" => "__builtin_ia32_cvtpd2qq128_mask", "avx512.mask.cvtpd2qq.256" => "__builtin_ia32_cvtpd2qq256_mask", @@ -8521,8 +8144,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvtps2dq.128" => "__builtin_ia32_cvtps2dq128_mask", "avx512.mask.cvtps2dq.256" => "__builtin_ia32_cvtps2dq256_mask", "avx512.mask.cvtps2dq.512" => "__builtin_ia32_cvtps2dq512_mask", - "avx512.mask.cvtps2pd.128" => "__builtin_ia32_cvtps2pd128_mask", - "avx512.mask.cvtps2pd.256" => "__builtin_ia32_cvtps2pd256_mask", "avx512.mask.cvtps2pd.512" => "__builtin_ia32_cvtps2pd512_mask", "avx512.mask.cvtps2qq.128" => "__builtin_ia32_cvtps2qq128_mask", "avx512.mask.cvtps2qq.256" => "__builtin_ia32_cvtps2qq256_mask", @@ -8533,16 +8154,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvtps2uqq.128" => "__builtin_ia32_cvtps2uqq128_mask", "avx512.mask.cvtps2uqq.256" => "__builtin_ia32_cvtps2uqq256_mask", "avx512.mask.cvtps2uqq.512" => "__builtin_ia32_cvtps2uqq512_mask", - "avx512.mask.cvtqq2pd.128" => "__builtin_ia32_cvtqq2pd128_mask", - "avx512.mask.cvtqq2pd.256" => "__builtin_ia32_cvtqq2pd256_mask", - "avx512.mask.cvtqq2pd.512" => "__builtin_ia32_cvtqq2pd512_mask", "avx512.mask.cvtqq2ps.128" => "__builtin_ia32_cvtqq2ps128_mask", - "avx512.mask.cvtqq2ps.256" => "__builtin_ia32_cvtqq2ps256_mask", - "avx512.mask.cvtqq2ps.512" => "__builtin_ia32_cvtqq2ps512_mask", // [INVALID CONVERSION]: "avx512.mask.cvtsd2ss.round" => "__builtin_ia32_cvtsd2ss_round_mask", // [INVALID CONVERSION]: "avx512.mask.cvtss2sd.round" => "__builtin_ia32_cvtss2sd_round_mask", "avx512.mask.cvttpd2dq.128" => "__builtin_ia32_cvttpd2dq128_mask", - "avx512.mask.cvttpd2dq.256" => "__builtin_ia32_cvttpd2dq256_mask", "avx512.mask.cvttpd2dq.512" => "__builtin_ia32_cvttpd2dq512_mask", "avx512.mask.cvttpd2qq.128" => "__builtin_ia32_cvttpd2qq128_mask", "avx512.mask.cvttpd2qq.256" => "__builtin_ia32_cvttpd2qq256_mask", @@ -8553,8 +8168,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvttpd2uqq.128" => "__builtin_ia32_cvttpd2uqq128_mask", "avx512.mask.cvttpd2uqq.256" => "__builtin_ia32_cvttpd2uqq256_mask", "avx512.mask.cvttpd2uqq.512" => "__builtin_ia32_cvttpd2uqq512_mask", - "avx512.mask.cvttps2dq.128" => "__builtin_ia32_cvttps2dq128_mask", - "avx512.mask.cvttps2dq.256" => "__builtin_ia32_cvttps2dq256_mask", "avx512.mask.cvttps2dq.512" => "__builtin_ia32_cvttps2dq512_mask", "avx512.mask.cvttps2qq.128" => "__builtin_ia32_cvttps2qq128_mask", "avx512.mask.cvttps2qq.256" => "__builtin_ia32_cvttps2qq256_mask", @@ -8565,53 +8178,9 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.cvttps2uqq.128" => "__builtin_ia32_cvttps2uqq128_mask", "avx512.mask.cvttps2uqq.256" => "__builtin_ia32_cvttps2uqq256_mask", "avx512.mask.cvttps2uqq.512" => "__builtin_ia32_cvttps2uqq512_mask", - "avx512.mask.cvtudq2pd.128" => "__builtin_ia32_cvtudq2pd128_mask", - "avx512.mask.cvtudq2pd.256" => "__builtin_ia32_cvtudq2pd256_mask", - "avx512.mask.cvtudq2pd.512" => "__builtin_ia32_cvtudq2pd512_mask", - "avx512.mask.cvtudq2ps.128" => "__builtin_ia32_cvtudq2ps128_mask", - "avx512.mask.cvtudq2ps.256" => "__builtin_ia32_cvtudq2ps256_mask", - "avx512.mask.cvtudq2ps.512" => "__builtin_ia32_cvtudq2ps512_mask", - "avx512.mask.cvtuqq2pd.128" => "__builtin_ia32_cvtuqq2pd128_mask", - "avx512.mask.cvtuqq2pd.256" => "__builtin_ia32_cvtuqq2pd256_mask", - "avx512.mask.cvtuqq2pd.512" => "__builtin_ia32_cvtuqq2pd512_mask", "avx512.mask.cvtuqq2ps.128" => "__builtin_ia32_cvtuqq2ps128_mask", - "avx512.mask.cvtuqq2ps.256" => "__builtin_ia32_cvtuqq2ps256_mask", - "avx512.mask.cvtuqq2ps.512" => "__builtin_ia32_cvtuqq2ps512_mask", - "avx512.mask.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128_mask", - "avx512.mask.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256_mask", - "avx512.mask.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512_mask", - "avx512.mask.div.pd.128" => "__builtin_ia32_divpd_mask", - "avx512.mask.div.pd.256" => "__builtin_ia32_divpd256_mask", - "avx512.mask.div.pd.512" => "__builtin_ia32_divpd512_mask", - "avx512.mask.div.ps.128" => "__builtin_ia32_divps_mask", - "avx512.mask.div.ps.256" => "__builtin_ia32_divps256_mask", - "avx512.mask.div.ps.512" => "__builtin_ia32_divps512_mask", // [INVALID CONVERSION]: "avx512.mask.div.sd.round" => "__builtin_ia32_divsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.div.ss.round" => "__builtin_ia32_divss_round_mask", - "avx512.mask.expand.d.128" => "__builtin_ia32_expandsi128_mask", - "avx512.mask.expand.d.256" => "__builtin_ia32_expandsi256_mask", - "avx512.mask.expand.d.512" => "__builtin_ia32_expandsi512_mask", - "avx512.mask.expand.load.d.128" => "__builtin_ia32_expandloadsi128_mask", - "avx512.mask.expand.load.d.256" => "__builtin_ia32_expandloadsi256_mask", - "avx512.mask.expand.load.d.512" => "__builtin_ia32_expandloadsi512_mask", - "avx512.mask.expand.load.pd.128" => "__builtin_ia32_expandloaddf128_mask", - "avx512.mask.expand.load.pd.256" => "__builtin_ia32_expandloaddf256_mask", - "avx512.mask.expand.load.pd.512" => "__builtin_ia32_expandloaddf512_mask", - "avx512.mask.expand.load.ps.128" => "__builtin_ia32_expandloadsf128_mask", - "avx512.mask.expand.load.ps.256" => "__builtin_ia32_expandloadsf256_mask", - "avx512.mask.expand.load.ps.512" => "__builtin_ia32_expandloadsf512_mask", - "avx512.mask.expand.load.q.128" => "__builtin_ia32_expandloaddi128_mask", - "avx512.mask.expand.load.q.256" => "__builtin_ia32_expandloaddi256_mask", - "avx512.mask.expand.load.q.512" => "__builtin_ia32_expandloaddi512_mask", - "avx512.mask.expand.pd.128" => "__builtin_ia32_expanddf128_mask", - "avx512.mask.expand.pd.256" => "__builtin_ia32_expanddf256_mask", - "avx512.mask.expand.pd.512" => "__builtin_ia32_expanddf512_mask", - "avx512.mask.expand.ps.128" => "__builtin_ia32_expandsf128_mask", - "avx512.mask.expand.ps.256" => "__builtin_ia32_expandsf256_mask", - "avx512.mask.expand.ps.512" => "__builtin_ia32_expandsf512_mask", - "avx512.mask.expand.q.128" => "__builtin_ia32_expanddi128_mask", - "avx512.mask.expand.q.256" => "__builtin_ia32_expanddi256_mask", - "avx512.mask.expand.q.512" => "__builtin_ia32_expanddi512_mask", "avx512.mask.fixupimm.pd.128" => "__builtin_ia32_fixupimmpd128_mask", "avx512.mask.fixupimm.pd.256" => "__builtin_ia32_fixupimmpd256_mask", "avx512.mask.fixupimm.pd.512" => "__builtin_ia32_fixupimmpd512_mask", @@ -8620,12 +8189,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.fixupimm.ps.512" => "__builtin_ia32_fixupimmps512_mask", "avx512.mask.fixupimm.sd" => "__builtin_ia32_fixupimmsd_mask", "avx512.mask.fixupimm.ss" => "__builtin_ia32_fixupimmss_mask", - "avx512.mask.fpclass.pd.128" => "__builtin_ia32_fpclasspd128_mask", - "avx512.mask.fpclass.pd.256" => "__builtin_ia32_fpclasspd256_mask", - "avx512.mask.fpclass.pd.512" => "__builtin_ia32_fpclasspd512_mask", - "avx512.mask.fpclass.ps.128" => "__builtin_ia32_fpclassps128_mask", - "avx512.mask.fpclass.ps.256" => "__builtin_ia32_fpclassps256_mask", - "avx512.mask.fpclass.ps.512" => "__builtin_ia32_fpclassps512_mask", "avx512.mask.fpclass.sd" => "__builtin_ia32_fpclasssd_mask", "avx512.mask.fpclass.ss" => "__builtin_ia32_fpclassss_mask", "avx512.mask.getexp.pd.128" => "__builtin_ia32_getexppd128_mask", @@ -8644,226 +8207,19 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.getmant.ps.512" => "__builtin_ia32_getmantps512_mask", // [INVALID CONVERSION]: "avx512.mask.getmant.sd" => "__builtin_ia32_getmantsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.getmant.ss" => "__builtin_ia32_getmantss_round_mask", - "avx512.mask.insertf32x4.256" => "__builtin_ia32_insertf32x4_256_mask", - "avx512.mask.insertf32x4.512" => "__builtin_ia32_insertf32x4_mask", - "avx512.mask.insertf32x8.512" => "__builtin_ia32_insertf32x8_mask", - "avx512.mask.insertf64x2.256" => "__builtin_ia32_insertf64x2_256_mask", - "avx512.mask.insertf64x2.512" => "__builtin_ia32_insertf64x2_512_mask", - "avx512.mask.insertf64x4.512" => "__builtin_ia32_insertf64x4_mask", - "avx512.mask.inserti32x4.256" => "__builtin_ia32_inserti32x4_256_mask", - "avx512.mask.inserti32x4.512" => "__builtin_ia32_inserti32x4_mask", - "avx512.mask.inserti32x8.512" => "__builtin_ia32_inserti32x8_mask", - "avx512.mask.inserti64x2.256" => "__builtin_ia32_inserti64x2_256_mask", - "avx512.mask.inserti64x2.512" => "__builtin_ia32_inserti64x2_512_mask", - "avx512.mask.inserti64x4.512" => "__builtin_ia32_inserti64x4_mask", - "avx512.mask.loadu.d.512" => "__builtin_ia32_loaddqusi512_mask", - "avx512.mask.loadu.pd.512" => "__builtin_ia32_loadupd512_mask", - "avx512.mask.loadu.ps.512" => "__builtin_ia32_loadups512_mask", - "avx512.mask.loadu.q.512" => "__builtin_ia32_loaddqudi512_mask", - "avx512.mask.lzcnt.d.512" => "__builtin_ia32_vplzcntd_512_mask", - "avx512.mask.lzcnt.q.512" => "__builtin_ia32_vplzcntq_512_mask", - "avx512.mask.max.pd.128" => "__builtin_ia32_maxpd_mask", - "avx512.mask.max.pd.256" => "__builtin_ia32_maxpd256_mask", - "avx512.mask.max.pd.512" => "__builtin_ia32_maxpd512_mask", - "avx512.mask.max.ps.128" => "__builtin_ia32_maxps_mask", - "avx512.mask.max.ps.256" => "__builtin_ia32_maxps256_mask", - "avx512.mask.max.ps.512" => "__builtin_ia32_maxps512_mask", // [INVALID CONVERSION]: "avx512.mask.max.sd.round" => "__builtin_ia32_maxsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.max.ss.round" => "__builtin_ia32_maxss_round_mask", - "avx512.mask.min.pd.128" => "__builtin_ia32_minpd_mask", - "avx512.mask.min.pd.256" => "__builtin_ia32_minpd256_mask", - "avx512.mask.min.pd.512" => "__builtin_ia32_minpd512_mask", - "avx512.mask.min.ps.128" => "__builtin_ia32_minps_mask", - "avx512.mask.min.ps.256" => "__builtin_ia32_minps256_mask", - "avx512.mask.min.ps.512" => "__builtin_ia32_minps512_mask", // [INVALID CONVERSION]: "avx512.mask.min.sd.round" => "__builtin_ia32_minsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.min.ss.round" => "__builtin_ia32_minss_round_mask", - "avx512.mask.move.sd" => "__builtin_ia32_movsd_mask", - "avx512.mask.move.ss" => "__builtin_ia32_movss_mask", - "avx512.mask.mul.pd.128" => "__builtin_ia32_mulpd_mask", - "avx512.mask.mul.pd.256" => "__builtin_ia32_mulpd256_mask", - "avx512.mask.mul.pd.512" => "__builtin_ia32_mulpd512_mask", - "avx512.mask.mul.ps.128" => "__builtin_ia32_mulps_mask", - "avx512.mask.mul.ps.256" => "__builtin_ia32_mulps256_mask", - "avx512.mask.mul.ps.512" => "__builtin_ia32_mulps512_mask", // [INVALID CONVERSION]: "avx512.mask.mul.sd.round" => "__builtin_ia32_mulsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.mul.ss.round" => "__builtin_ia32_mulss_round_mask", - "avx512.mask.or.pd.128" => "__builtin_ia32_orpd128_mask", - "avx512.mask.or.pd.256" => "__builtin_ia32_orpd256_mask", - "avx512.mask.or.pd.512" => "__builtin_ia32_orpd512_mask", - "avx512.mask.or.ps.128" => "__builtin_ia32_orps128_mask", - "avx512.mask.or.ps.256" => "__builtin_ia32_orps256_mask", - "avx512.mask.or.ps.512" => "__builtin_ia32_orps512_mask", - "avx512.mask.pabs.b.128" => "__builtin_ia32_pabsb128_mask", - "avx512.mask.pabs.b.256" => "__builtin_ia32_pabsb256_mask", - "avx512.mask.pabs.b.512" => "__builtin_ia32_pabsb512_mask", - "avx512.mask.pabs.d.128" => "__builtin_ia32_pabsd128_mask", - "avx512.mask.pabs.d.256" => "__builtin_ia32_pabsd256_mask", - "avx512.mask.pabs.d.512" => "__builtin_ia32_pabsd512_mask", - "avx512.mask.pabs.q.128" => "__builtin_ia32_pabsq128_mask", - "avx512.mask.pabs.q.256" => "__builtin_ia32_pabsq256_mask", - "avx512.mask.pabs.q.512" => "__builtin_ia32_pabsq512_mask", - "avx512.mask.pabs.w.128" => "__builtin_ia32_pabsw128_mask", - "avx512.mask.pabs.w.256" => "__builtin_ia32_pabsw256_mask", - "avx512.mask.pabs.w.512" => "__builtin_ia32_pabsw512_mask", - "avx512.mask.packssdw.128" => "__builtin_ia32_packssdw128_mask", - "avx512.mask.packssdw.256" => "__builtin_ia32_packssdw256_mask", - "avx512.mask.packssdw.512" => "__builtin_ia32_packssdw512_mask", - "avx512.mask.packsswb.128" => "__builtin_ia32_packsswb128_mask", - "avx512.mask.packsswb.256" => "__builtin_ia32_packsswb256_mask", - "avx512.mask.packsswb.512" => "__builtin_ia32_packsswb512_mask", - "avx512.mask.packusdw.128" => "__builtin_ia32_packusdw128_mask", - "avx512.mask.packusdw.256" => "__builtin_ia32_packusdw256_mask", - "avx512.mask.packusdw.512" => "__builtin_ia32_packusdw512_mask", - "avx512.mask.packuswb.128" => "__builtin_ia32_packuswb128_mask", - "avx512.mask.packuswb.256" => "__builtin_ia32_packuswb256_mask", - "avx512.mask.packuswb.512" => "__builtin_ia32_packuswb512_mask", - "avx512.mask.padd.b.128" => "__builtin_ia32_paddb128_mask", - "avx512.mask.padd.b.256" => "__builtin_ia32_paddb256_mask", - "avx512.mask.padd.b.512" => "__builtin_ia32_paddb512_mask", - "avx512.mask.padd.d.128" => "__builtin_ia32_paddd128_mask", - "avx512.mask.padd.d.256" => "__builtin_ia32_paddd256_mask", - "avx512.mask.padd.d.512" => "__builtin_ia32_paddd512_mask", - "avx512.mask.padd.q.128" => "__builtin_ia32_paddq128_mask", - "avx512.mask.padd.q.256" => "__builtin_ia32_paddq256_mask", - "avx512.mask.padd.q.512" => "__builtin_ia32_paddq512_mask", - "avx512.mask.padd.w.128" => "__builtin_ia32_paddw128_mask", - "avx512.mask.padd.w.256" => "__builtin_ia32_paddw256_mask", - "avx512.mask.padd.w.512" => "__builtin_ia32_paddw512_mask", - "avx512.mask.padds.b.128" => "__builtin_ia32_paddsb128_mask", - "avx512.mask.padds.b.256" => "__builtin_ia32_paddsb256_mask", - "avx512.mask.padds.b.512" => "__builtin_ia32_paddsb512_mask", - "avx512.mask.padds.w.128" => "__builtin_ia32_paddsw128_mask", - "avx512.mask.padds.w.256" => "__builtin_ia32_paddsw256_mask", - "avx512.mask.padds.w.512" => "__builtin_ia32_paddsw512_mask", - "avx512.mask.paddus.b.128" => "__builtin_ia32_paddusb128_mask", - "avx512.mask.paddus.b.256" => "__builtin_ia32_paddusb256_mask", - "avx512.mask.paddus.b.512" => "__builtin_ia32_paddusb512_mask", - "avx512.mask.paddus.w.128" => "__builtin_ia32_paddusw128_mask", - "avx512.mask.paddus.w.256" => "__builtin_ia32_paddusw256_mask", - "avx512.mask.paddus.w.512" => "__builtin_ia32_paddusw512_mask", - "avx512.mask.pand.d.512" => "__builtin_ia32_pandd512_mask", - "avx512.mask.pand.q.512" => "__builtin_ia32_pandq512_mask", - "avx512.mask.pavg.b.128" => "__builtin_ia32_pavgb128_mask", - "avx512.mask.pavg.b.256" => "__builtin_ia32_pavgb256_mask", - "avx512.mask.pavg.b.512" => "__builtin_ia32_pavgb512_mask", - "avx512.mask.pavg.w.128" => "__builtin_ia32_pavgw128_mask", - "avx512.mask.pavg.w.256" => "__builtin_ia32_pavgw256_mask", - "avx512.mask.pavg.w.512" => "__builtin_ia32_pavgw512_mask", - "avx512.mask.pbroadcast.b.gpr.128" => "__builtin_ia32_pbroadcastb128_gpr_mask", - "avx512.mask.pbroadcast.b.gpr.256" => "__builtin_ia32_pbroadcastb256_gpr_mask", - "avx512.mask.pbroadcast.b.gpr.512" => "__builtin_ia32_pbroadcastb512_gpr_mask", - "avx512.mask.pbroadcast.d.gpr.128" => "__builtin_ia32_pbroadcastd128_gpr_mask", - "avx512.mask.pbroadcast.d.gpr.256" => "__builtin_ia32_pbroadcastd256_gpr_mask", - "avx512.mask.pbroadcast.d.gpr.512" => "__builtin_ia32_pbroadcastd512_gpr_mask", - "avx512.mask.pbroadcast.q.gpr.128" => "__builtin_ia32_pbroadcastq128_gpr_mask", - "avx512.mask.pbroadcast.q.gpr.256" => "__builtin_ia32_pbroadcastq256_gpr_mask", - "avx512.mask.pbroadcast.q.gpr.512" => "__builtin_ia32_pbroadcastq512_gpr_mask", - "avx512.mask.pbroadcast.q.mem.512" => "__builtin_ia32_pbroadcastq512_mem_mask", - "avx512.mask.pbroadcast.w.gpr.128" => "__builtin_ia32_pbroadcastw128_gpr_mask", - "avx512.mask.pbroadcast.w.gpr.256" => "__builtin_ia32_pbroadcastw256_gpr_mask", - "avx512.mask.pbroadcast.w.gpr.512" => "__builtin_ia32_pbroadcastw512_gpr_mask", - "avx512.mask.pcmpeq.b.128" => "__builtin_ia32_pcmpeqb128_mask", - "avx512.mask.pcmpeq.b.256" => "__builtin_ia32_pcmpeqb256_mask", - "avx512.mask.pcmpeq.b.512" => "__builtin_ia32_pcmpeqb512_mask", - "avx512.mask.pcmpeq.d.128" => "__builtin_ia32_pcmpeqd128_mask", - "avx512.mask.pcmpeq.d.256" => "__builtin_ia32_pcmpeqd256_mask", - "avx512.mask.pcmpeq.d.512" => "__builtin_ia32_pcmpeqd512_mask", - "avx512.mask.pcmpeq.q.128" => "__builtin_ia32_pcmpeqq128_mask", - "avx512.mask.pcmpeq.q.256" => "__builtin_ia32_pcmpeqq256_mask", - "avx512.mask.pcmpeq.q.512" => "__builtin_ia32_pcmpeqq512_mask", - "avx512.mask.pcmpeq.w.128" => "__builtin_ia32_pcmpeqw128_mask", - "avx512.mask.pcmpeq.w.256" => "__builtin_ia32_pcmpeqw256_mask", - "avx512.mask.pcmpeq.w.512" => "__builtin_ia32_pcmpeqw512_mask", - "avx512.mask.pcmpgt.b.128" => "__builtin_ia32_pcmpgtb128_mask", - "avx512.mask.pcmpgt.b.256" => "__builtin_ia32_pcmpgtb256_mask", - "avx512.mask.pcmpgt.b.512" => "__builtin_ia32_pcmpgtb512_mask", - "avx512.mask.pcmpgt.d.128" => "__builtin_ia32_pcmpgtd128_mask", - "avx512.mask.pcmpgt.d.256" => "__builtin_ia32_pcmpgtd256_mask", - "avx512.mask.pcmpgt.d.512" => "__builtin_ia32_pcmpgtd512_mask", - "avx512.mask.pcmpgt.q.128" => "__builtin_ia32_pcmpgtq128_mask", - "avx512.mask.pcmpgt.q.256" => "__builtin_ia32_pcmpgtq256_mask", - "avx512.mask.pcmpgt.q.512" => "__builtin_ia32_pcmpgtq512_mask", - "avx512.mask.pcmpgt.w.128" => "__builtin_ia32_pcmpgtw128_mask", - "avx512.mask.pcmpgt.w.256" => "__builtin_ia32_pcmpgtw256_mask", - "avx512.mask.pcmpgt.w.512" => "__builtin_ia32_pcmpgtw512_mask", - "avx512.mask.permvar.df.256" => "__builtin_ia32_permvardf256_mask", - "avx512.mask.permvar.df.512" => "__builtin_ia32_permvardf512_mask", - "avx512.mask.permvar.di.256" => "__builtin_ia32_permvardi256_mask", - "avx512.mask.permvar.di.512" => "__builtin_ia32_permvardi512_mask", - "avx512.mask.permvar.hi.128" => "__builtin_ia32_permvarhi128_mask", - "avx512.mask.permvar.hi.256" => "__builtin_ia32_permvarhi256_mask", - "avx512.mask.permvar.hi.512" => "__builtin_ia32_permvarhi512_mask", - "avx512.mask.permvar.qi.128" => "__builtin_ia32_permvarqi128_mask", - "avx512.mask.permvar.qi.256" => "__builtin_ia32_permvarqi256_mask", - "avx512.mask.permvar.qi.512" => "__builtin_ia32_permvarqi512_mask", - "avx512.mask.permvar.sf.256" => "__builtin_ia32_permvarsf256_mask", - "avx512.mask.permvar.sf.512" => "__builtin_ia32_permvarsf512_mask", - "avx512.mask.permvar.si.256" => "__builtin_ia32_permvarsi256_mask", - "avx512.mask.permvar.si.512" => "__builtin_ia32_permvarsi512_mask", - "avx512.mask.pmaddubs.w.128" => "__builtin_ia32_pmaddubsw128_mask", - "avx512.mask.pmaddubs.w.256" => "__builtin_ia32_pmaddubsw256_mask", - "avx512.mask.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512_mask", - "avx512.mask.pmaddw.d.128" => "__builtin_ia32_pmaddwd128_mask", - "avx512.mask.pmaddw.d.256" => "__builtin_ia32_pmaddwd256_mask", - "avx512.mask.pmaddw.d.512" => "__builtin_ia32_pmaddwd512_mask", - "avx512.mask.pmaxs.b.128" => "__builtin_ia32_pmaxsb128_mask", - "avx512.mask.pmaxs.b.256" => "__builtin_ia32_pmaxsb256_mask", - "avx512.mask.pmaxs.b.512" => "__builtin_ia32_pmaxsb512_mask", - "avx512.mask.pmaxs.d.128" => "__builtin_ia32_pmaxsd128_mask", - "avx512.mask.pmaxs.d.256" => "__builtin_ia32_pmaxsd256_mask", - "avx512.mask.pmaxs.d.512" => "__builtin_ia32_pmaxsd512_mask", - "avx512.mask.pmaxs.q.128" => "__builtin_ia32_pmaxsq128_mask", - "avx512.mask.pmaxs.q.256" => "__builtin_ia32_pmaxsq256_mask", - "avx512.mask.pmaxs.q.512" => "__builtin_ia32_pmaxsq512_mask", - "avx512.mask.pmaxs.w.128" => "__builtin_ia32_pmaxsw128_mask", - "avx512.mask.pmaxs.w.256" => "__builtin_ia32_pmaxsw256_mask", - "avx512.mask.pmaxs.w.512" => "__builtin_ia32_pmaxsw512_mask", - "avx512.mask.pmaxu.b.128" => "__builtin_ia32_pmaxub128_mask", - "avx512.mask.pmaxu.b.256" => "__builtin_ia32_pmaxub256_mask", - "avx512.mask.pmaxu.b.512" => "__builtin_ia32_pmaxub512_mask", - "avx512.mask.pmaxu.d.128" => "__builtin_ia32_pmaxud128_mask", - "avx512.mask.pmaxu.d.256" => "__builtin_ia32_pmaxud256_mask", - "avx512.mask.pmaxu.d.512" => "__builtin_ia32_pmaxud512_mask", - "avx512.mask.pmaxu.q.128" => "__builtin_ia32_pmaxuq128_mask", - "avx512.mask.pmaxu.q.256" => "__builtin_ia32_pmaxuq256_mask", - "avx512.mask.pmaxu.q.512" => "__builtin_ia32_pmaxuq512_mask", - "avx512.mask.pmaxu.w.128" => "__builtin_ia32_pmaxuw128_mask", - "avx512.mask.pmaxu.w.256" => "__builtin_ia32_pmaxuw256_mask", - "avx512.mask.pmaxu.w.512" => "__builtin_ia32_pmaxuw512_mask", - "avx512.mask.pmins.b.128" => "__builtin_ia32_pminsb128_mask", - "avx512.mask.pmins.b.256" => "__builtin_ia32_pminsb256_mask", - "avx512.mask.pmins.b.512" => "__builtin_ia32_pminsb512_mask", - "avx512.mask.pmins.d.128" => "__builtin_ia32_pminsd128_mask", - "avx512.mask.pmins.d.256" => "__builtin_ia32_pminsd256_mask", - "avx512.mask.pmins.d.512" => "__builtin_ia32_pminsd512_mask", - "avx512.mask.pmins.q.128" => "__builtin_ia32_pminsq128_mask", - "avx512.mask.pmins.q.256" => "__builtin_ia32_pminsq256_mask", - "avx512.mask.pmins.q.512" => "__builtin_ia32_pminsq512_mask", - "avx512.mask.pmins.w.128" => "__builtin_ia32_pminsw128_mask", - "avx512.mask.pmins.w.256" => "__builtin_ia32_pminsw256_mask", - "avx512.mask.pmins.w.512" => "__builtin_ia32_pminsw512_mask", - "avx512.mask.pminu.b.128" => "__builtin_ia32_pminub128_mask", - "avx512.mask.pminu.b.256" => "__builtin_ia32_pminub256_mask", - "avx512.mask.pminu.b.512" => "__builtin_ia32_pminub512_mask", - "avx512.mask.pminu.d.128" => "__builtin_ia32_pminud128_mask", - "avx512.mask.pminu.d.256" => "__builtin_ia32_pminud256_mask", - "avx512.mask.pminu.d.512" => "__builtin_ia32_pminud512_mask", - "avx512.mask.pminu.q.128" => "__builtin_ia32_pminuq128_mask", - "avx512.mask.pminu.q.256" => "__builtin_ia32_pminuq256_mask", - "avx512.mask.pminu.q.512" => "__builtin_ia32_pminuq512_mask", - "avx512.mask.pminu.w.128" => "__builtin_ia32_pminuw128_mask", - "avx512.mask.pminu.w.256" => "__builtin_ia32_pminuw256_mask", - "avx512.mask.pminu.w.512" => "__builtin_ia32_pminuw512_mask", "avx512.mask.pmov.db.128" => "__builtin_ia32_pmovdb128_mask", "avx512.mask.pmov.db.256" => "__builtin_ia32_pmovdb256_mask", - "avx512.mask.pmov.db.512" => "__builtin_ia32_pmovdb512_mask", "avx512.mask.pmov.db.mem.128" => "__builtin_ia32_pmovdb128mem_mask", "avx512.mask.pmov.db.mem.256" => "__builtin_ia32_pmovdb256mem_mask", "avx512.mask.pmov.db.mem.512" => "__builtin_ia32_pmovdb512mem_mask", "avx512.mask.pmov.dw.128" => "__builtin_ia32_pmovdw128_mask", "avx512.mask.pmov.dw.256" => "__builtin_ia32_pmovdw256_mask", - "avx512.mask.pmov.dw.512" => "__builtin_ia32_pmovdw512_mask", "avx512.mask.pmov.dw.mem.128" => "__builtin_ia32_pmovdw128mem_mask", "avx512.mask.pmov.dw.mem.256" => "__builtin_ia32_pmovdw256mem_mask", "avx512.mask.pmov.dw.mem.512" => "__builtin_ia32_pmovdw512mem_mask", @@ -8874,20 +8230,15 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.pmov.qb.mem.256" => "__builtin_ia32_pmovqb256mem_mask", "avx512.mask.pmov.qb.mem.512" => "__builtin_ia32_pmovqb512mem_mask", "avx512.mask.pmov.qd.128" => "__builtin_ia32_pmovqd128_mask", - "avx512.mask.pmov.qd.256" => "__builtin_ia32_pmovqd256_mask", - "avx512.mask.pmov.qd.512" => "__builtin_ia32_pmovqd512_mask", "avx512.mask.pmov.qd.mem.128" => "__builtin_ia32_pmovqd128mem_mask", "avx512.mask.pmov.qd.mem.256" => "__builtin_ia32_pmovqd256mem_mask", "avx512.mask.pmov.qd.mem.512" => "__builtin_ia32_pmovqd512mem_mask", "avx512.mask.pmov.qw.128" => "__builtin_ia32_pmovqw128_mask", "avx512.mask.pmov.qw.256" => "__builtin_ia32_pmovqw256_mask", - "avx512.mask.pmov.qw.512" => "__builtin_ia32_pmovqw512_mask", "avx512.mask.pmov.qw.mem.128" => "__builtin_ia32_pmovqw128mem_mask", "avx512.mask.pmov.qw.mem.256" => "__builtin_ia32_pmovqw256mem_mask", "avx512.mask.pmov.qw.mem.512" => "__builtin_ia32_pmovqw512mem_mask", "avx512.mask.pmov.wb.128" => "__builtin_ia32_pmovwb128_mask", - "avx512.mask.pmov.wb.256" => "__builtin_ia32_pmovwb256_mask", - "avx512.mask.pmov.wb.512" => "__builtin_ia32_pmovwb512_mask", "avx512.mask.pmov.wb.mem.128" => "__builtin_ia32_pmovwb128mem_mask", "avx512.mask.pmov.wb.mem.256" => "__builtin_ia32_pmovwb256mem_mask", "avx512.mask.pmov.wb.mem.512" => "__builtin_ia32_pmovwb512mem_mask", @@ -8927,24 +8278,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.pmovs.wb.mem.128" => "__builtin_ia32_pmovswb128mem_mask", "avx512.mask.pmovs.wb.mem.256" => "__builtin_ia32_pmovswb256mem_mask", "avx512.mask.pmovs.wb.mem.512" => "__builtin_ia32_pmovswb512mem_mask", - "avx512.mask.pmovsxb.d.128" => "__builtin_ia32_pmovsxbd128_mask", - "avx512.mask.pmovsxb.d.256" => "__builtin_ia32_pmovsxbd256_mask", - "avx512.mask.pmovsxb.d.512" => "__builtin_ia32_pmovsxbd512_mask", - "avx512.mask.pmovsxb.q.128" => "__builtin_ia32_pmovsxbq128_mask", - "avx512.mask.pmovsxb.q.256" => "__builtin_ia32_pmovsxbq256_mask", - "avx512.mask.pmovsxb.q.512" => "__builtin_ia32_pmovsxbq512_mask", - "avx512.mask.pmovsxb.w.128" => "__builtin_ia32_pmovsxbw128_mask", - "avx512.mask.pmovsxb.w.256" => "__builtin_ia32_pmovsxbw256_mask", - "avx512.mask.pmovsxb.w.512" => "__builtin_ia32_pmovsxbw512_mask", - "avx512.mask.pmovsxd.q.128" => "__builtin_ia32_pmovsxdq128_mask", - "avx512.mask.pmovsxd.q.256" => "__builtin_ia32_pmovsxdq256_mask", - "avx512.mask.pmovsxd.q.512" => "__builtin_ia32_pmovsxdq512_mask", - "avx512.mask.pmovsxw.d.128" => "__builtin_ia32_pmovsxwd128_mask", - "avx512.mask.pmovsxw.d.256" => "__builtin_ia32_pmovsxwd256_mask", - "avx512.mask.pmovsxw.d.512" => "__builtin_ia32_pmovsxwd512_mask", - "avx512.mask.pmovsxw.q.128" => "__builtin_ia32_pmovsxwq128_mask", - "avx512.mask.pmovsxw.q.256" => "__builtin_ia32_pmovsxwq256_mask", - "avx512.mask.pmovsxw.q.512" => "__builtin_ia32_pmovsxwq512_mask", "avx512.mask.pmovus.db.128" => "__builtin_ia32_pmovusdb128_mask", "avx512.mask.pmovus.db.256" => "__builtin_ia32_pmovusdb256_mask", "avx512.mask.pmovus.db.512" => "__builtin_ia32_pmovusdb512_mask", @@ -8981,191 +8314,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.pmovus.wb.mem.128" => "__builtin_ia32_pmovuswb128mem_mask", "avx512.mask.pmovus.wb.mem.256" => "__builtin_ia32_pmovuswb256mem_mask", "avx512.mask.pmovus.wb.mem.512" => "__builtin_ia32_pmovuswb512mem_mask", - "avx512.mask.pmovzxb.d.128" => "__builtin_ia32_pmovzxbd128_mask", - "avx512.mask.pmovzxb.d.256" => "__builtin_ia32_pmovzxbd256_mask", - "avx512.mask.pmovzxb.d.512" => "__builtin_ia32_pmovzxbd512_mask", - "avx512.mask.pmovzxb.q.128" => "__builtin_ia32_pmovzxbq128_mask", - "avx512.mask.pmovzxb.q.256" => "__builtin_ia32_pmovzxbq256_mask", - "avx512.mask.pmovzxb.q.512" => "__builtin_ia32_pmovzxbq512_mask", - "avx512.mask.pmovzxb.w.128" => "__builtin_ia32_pmovzxbw128_mask", - "avx512.mask.pmovzxb.w.256" => "__builtin_ia32_pmovzxbw256_mask", - "avx512.mask.pmovzxb.w.512" => "__builtin_ia32_pmovzxbw512_mask", - "avx512.mask.pmovzxd.q.128" => "__builtin_ia32_pmovzxdq128_mask", - "avx512.mask.pmovzxd.q.256" => "__builtin_ia32_pmovzxdq256_mask", - "avx512.mask.pmovzxd.q.512" => "__builtin_ia32_pmovzxdq512_mask", - "avx512.mask.pmovzxw.d.128" => "__builtin_ia32_pmovzxwd128_mask", - "avx512.mask.pmovzxw.d.256" => "__builtin_ia32_pmovzxwd256_mask", - "avx512.mask.pmovzxw.d.512" => "__builtin_ia32_pmovzxwd512_mask", - "avx512.mask.pmovzxw.q.128" => "__builtin_ia32_pmovzxwq128_mask", - "avx512.mask.pmovzxw.q.256" => "__builtin_ia32_pmovzxwq256_mask", - "avx512.mask.pmovzxw.q.512" => "__builtin_ia32_pmovzxwq512_mask", - "avx512.mask.pmul.dq.128" => "__builtin_ia32_pmuldq128_mask", - "avx512.mask.pmul.dq.256" => "__builtin_ia32_pmuldq256_mask", - "avx512.mask.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask", - "avx512.mask.pmul.hr.sw.128" => "__builtin_ia32_pmulhrsw128_mask", - "avx512.mask.pmul.hr.sw.256" => "__builtin_ia32_pmulhrsw256_mask", - "avx512.mask.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512_mask", - "avx512.mask.pmulh.w.128" => "__builtin_ia32_pmulhw128_mask", - "avx512.mask.pmulh.w.256" => "__builtin_ia32_pmulhw256_mask", - "avx512.mask.pmulh.w.512" => "__builtin_ia32_pmulhw512_mask", - "avx512.mask.pmulhu.w.128" => "__builtin_ia32_pmulhuw128_mask", - "avx512.mask.pmulhu.w.256" => "__builtin_ia32_pmulhuw256_mask", - "avx512.mask.pmulhu.w.512" => "__builtin_ia32_pmulhuw512_mask", - "avx512.mask.pmull.d.128" => "__builtin_ia32_pmulld128_mask", - "avx512.mask.pmull.d.256" => "__builtin_ia32_pmulld256_mask", - "avx512.mask.pmull.d.512" => "__builtin_ia32_pmulld512_mask", - "avx512.mask.pmull.q.128" => "__builtin_ia32_pmullq128_mask", - "avx512.mask.pmull.q.256" => "__builtin_ia32_pmullq256_mask", - "avx512.mask.pmull.q.512" => "__builtin_ia32_pmullq512_mask", - "avx512.mask.pmull.w.128" => "__builtin_ia32_pmullw128_mask", - "avx512.mask.pmull.w.256" => "__builtin_ia32_pmullw256_mask", - "avx512.mask.pmull.w.512" => "__builtin_ia32_pmullw512_mask", - "avx512.mask.pmultishift.qb.128" => "__builtin_ia32_vpmultishiftqb128_mask", - "avx512.mask.pmultishift.qb.256" => "__builtin_ia32_vpmultishiftqb256_mask", - "avx512.mask.pmultishift.qb.512" => "__builtin_ia32_vpmultishiftqb512_mask", - "avx512.mask.pmulu.dq.128" => "__builtin_ia32_pmuludq128_mask", - "avx512.mask.pmulu.dq.256" => "__builtin_ia32_pmuludq256_mask", - "avx512.mask.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask", - "avx512.mask.prol.d.128" => "__builtin_ia32_prold128_mask", - "avx512.mask.prol.d.256" => "__builtin_ia32_prold256_mask", - "avx512.mask.prol.d.512" => "__builtin_ia32_prold512_mask", - "avx512.mask.prol.q.128" => "__builtin_ia32_prolq128_mask", - "avx512.mask.prol.q.256" => "__builtin_ia32_prolq256_mask", - "avx512.mask.prol.q.512" => "__builtin_ia32_prolq512_mask", - "avx512.mask.prolv.d.128" => "__builtin_ia32_prolvd128_mask", - "avx512.mask.prolv.d.256" => "__builtin_ia32_prolvd256_mask", - "avx512.mask.prolv.d.512" => "__builtin_ia32_prolvd512_mask", - "avx512.mask.prolv.q.128" => "__builtin_ia32_prolvq128_mask", - "avx512.mask.prolv.q.256" => "__builtin_ia32_prolvq256_mask", - "avx512.mask.prolv.q.512" => "__builtin_ia32_prolvq512_mask", - "avx512.mask.pror.d.128" => "__builtin_ia32_prord128_mask", - "avx512.mask.pror.d.256" => "__builtin_ia32_prord256_mask", - "avx512.mask.pror.d.512" => "__builtin_ia32_prord512_mask", - "avx512.mask.pror.q.128" => "__builtin_ia32_prorq128_mask", - "avx512.mask.pror.q.256" => "__builtin_ia32_prorq256_mask", - "avx512.mask.pror.q.512" => "__builtin_ia32_prorq512_mask", - "avx512.mask.prorv.d.128" => "__builtin_ia32_prorvd128_mask", - "avx512.mask.prorv.d.256" => "__builtin_ia32_prorvd256_mask", - "avx512.mask.prorv.d.512" => "__builtin_ia32_prorvd512_mask", - "avx512.mask.prorv.q.128" => "__builtin_ia32_prorvq128_mask", - "avx512.mask.prorv.q.256" => "__builtin_ia32_prorvq256_mask", - "avx512.mask.prorv.q.512" => "__builtin_ia32_prorvq512_mask", - "avx512.mask.pshuf.b.128" => "__builtin_ia32_pshufb128_mask", - "avx512.mask.pshuf.b.256" => "__builtin_ia32_pshufb256_mask", - "avx512.mask.pshuf.b.512" => "__builtin_ia32_pshufb512_mask", - "avx512.mask.psll.d" => "__builtin_ia32_pslld512_mask", - "avx512.mask.psll.d.128" => "__builtin_ia32_pslld128_mask", - "avx512.mask.psll.d.256" => "__builtin_ia32_pslld256_mask", - "avx512.mask.psll.di.128" => "__builtin_ia32_pslldi128_mask", - "avx512.mask.psll.di.256" => "__builtin_ia32_pslldi256_mask", - "avx512.mask.psll.di.512" => "__builtin_ia32_pslldi512_mask", - "avx512.mask.psll.q" => "__builtin_ia32_psllq512_mask", - "avx512.mask.psll.q.128" => "__builtin_ia32_psllq128_mask", - "avx512.mask.psll.q.256" => "__builtin_ia32_psllq256_mask", - "avx512.mask.psll.qi.128" => "__builtin_ia32_psllqi128_mask", - "avx512.mask.psll.qi.256" => "__builtin_ia32_psllqi256_mask", - "avx512.mask.psll.qi.512" => "__builtin_ia32_psllqi512_mask", - "avx512.mask.psll.w.128" => "__builtin_ia32_psllw128_mask", - "avx512.mask.psll.w.256" => "__builtin_ia32_psllw256_mask", - "avx512.mask.psll.w.512" => "__builtin_ia32_psllw512_mask", - "avx512.mask.psll.wi.128" => "__builtin_ia32_psllwi128_mask", - "avx512.mask.psll.wi.256" => "__builtin_ia32_psllwi256_mask", - "avx512.mask.psll.wi.512" => "__builtin_ia32_psllwi512_mask", - "avx512.mask.psllv.d" => "__builtin_ia32_psllv16si_mask", - "avx512.mask.psllv.q" => "__builtin_ia32_psllv8di_mask", - "avx512.mask.psllv16.hi" => "__builtin_ia32_psllv16hi_mask", - "avx512.mask.psllv2.di" => "__builtin_ia32_psllv2di_mask", - "avx512.mask.psllv32hi" => "__builtin_ia32_psllv32hi_mask", - "avx512.mask.psllv4.di" => "__builtin_ia32_psllv4di_mask", - "avx512.mask.psllv4.si" => "__builtin_ia32_psllv4si_mask", - "avx512.mask.psllv8.hi" => "__builtin_ia32_psllv8hi_mask", - "avx512.mask.psllv8.si" => "__builtin_ia32_psllv8si_mask", - "avx512.mask.psra.d" => "__builtin_ia32_psrad512_mask", - "avx512.mask.psra.d.128" => "__builtin_ia32_psrad128_mask", - "avx512.mask.psra.d.256" => "__builtin_ia32_psrad256_mask", - "avx512.mask.psra.di.128" => "__builtin_ia32_psradi128_mask", - "avx512.mask.psra.di.256" => "__builtin_ia32_psradi256_mask", - "avx512.mask.psra.di.512" => "__builtin_ia32_psradi512_mask", - "avx512.mask.psra.q" => "__builtin_ia32_psraq512_mask", - "avx512.mask.psra.q.128" => "__builtin_ia32_psraq128_mask", - "avx512.mask.psra.q.256" => "__builtin_ia32_psraq256_mask", - "avx512.mask.psra.qi.128" => "__builtin_ia32_psraqi128_mask", - "avx512.mask.psra.qi.256" => "__builtin_ia32_psraqi256_mask", - "avx512.mask.psra.qi.512" => "__builtin_ia32_psraqi512_mask", - "avx512.mask.psra.w.128" => "__builtin_ia32_psraw128_mask", - "avx512.mask.psra.w.256" => "__builtin_ia32_psraw256_mask", - "avx512.mask.psra.w.512" => "__builtin_ia32_psraw512_mask", - "avx512.mask.psra.wi.128" => "__builtin_ia32_psrawi128_mask", - "avx512.mask.psra.wi.256" => "__builtin_ia32_psrawi256_mask", - "avx512.mask.psra.wi.512" => "__builtin_ia32_psrawi512_mask", - "avx512.mask.psrav.d" => "__builtin_ia32_psrav16si_mask", - "avx512.mask.psrav.q" => "__builtin_ia32_psrav8di_mask", - "avx512.mask.psrav.q.128" => "__builtin_ia32_psravq128_mask", - "avx512.mask.psrav.q.256" => "__builtin_ia32_psravq256_mask", - "avx512.mask.psrav16.hi" => "__builtin_ia32_psrav16hi_mask", - "avx512.mask.psrav32.hi" => "__builtin_ia32_psrav32hi_mask", - "avx512.mask.psrav4.si" => "__builtin_ia32_psrav4si_mask", - "avx512.mask.psrav8.hi" => "__builtin_ia32_psrav8hi_mask", - "avx512.mask.psrav8.si" => "__builtin_ia32_psrav8si_mask", - "avx512.mask.psrl.d" => "__builtin_ia32_psrld512_mask", - "avx512.mask.psrl.d.128" => "__builtin_ia32_psrld128_mask", - "avx512.mask.psrl.d.256" => "__builtin_ia32_psrld256_mask", - "avx512.mask.psrl.di.128" => "__builtin_ia32_psrldi128_mask", - "avx512.mask.psrl.di.256" => "__builtin_ia32_psrldi256_mask", - "avx512.mask.psrl.di.512" => "__builtin_ia32_psrldi512_mask", - "avx512.mask.psrl.q" => "__builtin_ia32_psrlq512_mask", - "avx512.mask.psrl.q.128" => "__builtin_ia32_psrlq128_mask", - "avx512.mask.psrl.q.256" => "__builtin_ia32_psrlq256_mask", - "avx512.mask.psrl.qi.128" => "__builtin_ia32_psrlqi128_mask", - "avx512.mask.psrl.qi.256" => "__builtin_ia32_psrlqi256_mask", - "avx512.mask.psrl.qi.512" => "__builtin_ia32_psrlqi512_mask", - "avx512.mask.psrl.w.128" => "__builtin_ia32_psrlw128_mask", - "avx512.mask.psrl.w.256" => "__builtin_ia32_psrlw256_mask", - "avx512.mask.psrl.w.512" => "__builtin_ia32_psrlw512_mask", - "avx512.mask.psrl.wi.128" => "__builtin_ia32_psrlwi128_mask", - "avx512.mask.psrl.wi.256" => "__builtin_ia32_psrlwi256_mask", - "avx512.mask.psrl.wi.512" => "__builtin_ia32_psrlwi512_mask", - "avx512.mask.psrlv.d" => "__builtin_ia32_psrlv16si_mask", - "avx512.mask.psrlv.q" => "__builtin_ia32_psrlv8di_mask", - "avx512.mask.psrlv16.hi" => "__builtin_ia32_psrlv16hi_mask", - "avx512.mask.psrlv2.di" => "__builtin_ia32_psrlv2di_mask", - "avx512.mask.psrlv32hi" => "__builtin_ia32_psrlv32hi_mask", - "avx512.mask.psrlv4.di" => "__builtin_ia32_psrlv4di_mask", - "avx512.mask.psrlv4.si" => "__builtin_ia32_psrlv4si_mask", - "avx512.mask.psrlv8.hi" => "__builtin_ia32_psrlv8hi_mask", - "avx512.mask.psrlv8.si" => "__builtin_ia32_psrlv8si_mask", - "avx512.mask.psub.b.128" => "__builtin_ia32_psubb128_mask", - "avx512.mask.psub.b.256" => "__builtin_ia32_psubb256_mask", - "avx512.mask.psub.b.512" => "__builtin_ia32_psubb512_mask", - "avx512.mask.psub.d.128" => "__builtin_ia32_psubd128_mask", - "avx512.mask.psub.d.256" => "__builtin_ia32_psubd256_mask", - "avx512.mask.psub.d.512" => "__builtin_ia32_psubd512_mask", - "avx512.mask.psub.q.128" => "__builtin_ia32_psubq128_mask", - "avx512.mask.psub.q.256" => "__builtin_ia32_psubq256_mask", - "avx512.mask.psub.q.512" => "__builtin_ia32_psubq512_mask", - "avx512.mask.psub.w.128" => "__builtin_ia32_psubw128_mask", - "avx512.mask.psub.w.256" => "__builtin_ia32_psubw256_mask", - "avx512.mask.psub.w.512" => "__builtin_ia32_psubw512_mask", - "avx512.mask.psubs.b.128" => "__builtin_ia32_psubsb128_mask", - "avx512.mask.psubs.b.256" => "__builtin_ia32_psubsb256_mask", - "avx512.mask.psubs.b.512" => "__builtin_ia32_psubsb512_mask", - "avx512.mask.psubs.w.128" => "__builtin_ia32_psubsw128_mask", - "avx512.mask.psubs.w.256" => "__builtin_ia32_psubsw256_mask", - "avx512.mask.psubs.w.512" => "__builtin_ia32_psubsw512_mask", - "avx512.mask.psubus.b.128" => "__builtin_ia32_psubusb128_mask", - "avx512.mask.psubus.b.256" => "__builtin_ia32_psubusb256_mask", - "avx512.mask.psubus.b.512" => "__builtin_ia32_psubusb512_mask", - "avx512.mask.psubus.w.128" => "__builtin_ia32_psubusw128_mask", - "avx512.mask.psubus.w.256" => "__builtin_ia32_psubusw256_mask", - "avx512.mask.psubus.w.512" => "__builtin_ia32_psubusw512_mask", - "avx512.mask.pternlog.d.128" => "__builtin_ia32_pternlogd128_mask", - "avx512.mask.pternlog.d.256" => "__builtin_ia32_pternlogd256_mask", - "avx512.mask.pternlog.d.512" => "__builtin_ia32_pternlogd512_mask", - "avx512.mask.pternlog.q.128" => "__builtin_ia32_pternlogq128_mask", - "avx512.mask.pternlog.q.256" => "__builtin_ia32_pternlogq256_mask", - "avx512.mask.pternlog.q.512" => "__builtin_ia32_pternlogq512_mask", - "avx512.mask.ptestm.d.512" => "__builtin_ia32_ptestmd512", - "avx512.mask.ptestm.q.512" => "__builtin_ia32_ptestmq512", "avx512.mask.range.pd.128" => "__builtin_ia32_rangepd128_mask", "avx512.mask.range.pd.256" => "__builtin_ia32_rangepd256_mask", "avx512.mask.range.pd.512" => "__builtin_ia32_rangepd512_mask", @@ -9198,181 +8346,11 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.mask.scalef.ps.512" => "__builtin_ia32_scalefps512_mask", // [INVALID CONVERSION]: "avx512.mask.scalef.sd" => "__builtin_ia32_scalefsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.scalef.ss" => "__builtin_ia32_scalefss_round_mask", - "avx512.mask.shuf.f32x4" => "__builtin_ia32_shuf_f32x4_mask", - "avx512.mask.shuf.f32x4.256" => "__builtin_ia32_shuf_f32x4_256_mask", - "avx512.mask.shuf.f64x2" => "__builtin_ia32_shuf_f64x2_mask", - "avx512.mask.shuf.f64x2.256" => "__builtin_ia32_shuf_f64x2_256_mask", - "avx512.mask.shuf.i32x4" => "__builtin_ia32_shuf_i32x4_mask", - "avx512.mask.shuf.i32x4.256" => "__builtin_ia32_shuf_i32x4_256_mask", - "avx512.mask.shuf.i64x2" => "__builtin_ia32_shuf_i64x2_mask", - "avx512.mask.shuf.i64x2.256" => "__builtin_ia32_shuf_i64x2_256_mask", - "avx512.mask.shuf.pd.128" => "__builtin_ia32_shufpd128_mask", - "avx512.mask.shuf.pd.256" => "__builtin_ia32_shufpd256_mask", - "avx512.mask.shuf.pd.512" => "__builtin_ia32_shufpd512_mask", - "avx512.mask.shuf.ps.128" => "__builtin_ia32_shufps128_mask", - "avx512.mask.shuf.ps.256" => "__builtin_ia32_shufps256_mask", - "avx512.mask.shuf.ps.512" => "__builtin_ia32_shufps512_mask", - "avx512.mask.sqrt.pd.128" => "__builtin_ia32_sqrtpd128_mask", - "avx512.mask.sqrt.pd.256" => "__builtin_ia32_sqrtpd256_mask", - "avx512.mask.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", - "avx512.mask.sqrt.ps.128" => "__builtin_ia32_sqrtps128_mask", - "avx512.mask.sqrt.ps.256" => "__builtin_ia32_sqrtps256_mask", - "avx512.mask.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", - // [INVALID CONVERSION]: "avx512.mask.sqrt.sd" => "__builtin_ia32_sqrtsd_round_mask", - // [INVALID CONVERSION]: "avx512.mask.sqrt.ss" => "__builtin_ia32_sqrtss_round_mask", - "avx512.mask.store.ss" => "__builtin_ia32_storess_mask", - "avx512.mask.storeu.d.512" => "__builtin_ia32_storedqusi512_mask", - "avx512.mask.storeu.pd.512" => "__builtin_ia32_storeupd512_mask", - "avx512.mask.storeu.ps.512" => "__builtin_ia32_storeups512_mask", - "avx512.mask.storeu.q.512" => "__builtin_ia32_storedqudi512_mask", - "avx512.mask.sub.pd.128" => "__builtin_ia32_subpd128_mask", - "avx512.mask.sub.pd.256" => "__builtin_ia32_subpd256_mask", - "avx512.mask.sub.pd.512" => "__builtin_ia32_subpd512_mask", - "avx512.mask.sub.ps.128" => "__builtin_ia32_subps128_mask", - "avx512.mask.sub.ps.256" => "__builtin_ia32_subps256_mask", - "avx512.mask.sub.ps.512" => "__builtin_ia32_subps512_mask", // [INVALID CONVERSION]: "avx512.mask.sub.sd.round" => "__builtin_ia32_subsd_round_mask", // [INVALID CONVERSION]: "avx512.mask.sub.ss.round" => "__builtin_ia32_subss_round_mask", - "avx512.mask.valign.d.128" => "__builtin_ia32_alignd128_mask", - "avx512.mask.valign.d.256" => "__builtin_ia32_alignd256_mask", - "avx512.mask.valign.d.512" => "__builtin_ia32_alignd512_mask", - "avx512.mask.valign.q.128" => "__builtin_ia32_alignq128_mask", - "avx512.mask.valign.q.256" => "__builtin_ia32_alignq256_mask", - "avx512.mask.valign.q.512" => "__builtin_ia32_alignq512_mask", - "avx512.mask.vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps_mask", - "avx512.mask.vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256_mask", - "avx512.mask.vcvtph2ps.512" => "__builtin_ia32_vcvtph2ps512_mask", "avx512.mask.vcvtps2ph.128" => "__builtin_ia32_vcvtps2ph_mask", "avx512.mask.vcvtps2ph.256" => "__builtin_ia32_vcvtps2ph256_mask", "avx512.mask.vcvtps2ph.512" => "__builtin_ia32_vcvtps2ph512_mask", - "avx512.mask.vextractf32x4.256" => "__builtin_ia32_extractf32x4_256_mask", - "avx512.mask.vextractf32x4.512" => "__builtin_ia32_extractf32x4_mask", - "avx512.mask.vextractf32x8.512" => "__builtin_ia32_extractf32x8_mask", - "avx512.mask.vextractf64x2.256" => "__builtin_ia32_extractf64x2_256_mask", - "avx512.mask.vextractf64x2.512" => "__builtin_ia32_extractf64x2_512_mask", - "avx512.mask.vextractf64x4.512" => "__builtin_ia32_extractf64x4_mask", - "avx512.mask.vextracti32x4.256" => "__builtin_ia32_extracti32x4_256_mask", - "avx512.mask.vextracti32x4.512" => "__builtin_ia32_extracti32x4_mask", - "avx512.mask.vextracti32x8.512" => "__builtin_ia32_extracti32x8_mask", - "avx512.mask.vextracti64x2.256" => "__builtin_ia32_extracti64x2_256_mask", - "avx512.mask.vextracti64x2.512" => "__builtin_ia32_extracti64x2_512_mask", - "avx512.mask.vextracti64x4.512" => "__builtin_ia32_extracti64x4_mask", - "avx512.mask.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask", - "avx512.mask.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask", - "avx512.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", - "avx512.mask.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask", - "avx512.mask.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask", - "avx512.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", - "avx512.mask.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask", - "avx512.mask.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask", - "avx512.mask.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask", - "avx512.mask.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask", - "avx512.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", - "avx512.mask.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask", - "avx512.mask.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask", - "avx512.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", - "avx512.mask.vfnmadd.pd.128" => "__builtin_ia32_vfnmaddpd128_mask", - "avx512.mask.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256_mask", - "avx512.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", - "avx512.mask.vfnmadd.ps.128" => "__builtin_ia32_vfnmaddps128_mask", - "avx512.mask.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256_mask", - "avx512.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", - "avx512.mask.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask", - "avx512.mask.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask", - "avx512.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", - "avx512.mask.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask", - "avx512.mask.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask", - "avx512.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", - "avx512.mask.vpermi2var.d.128" => "__builtin_ia32_vpermi2vard128_mask", - "avx512.mask.vpermi2var.d.256" => "__builtin_ia32_vpermi2vard256_mask", - "avx512.mask.vpermi2var.d.512" => "__builtin_ia32_vpermi2vard512_mask", - "avx512.mask.vpermi2var.hi.128" => "__builtin_ia32_vpermi2varhi128_mask", - "avx512.mask.vpermi2var.hi.256" => "__builtin_ia32_vpermi2varhi256_mask", - "avx512.mask.vpermi2var.hi.512" => "__builtin_ia32_vpermi2varhi512_mask", - "avx512.mask.vpermi2var.pd.128" => "__builtin_ia32_vpermi2varpd128_mask", - "avx512.mask.vpermi2var.pd.256" => "__builtin_ia32_vpermi2varpd256_mask", - "avx512.mask.vpermi2var.pd.512" => "__builtin_ia32_vpermi2varpd512_mask", - "avx512.mask.vpermi2var.ps.128" => "__builtin_ia32_vpermi2varps128_mask", - "avx512.mask.vpermi2var.ps.256" => "__builtin_ia32_vpermi2varps256_mask", - "avx512.mask.vpermi2var.ps.512" => "__builtin_ia32_vpermi2varps512_mask", - "avx512.mask.vpermi2var.q.128" => "__builtin_ia32_vpermi2varq128_mask", - "avx512.mask.vpermi2var.q.256" => "__builtin_ia32_vpermi2varq256_mask", - "avx512.mask.vpermi2var.q.512" => "__builtin_ia32_vpermi2varq512_mask", - "avx512.mask.vpermi2var.qi.128" => "__builtin_ia32_vpermi2varqi128_mask", - "avx512.mask.vpermi2var.qi.256" => "__builtin_ia32_vpermi2varqi256_mask", - "avx512.mask.vpermi2var.qi.512" => "__builtin_ia32_vpermi2varqi512_mask", - "avx512.mask.vpermilvar.pd.128" => "__builtin_ia32_vpermilvarpd_mask", - "avx512.mask.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256_mask", - "avx512.mask.vpermilvar.pd.512" => "__builtin_ia32_vpermilvarpd512_mask", - "avx512.mask.vpermilvar.ps.128" => "__builtin_ia32_vpermilvarps_mask", - "avx512.mask.vpermilvar.ps.256" => "__builtin_ia32_vpermilvarps256_mask", - "avx512.mask.vpermilvar.ps.512" => "__builtin_ia32_vpermilvarps512_mask", - "avx512.mask.vpermt.d.512" => "__builtin_ia32_vpermt2vard512_mask", - "avx512.mask.vpermt.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", - "avx512.mask.vpermt.ps.512" => "__builtin_ia32_vpermt2varps512_mask", - "avx512.mask.vpermt.q.512" => "__builtin_ia32_vpermt2varq512_mask", - "avx512.mask.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_mask", - "avx512.mask.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_mask", - "avx512.mask.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_mask", - "avx512.mask.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_mask", - "avx512.mask.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_mask", - "avx512.mask.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_mask", - "avx512.mask.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_mask", - "avx512.mask.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_mask", - "avx512.mask.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", - "avx512.mask.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_mask", - "avx512.mask.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_mask", - "avx512.mask.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_mask", - "avx512.mask.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_mask", - "avx512.mask.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_mask", - "avx512.mask.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_mask", - "avx512.mask.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_mask", - "avx512.mask.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_mask", - "avx512.mask.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_mask", - "avx512.mask.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_mask", - "avx512.mask.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_mask", - "avx512.mask.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_mask", - "avx512.mask.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_mask", - "avx512.mask.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_mask", - "avx512.mask.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_mask", - "avx512.mask.xor.pd.128" => "__builtin_ia32_xorpd128_mask", - "avx512.mask.xor.pd.256" => "__builtin_ia32_xorpd256_mask", - "avx512.mask.xor.pd.512" => "__builtin_ia32_xorpd512_mask", - "avx512.mask.xor.ps.128" => "__builtin_ia32_xorps128_mask", - "avx512.mask.xor.ps.256" => "__builtin_ia32_xorps256_mask", - "avx512.mask.xor.ps.512" => "__builtin_ia32_xorps512_mask", - "avx512.mask3.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask3", - "avx512.mask3.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask3", - "avx512.mask3.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask3", - "avx512.mask3.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask3", - "avx512.mask3.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask3", - "avx512.mask3.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask3", - "avx512.mask3.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask3", - "avx512.mask3.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask3", - "avx512.mask3.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask3", - "avx512.mask3.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask3", - "avx512.mask3.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask3", - "avx512.mask3.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask3", - "avx512.mask3.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask3", - "avx512.mask3.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask3", - "avx512.mask3.vfmsub.pd.128" => "__builtin_ia32_vfmsubpd128_mask3", - "avx512.mask3.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256_mask3", - "avx512.mask3.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask3", - "avx512.mask3.vfmsub.ps.128" => "__builtin_ia32_vfmsubps128_mask3", - "avx512.mask3.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256_mask3", - "avx512.mask3.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask3", - "avx512.mask3.vfmsubadd.pd.128" => "__builtin_ia32_vfmsubaddpd128_mask3", - "avx512.mask3.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256_mask3", - "avx512.mask3.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask3", - "avx512.mask3.vfmsubadd.ps.128" => "__builtin_ia32_vfmsubaddps128_mask3", - "avx512.mask3.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256_mask3", - "avx512.mask3.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask3", - "avx512.mask3.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask3", - "avx512.mask3.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask3", - "avx512.mask3.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask3", - "avx512.mask3.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask3", - "avx512.mask3.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask3", - "avx512.mask3.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask3", "avx512.maskz.fixupimm.pd.128" => "__builtin_ia32_fixupimmpd128_maskz", "avx512.maskz.fixupimm.pd.256" => "__builtin_ia32_fixupimmpd256_maskz", "avx512.maskz.fixupimm.pd.512" => "__builtin_ia32_fixupimmpd512_maskz", @@ -9381,55 +8359,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.maskz.fixupimm.ps.512" => "__builtin_ia32_fixupimmps512_maskz", "avx512.maskz.fixupimm.sd" => "__builtin_ia32_fixupimmsd_maskz", "avx512.maskz.fixupimm.ss" => "__builtin_ia32_fixupimmss_maskz", - "avx512.maskz.pternlog.d.128" => "__builtin_ia32_pternlogd128_maskz", - "avx512.maskz.pternlog.d.256" => "__builtin_ia32_pternlogd256_maskz", - "avx512.maskz.pternlog.d.512" => "__builtin_ia32_pternlogd512_maskz", - "avx512.maskz.pternlog.q.128" => "__builtin_ia32_pternlogq128_maskz", - "avx512.maskz.pternlog.q.256" => "__builtin_ia32_pternlogq256_maskz", - "avx512.maskz.pternlog.q.512" => "__builtin_ia32_pternlogq512_maskz", - "avx512.maskz.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_maskz", - "avx512.maskz.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_maskz", - "avx512.maskz.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_maskz", - "avx512.maskz.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_maskz", - "avx512.maskz.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_maskz", - "avx512.maskz.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_maskz", - "avx512.maskz.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_maskz", - "avx512.maskz.vfmadd.ss" => "__builtin_ia32_vfmaddss3_maskz", - "avx512.maskz.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_maskz", - "avx512.maskz.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_maskz", - "avx512.maskz.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_maskz", - "avx512.maskz.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_maskz", - "avx512.maskz.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_maskz", - "avx512.maskz.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_maskz", - "avx512.maskz.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_maskz", - "avx512.maskz.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_maskz", - "avx512.maskz.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_maskz", - "avx512.maskz.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_maskz", - "avx512.maskz.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_maskz", - "avx512.maskz.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_maskz", - "avx512.maskz.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_maskz", - "avx512.maskz.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_maskz", - "avx512.maskz.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_maskz", - "avx512.maskz.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_maskz", - "avx512.maskz.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_maskz", - "avx512.maskz.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_maskz", - "avx512.maskz.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_maskz", - "avx512.maskz.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_maskz", - "avx512.maskz.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_maskz", - "avx512.maskz.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_maskz", - "avx512.maskz.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_maskz", - "avx512.maskz.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_maskz", - "avx512.maskz.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_maskz", - "avx512.maskz.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_maskz", - "avx512.maskz.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_maskz", - "avx512.maskz.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_maskz", - "avx512.maskz.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_maskz", - "avx512.maskz.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_maskz", "avx512.max.pd.512" => "__builtin_ia32_maxpd512", "avx512.max.ps.512" => "__builtin_ia32_maxps512", "avx512.min.pd.512" => "__builtin_ia32_minpd512", "avx512.min.ps.512" => "__builtin_ia32_minps512", - "avx512.movntdqa" => "__builtin_ia32_movntdqa512", "avx512.mul.pd.512" => "__builtin_ia32_mulpd512", "avx512.mul.ps.512" => "__builtin_ia32_mulps512", "avx512.packssdw.512" => "__builtin_ia32_packssdw512", @@ -9438,8 +8371,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.packuswb.512" => "__builtin_ia32_packuswb512", "avx512.pavg.b.512" => "__builtin_ia32_pavgb512", "avx512.pavg.w.512" => "__builtin_ia32_pavgw512", - "avx512.pbroadcastd.512" => "__builtin_ia32_pbroadcastd512", - "avx512.pbroadcastq.512" => "__builtin_ia32_pbroadcastq512", "avx512.permvar.df.256" => "__builtin_ia32_permvardf256", "avx512.permvar.df.512" => "__builtin_ia32_permvardf512", "avx512.permvar.di.256" => "__builtin_ia32_permvardi256", @@ -9454,11 +8385,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.permvar.si.512" => "__builtin_ia32_permvarsi512", "avx512.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512", "avx512.pmaddw.d.512" => "__builtin_ia32_pmaddwd512", - "avx512.pmovzxbd" => "__builtin_ia32_pmovzxbd512", - "avx512.pmovzxbq" => "__builtin_ia32_pmovzxbq512", - "avx512.pmovzxdq" => "__builtin_ia32_pmovzxdq512", - "avx512.pmovzxwd" => "__builtin_ia32_pmovzxwd512", - "avx512.pmovzxwq" => "__builtin_ia32_pmovzxwq512", "avx512.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512", "avx512.pmulh.w.512" => "__builtin_ia32_pmulhw512", "avx512.pmulhu.w.512" => "__builtin_ia32_pmulhuw512", @@ -9468,8 +8394,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.psad.bw.512" => "__builtin_ia32_psadbw512", "avx512.pshuf.b.512" => "__builtin_ia32_pshufb512", "avx512.psll.d.512" => "__builtin_ia32_pslld512", - "avx512.psll.dq" => "__builtin_ia32_pslldqi512", - "avx512.psll.dq.bs" => "__builtin_ia32_pslldqi512_byteshift", "avx512.psll.q.512" => "__builtin_ia32_psllq512", "avx512.psll.w.512" => "__builtin_ia32_psllw512", "avx512.pslli.d.512" => "__builtin_ia32_pslldi512", @@ -9498,8 +8422,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.psrav.w.256" => "__builtin_ia32_psrav16hi", "avx512.psrav.w.512" => "__builtin_ia32_psrav32hi", "avx512.psrl.d.512" => "__builtin_ia32_psrld512", - "avx512.psrl.dq" => "__builtin_ia32_psrldqi512", - "avx512.psrl.dq.bs" => "__builtin_ia32_psrldqi512_byteshift", "avx512.psrl.q.512" => "__builtin_ia32_psrlq512", "avx512.psrl.w.512" => "__builtin_ia32_psrlw512", "avx512.psrli.d.512" => "__builtin_ia32_psrldi512", @@ -9516,30 +8438,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.pternlog.q.128" => "__builtin_ia32_pternlogq128", "avx512.pternlog.q.256" => "__builtin_ia32_pternlogq256", "avx512.pternlog.q.512" => "__builtin_ia32_pternlogq512", - "avx512.ptestm.b.128" => "__builtin_ia32_ptestmb128", - "avx512.ptestm.b.256" => "__builtin_ia32_ptestmb256", - "avx512.ptestm.b.512" => "__builtin_ia32_ptestmb512", - "avx512.ptestm.d.128" => "__builtin_ia32_ptestmd128", - "avx512.ptestm.d.256" => "__builtin_ia32_ptestmd256", - "avx512.ptestm.d.512" => "__builtin_ia32_ptestmd512", - "avx512.ptestm.q.128" => "__builtin_ia32_ptestmq128", - "avx512.ptestm.q.256" => "__builtin_ia32_ptestmq256", - "avx512.ptestm.q.512" => "__builtin_ia32_ptestmq512", - "avx512.ptestm.w.128" => "__builtin_ia32_ptestmw128", - "avx512.ptestm.w.256" => "__builtin_ia32_ptestmw256", - "avx512.ptestm.w.512" => "__builtin_ia32_ptestmw512", - "avx512.ptestnm.b.128" => "__builtin_ia32_ptestnmb128", - "avx512.ptestnm.b.256" => "__builtin_ia32_ptestnmb256", - "avx512.ptestnm.b.512" => "__builtin_ia32_ptestnmb512", - "avx512.ptestnm.d.128" => "__builtin_ia32_ptestnmd128", - "avx512.ptestnm.d.256" => "__builtin_ia32_ptestnmd256", - "avx512.ptestnm.d.512" => "__builtin_ia32_ptestnmd512", - "avx512.ptestnm.q.128" => "__builtin_ia32_ptestnmq128", - "avx512.ptestnm.q.256" => "__builtin_ia32_ptestnmq256", - "avx512.ptestnm.q.512" => "__builtin_ia32_ptestnmq512", - "avx512.ptestnm.w.128" => "__builtin_ia32_ptestnmw128", - "avx512.ptestnm.w.256" => "__builtin_ia32_ptestnmw256", - "avx512.ptestnm.w.512" => "__builtin_ia32_ptestnmw512", "avx512.rcp14.pd.128" => "__builtin_ia32_rcp14pd128_mask", "avx512.rcp14.pd.256" => "__builtin_ia32_rcp14pd256_mask", "avx512.rcp14.pd.512" => "__builtin_ia32_rcp14pd512_mask", @@ -9548,14 +8446,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.rcp14.ps.512" => "__builtin_ia32_rcp14ps512_mask", "avx512.rcp14.sd" => "__builtin_ia32_rcp14sd_mask", "avx512.rcp14.ss" => "__builtin_ia32_rcp14ss_mask", - "avx512.rcp28.pd" => "__builtin_ia32_rcp28pd_mask", - "avx512.rcp28.ps" => "__builtin_ia32_rcp28ps_mask", - "avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_mask", - // [DUPLICATE]: "avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_round_mask", - "avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_mask", - // [DUPLICATE]: "avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_round_mask", - "avx512.rndscale.sd" => "__builtin_ia32_rndscalesd", - "avx512.rndscale.ss" => "__builtin_ia32_rndscaless", "avx512.rsqrt14.pd.128" => "__builtin_ia32_rsqrt14pd128_mask", "avx512.rsqrt14.pd.256" => "__builtin_ia32_rsqrt14pd256_mask", "avx512.rsqrt14.pd.512" => "__builtin_ia32_rsqrt14pd512_mask", @@ -9564,50 +8454,8 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "avx512.rsqrt14.ps.512" => "__builtin_ia32_rsqrt14ps512_mask", "avx512.rsqrt14.sd" => "__builtin_ia32_rsqrt14sd_mask", "avx512.rsqrt14.ss" => "__builtin_ia32_rsqrt14ss_mask", - "avx512.rsqrt28.pd" => "__builtin_ia32_rsqrt28pd_mask", - "avx512.rsqrt28.ps" => "__builtin_ia32_rsqrt28ps_mask", - "avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_mask", - // [DUPLICATE]: "avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_round_mask", - "avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_mask", - // [DUPLICATE]: "avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_round_mask", - "avx512.scatter.dpd.512" => "__builtin_ia32_scattersiv8df", - "avx512.scatter.dpi.512" => "__builtin_ia32_scattersiv16si", - "avx512.scatter.dpq.512" => "__builtin_ia32_scattersiv8di", - "avx512.scatter.dps.512" => "__builtin_ia32_scattersiv16sf", - "avx512.scatter.qpd.512" => "__builtin_ia32_scatterdiv8df", - "avx512.scatter.qpi.512" => "__builtin_ia32_scatterdiv16si", - "avx512.scatter.qpq.512" => "__builtin_ia32_scatterdiv8di", - "avx512.scatter.qps.512" => "__builtin_ia32_scatterdiv16sf", - "avx512.scatterdiv2.df" => "__builtin_ia32_scatterdiv2df", - "avx512.scatterdiv2.di" => "__builtin_ia32_scatterdiv2di", - "avx512.scatterdiv4.df" => "__builtin_ia32_scatterdiv4df", - "avx512.scatterdiv4.di" => "__builtin_ia32_scatterdiv4di", - "avx512.scatterdiv4.sf" => "__builtin_ia32_scatterdiv4sf", - "avx512.scatterdiv4.si" => "__builtin_ia32_scatterdiv4si", - "avx512.scatterdiv8.sf" => "__builtin_ia32_scatterdiv8sf", - "avx512.scatterdiv8.si" => "__builtin_ia32_scatterdiv8si", - "avx512.scatterpf.dpd.512" => "__builtin_ia32_scatterpfdpd", - "avx512.scatterpf.dps.512" => "__builtin_ia32_scatterpfdps", - "avx512.scatterpf.qpd.512" => "__builtin_ia32_scatterpfqpd", - "avx512.scatterpf.qps.512" => "__builtin_ia32_scatterpfqps", - "avx512.scattersiv2.df" => "__builtin_ia32_scattersiv2df", - "avx512.scattersiv2.di" => "__builtin_ia32_scattersiv2di", - "avx512.scattersiv4.df" => "__builtin_ia32_scattersiv4df", - "avx512.scattersiv4.di" => "__builtin_ia32_scattersiv4di", - "avx512.scattersiv4.sf" => "__builtin_ia32_scattersiv4sf", - "avx512.scattersiv4.si" => "__builtin_ia32_scattersiv4si", - "avx512.scattersiv8.sf" => "__builtin_ia32_scattersiv8sf", - "avx512.scattersiv8.si" => "__builtin_ia32_scattersiv8si", - "avx512.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", - "avx512.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", - "avx512.sqrt.sd" => "__builtin_ia32_sqrtrndsd", - "avx512.sqrt.ss" => "__builtin_ia32_sqrtrndss", "avx512.sub.pd.512" => "__builtin_ia32_subpd512", "avx512.sub.ps.512" => "__builtin_ia32_subps512", - "avx512.vbroadcast.sd.512" => "__builtin_ia32_vbroadcastsd512", - "avx512.vbroadcast.sd.pd.512" => "__builtin_ia32_vbroadcastsd_pd512", - "avx512.vbroadcast.ss.512" => "__builtin_ia32_vbroadcastss512", - "avx512.vbroadcast.ss.ps.512" => "__builtin_ia32_vbroadcastss_ps512", "avx512.vcomi.sd" => "__builtin_ia32_vcomisd", "avx512.vcomi.ss" => "__builtin_ia32_vcomiss", "avx512.vcvtsd2si32" => "__builtin_ia32_vcvtsd2si32", @@ -9833,50 +8681,10 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "flags.read.u64" => "__builtin_ia32_readeflags_u64", "flags.write.u32" => "__builtin_ia32_writeeflags_u32", "flags.write.u64" => "__builtin_ia32_writeeflags_u64", - "fma.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", - "fma.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", - "fma.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", - "fma.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", - "fma.mask.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask", - "fma.mask.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask", - "fma.mask.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask", - "fma.mask.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask", - "fma.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", - "fma.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", - "fma.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", - "fma.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", - "fma.vfmadd.pd" => "__builtin_ia32_vfmaddpd", - "fma.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256", - "fma.vfmadd.ps" => "__builtin_ia32_vfmaddps", - "fma.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256", - "fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd", - "fma.vfmadd.ss" => "__builtin_ia32_vfmaddss", "fma.vfmaddsub.pd" => "__builtin_ia32_vfmaddsubpd", "fma.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256", "fma.vfmaddsub.ps" => "__builtin_ia32_vfmaddsubps", "fma.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256", - "fma.vfmsub.pd" => "__builtin_ia32_vfmsubpd", - "fma.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256", - "fma.vfmsub.ps" => "__builtin_ia32_vfmsubps", - "fma.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256", - "fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd", - "fma.vfmsub.ss" => "__builtin_ia32_vfmsubss", - "fma.vfmsubadd.pd" => "__builtin_ia32_vfmsubaddpd", - "fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256", - "fma.vfmsubadd.ps" => "__builtin_ia32_vfmsubaddps", - "fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256", - "fma.vfnmadd.pd" => "__builtin_ia32_vfnmaddpd", - "fma.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256", - "fma.vfnmadd.ps" => "__builtin_ia32_vfnmaddps", - "fma.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256", - "fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd", - "fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss", - "fma.vfnmsub.pd" => "__builtin_ia32_vfnmsubpd", - "fma.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256", - "fma.vfnmsub.ps" => "__builtin_ia32_vfnmsubps", - "fma.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256", - "fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd", - "fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss", "fxrstor" => "__builtin_ia32_fxrstor", "fxrstor64" => "__builtin_ia32_fxrstor64", "fxsave" => "__builtin_ia32_fxsave", @@ -9893,7 +8701,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "lwpval32" => "__builtin_ia32_lwpval32", "lwpval64" => "__builtin_ia32_lwpval64", "mmx.emms" => "__builtin_ia32_emms", - "mmx.femms" => "__builtin_ia32_femms", "monitorx" => "__builtin_ia32_monitorx", "movdir64b" => "__builtin_ia32_movdir64b", "movrsdi" => "__builtin_ia32_movrsdi", @@ -9918,7 +8725,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "rdsspd" => "__builtin_ia32_rdsspd", "rdsspq" => "__builtin_ia32_rdsspq", "rdtsc" => "__builtin_ia32_rdtsc", - "rdtscp" => "__builtin_ia32_rdtscp", "rstorssp" => "__builtin_ia32_rstorssp", "saveprevssp" => "__builtin_ia32_saveprevssp", "senduipi" => "__builtin_ia32_senduipi", @@ -9932,8 +8738,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sha256msg2" => "__builtin_ia32_sha256msg2", "sha256rnds2" => "__builtin_ia32_sha256rnds2", "slwpcb" => "__builtin_ia32_slwpcb", - "sse.add.ss" => "__builtin_ia32_addss", - "sse.cmp.ps" => "__builtin_ia32_cmpps", "sse.cmp.ss" => "__builtin_ia32_cmpss", "sse.comieq.ss" => "__builtin_ia32_comieq", "sse.comige.ss" => "__builtin_ia32_comige", @@ -9941,37 +8745,27 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse.comile.ss" => "__builtin_ia32_comile", "sse.comilt.ss" => "__builtin_ia32_comilt", "sse.comineq.ss" => "__builtin_ia32_comineq", - "sse.cvtsi2ss" => "__builtin_ia32_cvtsi2ss", - "sse.cvtsi642ss" => "__builtin_ia32_cvtsi642ss", "sse.cvtss2si" => "__builtin_ia32_cvtss2si", "sse.cvtss2si64" => "__builtin_ia32_cvtss2si64", "sse.cvttss2si" => "__builtin_ia32_cvttss2si", "sse.cvttss2si64" => "__builtin_ia32_cvttss2si64", - "sse.div.ss" => "__builtin_ia32_divss", "sse.max.ps" => "__builtin_ia32_maxps", "sse.max.ss" => "__builtin_ia32_maxss", "sse.min.ps" => "__builtin_ia32_minps", "sse.min.ss" => "__builtin_ia32_minss", "sse.movmsk.ps" => "__builtin_ia32_movmskps", - "sse.mul.ss" => "__builtin_ia32_mulss", "sse.rcp.ps" => "__builtin_ia32_rcpps", "sse.rcp.ss" => "__builtin_ia32_rcpss", "sse.rsqrt.ps" => "__builtin_ia32_rsqrtps", "sse.rsqrt.ss" => "__builtin_ia32_rsqrtss", "sse.sfence" => "__builtin_ia32_sfence", - "sse.sqrt.ps" => "__builtin_ia32_sqrtps", - "sse.sqrt.ss" => "__builtin_ia32_sqrtss", - "sse.storeu.ps" => "__builtin_ia32_storeups", - "sse.sub.ss" => "__builtin_ia32_subss", "sse.ucomieq.ss" => "__builtin_ia32_ucomieq", "sse.ucomige.ss" => "__builtin_ia32_ucomige", "sse.ucomigt.ss" => "__builtin_ia32_ucomigt", "sse.ucomile.ss" => "__builtin_ia32_ucomile", "sse.ucomilt.ss" => "__builtin_ia32_ucomilt", "sse.ucomineq.ss" => "__builtin_ia32_ucomineq", - "sse2.add.sd" => "__builtin_ia32_addsd", "sse2.clflush" => "__builtin_ia32_clflush", - "sse2.cmp.pd" => "__builtin_ia32_cmppd", "sse2.cmp.sd" => "__builtin_ia32_cmpsd", "sse2.comieq.sd" => "__builtin_ia32_comisdeq", "sse2.comige.sd" => "__builtin_ia32_comisdge", @@ -9979,23 +8773,16 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse2.comile.sd" => "__builtin_ia32_comisdle", "sse2.comilt.sd" => "__builtin_ia32_comisdlt", "sse2.comineq.sd" => "__builtin_ia32_comisdneq", - "sse2.cvtdq2pd" => "__builtin_ia32_cvtdq2pd", - "sse2.cvtdq2ps" => "__builtin_ia32_cvtdq2ps", "sse2.cvtpd2dq" => "__builtin_ia32_cvtpd2dq", "sse2.cvtpd2ps" => "__builtin_ia32_cvtpd2ps", "sse2.cvtps2dq" => "__builtin_ia32_cvtps2dq", - "sse2.cvtps2pd" => "__builtin_ia32_cvtps2pd", "sse2.cvtsd2si" => "__builtin_ia32_cvtsd2si", "sse2.cvtsd2si64" => "__builtin_ia32_cvtsd2si64", "sse2.cvtsd2ss" => "__builtin_ia32_cvtsd2ss", - "sse2.cvtsi2sd" => "__builtin_ia32_cvtsi2sd", - "sse2.cvtsi642sd" => "__builtin_ia32_cvtsi642sd", - "sse2.cvtss2sd" => "__builtin_ia32_cvtss2sd", "sse2.cvttpd2dq" => "__builtin_ia32_cvttpd2dq", "sse2.cvttps2dq" => "__builtin_ia32_cvttps2dq", "sse2.cvttsd2si" => "__builtin_ia32_cvttsd2si", "sse2.cvttsd2si64" => "__builtin_ia32_cvttsd2si64", - "sse2.div.sd" => "__builtin_ia32_divsd", "sse2.lfence" => "__builtin_ia32_lfence", "sse2.maskmov.dqu" => "__builtin_ia32_maskmovdqu", "sse2.max.pd" => "__builtin_ia32_maxpd", @@ -10004,33 +8791,18 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse2.min.pd" => "__builtin_ia32_minpd", "sse2.min.sd" => "__builtin_ia32_minsd", "sse2.movmsk.pd" => "__builtin_ia32_movmskpd", - "sse2.mul.sd" => "__builtin_ia32_mulsd", "sse2.packssdw.128" => "__builtin_ia32_packssdw128", "sse2.packsswb.128" => "__builtin_ia32_packsswb128", "sse2.packuswb.128" => "__builtin_ia32_packuswb128", - "sse2.padds.b" => "__builtin_ia32_paddsb128", - "sse2.padds.w" => "__builtin_ia32_paddsw128", - "sse2.paddus.b" => "__builtin_ia32_paddusb128", - "sse2.paddus.w" => "__builtin_ia32_paddusw128", "sse2.pause" => "__builtin_ia32_pause", "sse2.pavg.b" => "__builtin_ia32_pavgb128", "sse2.pavg.w" => "__builtin_ia32_pavgw128", "sse2.pmadd.wd" => "__builtin_ia32_pmaddwd128", - "sse2.pmaxs.w" => "__builtin_ia32_pmaxsw128", - "sse2.pmaxu.b" => "__builtin_ia32_pmaxub128", - "sse2.pmins.w" => "__builtin_ia32_pminsw128", - "sse2.pminu.b" => "__builtin_ia32_pminub128", "sse2.pmovmskb.128" => "__builtin_ia32_pmovmskb128", "sse2.pmulh.w" => "__builtin_ia32_pmulhw128", "sse2.pmulhu.w" => "__builtin_ia32_pmulhuw128", - "sse2.pmulu.dq" => "__builtin_ia32_pmuludq128", "sse2.psad.bw" => "__builtin_ia32_psadbw128", - "sse2.pshuf.d" => "__builtin_ia32_pshufd", - "sse2.pshufh.w" => "__builtin_ia32_pshufhw", - "sse2.pshufl.w" => "__builtin_ia32_pshuflw", "sse2.psll.d" => "__builtin_ia32_pslld128", - "sse2.psll.dq" => "__builtin_ia32_pslldqi128", - "sse2.psll.dq.bs" => "__builtin_ia32_pslldqi128_byteshift", "sse2.psll.q" => "__builtin_ia32_psllq128", "sse2.psll.w" => "__builtin_ia32_psllw128", "sse2.pslli.d" => "__builtin_ia32_pslldi128", @@ -10041,23 +8813,11 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse2.psrai.d" => "__builtin_ia32_psradi128", "sse2.psrai.w" => "__builtin_ia32_psrawi128", "sse2.psrl.d" => "__builtin_ia32_psrld128", - "sse2.psrl.dq" => "__builtin_ia32_psrldqi128", - "sse2.psrl.dq.bs" => "__builtin_ia32_psrldqi128_byteshift", "sse2.psrl.q" => "__builtin_ia32_psrlq128", "sse2.psrl.w" => "__builtin_ia32_psrlw128", "sse2.psrli.d" => "__builtin_ia32_psrldi128", "sse2.psrli.q" => "__builtin_ia32_psrlqi128", "sse2.psrli.w" => "__builtin_ia32_psrlwi128", - "sse2.psubs.b" => "__builtin_ia32_psubsb128", - "sse2.psubs.w" => "__builtin_ia32_psubsw128", - "sse2.psubus.b" => "__builtin_ia32_psubusb128", - "sse2.psubus.w" => "__builtin_ia32_psubusw128", - "sse2.sqrt.pd" => "__builtin_ia32_sqrtpd", - "sse2.sqrt.sd" => "__builtin_ia32_sqrtsd", - "sse2.storel.dq" => "__builtin_ia32_storelv4si", - "sse2.storeu.dq" => "__builtin_ia32_storedqu", - "sse2.storeu.pd" => "__builtin_ia32_storeupd", - "sse2.sub.sd" => "__builtin_ia32_subsd", "sse2.ucomieq.sd" => "__builtin_ia32_ucomisdeq", "sse2.ucomige.sd" => "__builtin_ia32_ucomisdge", "sse2.ucomigt.sd" => "__builtin_ia32_ucomisdgt", @@ -10073,48 +8833,18 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse3.ldu.dq" => "__builtin_ia32_lddqu", "sse3.monitor" => "__builtin_ia32_monitor", "sse3.mwait" => "__builtin_ia32_mwait", - "sse41.blendpd" => "__builtin_ia32_blendpd", - "sse41.blendps" => "__builtin_ia32_blendps", "sse41.blendvpd" => "__builtin_ia32_blendvpd", "sse41.blendvps" => "__builtin_ia32_blendvps", "sse41.dppd" => "__builtin_ia32_dppd", "sse41.dpps" => "__builtin_ia32_dpps", - "sse41.extractps" => "__builtin_ia32_extractps128", "sse41.insertps" => "__builtin_ia32_insertps128", - "sse41.movntdqa" => "__builtin_ia32_movntdqa", "sse41.mpsadbw" => "__builtin_ia32_mpsadbw128", "sse41.packusdw" => "__builtin_ia32_packusdw128", "sse41.pblendvb" => "__builtin_ia32_pblendvb128", - "sse41.pblendw" => "__builtin_ia32_pblendw128", "sse41.phminposuw" => "__builtin_ia32_phminposuw128", - "sse41.pmaxsb" => "__builtin_ia32_pmaxsb128", - "sse41.pmaxsd" => "__builtin_ia32_pmaxsd128", - "sse41.pmaxud" => "__builtin_ia32_pmaxud128", - "sse41.pmaxuw" => "__builtin_ia32_pmaxuw128", - "sse41.pminsb" => "__builtin_ia32_pminsb128", - "sse41.pminsd" => "__builtin_ia32_pminsd128", - "sse41.pminud" => "__builtin_ia32_pminud128", - "sse41.pminuw" => "__builtin_ia32_pminuw128", - "sse41.pmovsxbd" => "__builtin_ia32_pmovsxbd128", - "sse41.pmovsxbq" => "__builtin_ia32_pmovsxbq128", - "sse41.pmovsxbw" => "__builtin_ia32_pmovsxbw128", - "sse41.pmovsxdq" => "__builtin_ia32_pmovsxdq128", - "sse41.pmovsxwd" => "__builtin_ia32_pmovsxwd128", - "sse41.pmovsxwq" => "__builtin_ia32_pmovsxwq128", - "sse41.pmovzxbd" => "__builtin_ia32_pmovzxbd128", - "sse41.pmovzxbq" => "__builtin_ia32_pmovzxbq128", - "sse41.pmovzxbw" => "__builtin_ia32_pmovzxbw128", - "sse41.pmovzxdq" => "__builtin_ia32_pmovzxdq128", - "sse41.pmovzxwd" => "__builtin_ia32_pmovzxwd128", - "sse41.pmovzxwq" => "__builtin_ia32_pmovzxwq128", - "sse41.pmuldq" => "__builtin_ia32_pmuldq128", "sse41.ptestc" => "__builtin_ia32_ptestc128", "sse41.ptestnzc" => "__builtin_ia32_ptestnzc128", "sse41.ptestz" => "__builtin_ia32_ptestz128", - "sse41.round.pd" => "__builtin_ia32_roundpd", - "sse41.round.ps" => "__builtin_ia32_roundps", - "sse41.round.sd" => "__builtin_ia32_roundsd", - "sse41.round.ss" => "__builtin_ia32_roundss", "sse42.crc32.32.16" => "__builtin_ia32_crc32hi", "sse42.crc32.32.32" => "__builtin_ia32_crc32si", "sse42.crc32.32.8" => "__builtin_ia32_crc32qi", @@ -10137,11 +8867,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "sse4a.extrqi" => "__builtin_ia32_extrqi", "sse4a.insertq" => "__builtin_ia32_insertq", "sse4a.insertqi" => "__builtin_ia32_insertqi", - "sse4a.movnt.sd" => "__builtin_ia32_movntsd", - "sse4a.movnt.ss" => "__builtin_ia32_movntss", - "ssse3.pabs.b.128" => "__builtin_ia32_pabsb128", - "ssse3.pabs.d.128" => "__builtin_ia32_pabsd128", - "ssse3.pabs.w.128" => "__builtin_ia32_pabsw128", "ssse3.phadd.d.128" => "__builtin_ia32_phaddd128", "ssse3.phadd.sw.128" => "__builtin_ia32_phaddsw128", "ssse3.phadd.w.128" => "__builtin_ia32_phaddw128", @@ -10156,36 +8881,27 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "ssse3.psign.w.128" => "__builtin_ia32_psignw128", "sttilecfg" => "__builtin_ia32_tile_storeconfig", "stui" => "__builtin_ia32_stui", - "subborrow.u32" => "__builtin_ia32_subborrow_u32", - "subborrow.u64" => "__builtin_ia32_subborrow_u64", - "t2rpntlvwz0" => "__builtin_ia32_t2rpntlvwz0", - "t2rpntlvwz0rs" => "__builtin_ia32_t2rpntlvwz0rs", - "t2rpntlvwz0rst1" => "__builtin_ia32_t2rpntlvwz0rst1", - "t2rpntlvwz0t1" => "__builtin_ia32_t2rpntlvwz0t1", - "t2rpntlvwz1" => "__builtin_ia32_t2rpntlvwz1", - "t2rpntlvwz1rs" => "__builtin_ia32_t2rpntlvwz1rs", - "t2rpntlvwz1rst1" => "__builtin_ia32_t2rpntlvwz1rst1", - "t2rpntlvwz1t1" => "__builtin_ia32_t2rpntlvwz1t1", "tbm.bextri.u32" => "__builtin_ia32_bextri_u32", "tbm.bextri.u64" => "__builtin_ia32_bextri_u64", "tcmmimfp16ps" => "__builtin_ia32_tcmmimfp16ps", "tcmmimfp16ps.internal" => "__builtin_ia32_tcmmimfp16ps_internal", "tcmmrlfp16ps" => "__builtin_ia32_tcmmrlfp16ps", "tcmmrlfp16ps.internal" => "__builtin_ia32_tcmmrlfp16ps_internal", - "tconjtcmmimfp16ps" => "__builtin_ia32_tconjtcmmimfp16ps", - "tconjtcmmimfp16ps.internal" => "__builtin_ia32_tconjtcmmimfp16ps_internal", - "tconjtfp16" => "__builtin_ia32_tconjtfp16", - "tconjtfp16.internal" => "__builtin_ia32_tconjtfp16_internal", "tcvtrowd2ps" => "__builtin_ia32_tcvtrowd2ps", "tcvtrowd2ps.internal" => "__builtin_ia32_tcvtrowd2ps_internal", + "tcvtrowd2psi" => "__builtin_ia32_tcvtrowd2psi", "tcvtrowps2bf16h" => "__builtin_ia32_tcvtrowps2bf16h", "tcvtrowps2bf16h.internal" => "__builtin_ia32_tcvtrowps2bf16h_internal", + "tcvtrowps2bf16hi" => "__builtin_ia32_tcvtrowps2bf16hi", "tcvtrowps2bf16l" => "__builtin_ia32_tcvtrowps2bf16l", "tcvtrowps2bf16l.internal" => "__builtin_ia32_tcvtrowps2bf16l_internal", + "tcvtrowps2bf16li" => "__builtin_ia32_tcvtrowps2bf16li", "tcvtrowps2phh" => "__builtin_ia32_tcvtrowps2phh", "tcvtrowps2phh.internal" => "__builtin_ia32_tcvtrowps2phh_internal", + "tcvtrowps2phhi" => "__builtin_ia32_tcvtrowps2phhi", "tcvtrowps2phl" => "__builtin_ia32_tcvtrowps2phl", "tcvtrowps2phl.internal" => "__builtin_ia32_tcvtrowps2phl_internal", + "tcvtrowps2phli" => "__builtin_ia32_tcvtrowps2phli", "tdpbf16ps" => "__builtin_ia32_tdpbf16ps", "tdpbf16ps.internal" => "__builtin_ia32_tdpbf16ps_internal", "tdpbf8ps" => "__builtin_ia32_tdpbf8ps", @@ -10217,6 +8933,7 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "tileloaddt164.internal" => "__builtin_ia32_tileloaddt164_internal", "tilemovrow" => "__builtin_ia32_tilemovrow", "tilemovrow.internal" => "__builtin_ia32_tilemovrow_internal", + "tilemovrowi" => "__builtin_ia32_tilemovrowi", "tilerelease" => "__builtin_ia32_tilerelease", "tilestored64" => "__builtin_ia32_tilestored64", "tilestored64.internal" => "__builtin_ia32_tilestored64_internal", @@ -10225,18 +8942,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "tmmultf32ps" => "__builtin_ia32_tmmultf32ps", "tmmultf32ps.internal" => "__builtin_ia32_tmmultf32ps_internal", "tpause" => "__builtin_ia32_tpause", - "ttcmmimfp16ps" => "__builtin_ia32_ttcmmimfp16ps", - "ttcmmimfp16ps.internal" => "__builtin_ia32_ttcmmimfp16ps_internal", - "ttcmmrlfp16ps" => "__builtin_ia32_ttcmmrlfp16ps", - "ttcmmrlfp16ps.internal" => "__builtin_ia32_ttcmmrlfp16ps_internal", - "ttdpbf16ps" => "__builtin_ia32_ttdpbf16ps", - "ttdpbf16ps.internal" => "__builtin_ia32_ttdpbf16ps_internal", - "ttdpfp16ps" => "__builtin_ia32_ttdpfp16ps", - "ttdpfp16ps.internal" => "__builtin_ia32_ttdpfp16ps_internal", - "ttmmultf32ps" => "__builtin_ia32_ttmmultf32ps", - "ttmmultf32ps.internal" => "__builtin_ia32_ttmmultf32ps_internal", - "ttransposed" => "__builtin_ia32_ttransposed", - "ttransposed.internal" => "__builtin_ia32_ttransposed_internal", "umonitor" => "__builtin_ia32_umonitor", "umwait" => "__builtin_ia32_umwait", "urdmsr" => "__builtin_ia32_urdmsr", @@ -10255,8 +8960,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "vcvtneoph2ps256" => "__builtin_ia32_vcvtneoph2ps256", "vcvtneps2bf16128" => "__builtin_ia32_vcvtneps2bf16128", "vcvtneps2bf16256" => "__builtin_ia32_vcvtneps2bf16256", - "vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps", - "vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256", "vcvtps2ph.128" => "__builtin_ia32_vcvtps2ph", "vcvtps2ph.256" => "__builtin_ia32_vcvtps2ph256", "vgf2p8affineinvqb.128" => "__builtin_ia32_vgf2p8affineinvqb_v16qi", @@ -10300,16 +9003,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "xop.vfrcz.ps.256" => "__builtin_ia32_vfrczps256", "xop.vfrcz.sd" => "__builtin_ia32_vfrczsd", "xop.vfrcz.ss" => "__builtin_ia32_vfrczss", - "xop.vpcmov" => "__builtin_ia32_vpcmov", - "xop.vpcmov.256" => "__builtin_ia32_vpcmov_256", - "xop.vpcomb" => "__builtin_ia32_vpcomb", - "xop.vpcomd" => "__builtin_ia32_vpcomd", - "xop.vpcomq" => "__builtin_ia32_vpcomq", - "xop.vpcomub" => "__builtin_ia32_vpcomub", - "xop.vpcomud" => "__builtin_ia32_vpcomud", - "xop.vpcomuq" => "__builtin_ia32_vpcomuq", - "xop.vpcomuw" => "__builtin_ia32_vpcomuw", - "xop.vpcomw" => "__builtin_ia32_vpcomw", "xop.vpermil2pd" => "__builtin_ia32_vpermil2pd", "xop.vpermil2pd.256" => "__builtin_ia32_vpermil2pd256", "xop.vpermil2ps" => "__builtin_ia32_vpermil2ps", @@ -10342,14 +9035,6 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { "xop.vpmadcsswd" => "__builtin_ia32_vpmadcsswd", "xop.vpmadcswd" => "__builtin_ia32_vpmadcswd", "xop.vpperm" => "__builtin_ia32_vpperm", - "xop.vprotb" => "__builtin_ia32_vprotb", - "xop.vprotbi" => "__builtin_ia32_vprotbi", - "xop.vprotd" => "__builtin_ia32_vprotd", - "xop.vprotdi" => "__builtin_ia32_vprotdi", - "xop.vprotq" => "__builtin_ia32_vprotq", - "xop.vprotqi" => "__builtin_ia32_vprotqi", - "xop.vprotw" => "__builtin_ia32_vprotw", - "xop.vprotwi" => "__builtin_ia32_vprotwi", "xop.vpshab" => "__builtin_ia32_vpshab", "xop.vpshad" => "__builtin_ia32_vpshad", "xop.vpshaq" => "__builtin_ia32_vpshaq", @@ -10379,6 +9064,14 @@ fn map_arch_intrinsic(full_name: &str) -> &'static str { } xcore(name, full_name) } - _ => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic:{full_name}"), + _ => match old_arch_res { + ArchCheckResult::UnknownIntrinsic => { + unimplemented!("***** unsupported LLVM intrinsic {full_name}") + } + ArchCheckResult::UnknownArch => { + unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic: {full_name}") + } + ArchCheckResult::Ok(_) => unreachable!(), + }, } } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs index e3d189c95ced..11a69acdde42 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs @@ -4,7 +4,7 @@ use gccjit::{CType, Context, Field, Function, FunctionPtrType, RValue, ToRValue, use rustc_codegen_ssa::traits::BuilderMethods; use crate::builder::Builder; -use crate::context::CodegenCx; +use crate::context::{CodegenCx, new_array_type}; fn encode_key_128_type<'a, 'gcc, 'tcx>( builder: &Builder<'a, 'gcc, 'tcx>, @@ -585,7 +585,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( "__builtin_ia32_encodekey128_u32" => { let mut new_args = args.to_vec(); let m128i = builder.context.new_vector_type(builder.i64_type, 2); - let array_type = builder.context.new_array_type(None, m128i, 6); + let array_type = new_array_type(builder.context, None, m128i, 6); let result = builder.current_func().new_local(None, array_type, "result"); new_args.push(result.get_address(None)); args = new_args.into(); @@ -593,7 +593,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( "__builtin_ia32_encodekey256_u32" => { let mut new_args = args.to_vec(); let m128i = builder.context.new_vector_type(builder.i64_type, 2); - let array_type = builder.context.new_array_type(None, m128i, 7); + let array_type = new_array_type(builder.context, None, m128i, 7); let result = builder.current_func().new_local(None, array_type, "result"); new_args.push(result.get_address(None)); args = new_args.into(); @@ -620,7 +620,7 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>( let first_value = old_args.swap_remove(0); let element_type = first_value.get_type(); - let array_type = builder.context.new_array_type(None, element_type, 8); + let array_type = new_array_type(builder.context, None, element_type, 8); let result = builder.current_func().new_local(None, array_type, "result"); new_args.push(result.get_address(None)); @@ -869,7 +869,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( builder.llbb().add_assignment(None, field1, return_value); let field2 = result.access_field(None, field2); let field2_type = field2.to_rvalue().get_type(); - let array_type = builder.context.new_array_type(None, field2_type, 6); + let array_type = new_array_type(builder.context, None, field2_type, 6); let ptr = builder.context.new_cast(None, args[2], array_type.make_pointer()); let field2_ptr = builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); @@ -891,7 +891,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( builder.llbb().add_assignment(None, field1, return_value); let field2 = result.access_field(None, field2); let field2_type = field2.to_rvalue().get_type(); - let array_type = builder.context.new_array_type(None, field2_type, 7); + let array_type = new_array_type(builder.context, None, field2_type, 7); let ptr = builder.context.new_cast(None, args[3], array_type.make_pointer()); let field2_ptr = builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); @@ -937,7 +937,7 @@ pub fn adjust_intrinsic_return_value<'a, 'gcc, 'tcx>( builder.llbb().add_assignment(None, field1, return_value); let field2 = result.access_field(None, field2); let field2_type = field2.to_rvalue().get_type(); - let array_type = builder.context.new_array_type(None, field2_type, 8); + let array_type = new_array_type(builder.context, None, field2_type, 8); let ptr = builder.context.new_cast(None, args[0], array_type.make_pointer()); let field2_ptr = builder.context.new_cast(None, field2.get_address(None), array_type.make_pointer()); @@ -1061,7 +1061,18 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function "llvm.x86.xgetbv" => "__builtin_ia32_xgetbv", // NOTE: this doc specifies the equivalent GCC builtins: http://huonw.github.io/llvmint/llvmint/x86/index.html + // FIXME: Should handle other targets than `ia32`. "llvm.sqrt.v2f64" => "__builtin_ia32_sqrtpd", + // FIXME: Should handle other targets than `ia32`. + "llvm.sqrt.v4f32" => "__builtin_ia32_sqrtps", + "llvm.sqrt.f32" => { + let gcc_name = "__builtin_sqrtf"; + let func = cx.context.get_builtin_function(gcc_name); + cx.functions.borrow_mut().insert(gcc_name.to_string(), func); + return func; + } + // FIXME: Should handle other targets than `ia32`. + "llvm.smax.v4i32" => "__builtin_ia32_pmaxsd128", "llvm.x86.avx512.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask", "llvm.x86.avx512.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask", "llvm.x86.avx512.max.ps.512" => "__builtin_ia32_maxps512_mask", @@ -1604,5 +1615,7 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function func } +#[cfg(feature = "master")] +include!("old_archs.rs"); #[cfg(feature = "master")] include!("archs.rs"); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 23d16eda030c..7e15a5eeaa5e 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -9,7 +9,7 @@ use gccjit::Type; use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, UnaryOp}; #[cfg(feature = "master")] use rustc_abi::ExternAbi; -use rustc_abi::{BackendRepr, HasDataLayout}; +use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::common::IntPredicate; @@ -20,8 +20,9 @@ use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::MiscCodegenMethods; use rustc_codegen_ssa::traits::{ ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, - IntrinsicCallBuilderMethods, + IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods, }; +use rustc_data_structures::fx::FxHashSet; use rustc_middle::bug; #[cfg(feature = "master")] use rustc_middle::ty::layout::FnAbiOf; @@ -207,6 +208,7 @@ fn get_simple_function_f128<'gcc, 'tcx>( let f128_type = cx.type_f128(); let func_name = match name { sym::ceilf128 => "ceilf128", + sym::fabsf128 => "fabsf128", sym::floorf128 => "floorf128", sym::truncf128 => "truncf128", sym::roundf128 => "roundf128", @@ -261,6 +263,7 @@ fn f16_builtin<'gcc, 'tcx>( let builtin_name = match name { sym::ceilf16 => "__builtin_ceilf", sym::copysignf16 => "__builtin_copysignf", + sym::fabsf16 => "fabsf", sym::floorf16 => "__builtin_floorf", sym::fmaf16 => "fmaf", sym::maxnumf16 => "__builtin_fmaxf", @@ -327,6 +330,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } sym::ceilf16 | sym::copysignf16 + | sym::fabsf16 | sym::floorf16 | sym::fmaf16 | sym::maxnumf16 @@ -395,9 +399,6 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc sym::breakpoint => { unimplemented!(); } - sym::va_copy => { - unimplemented!(); - } sym::va_arg => { unimplemented!(); } @@ -460,9 +461,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } sym::bitreverse => self.bit_reverse(width, args[0].immediate()), sym::rotate_left | sym::rotate_right => { - // TODO(antoyo): implement using algorithm from: + // Using optimized branchless algorithm from: // https://blog.regehr.org/archives/1063 - // for other platforms. + // This implementation uses the pattern (x<>(-n&(width-1))) + // which generates efficient code for other platforms. let is_left = name == sym::rotate_left; let val = args[0].immediate(); let raw_shift = args[1].immediate(); @@ -503,7 +505,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - SimdVector { .. } => false, + SimdVector { .. } | ScalableVector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), @@ -608,6 +610,86 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc Ok(()) } + fn codegen_llvm_intrinsic_call( + &mut self, + instance: ty::Instance<'tcx>, + args: &[OperandRef<'tcx, Self::Value>], + is_cleanup: bool, + ) -> Self::Value { + let func = if let Some(&func) = self.intrinsic_instances.borrow().get(&instance) { + func + } else { + let sym = self.tcx.symbol_name(instance).name; + + let func = if let Some(func) = self.intrinsics.borrow().get(sym) { + *func + } else { + self.linkage.set(FunctionType::Extern); + + let func = match sym { + "llvm.fma.f16" => { + // fma is not a target builtin, but a normal builtin, so we handle it differently + // here. + self.context.get_builtin_function("fma") + } + _ => llvm::intrinsic(sym, self), + }; + + self.intrinsics.borrow_mut().insert(sym.to_string(), func); + + self.on_stack_function_params.borrow_mut().insert(func, FxHashSet::default()); + + crate::attributes::from_fn_attrs(self, func, instance); + + func + }; + + self.intrinsic_instances.borrow_mut().insert(instance, func); + + func + }; + let fn_ptr = func.get_address(None); + let fn_ty = fn_ptr.get_type(); + + let mut call_args = vec![]; + + for arg in args { + match arg.val { + OperandValue::ZeroSized => {} + OperandValue::Immediate(_) => call_args.push(arg.immediate()), + OperandValue::Pair(a, b) => { + call_args.push(a); + call_args.push(b); + } + OperandValue::Ref(op_place_val) => { + let mut llval = op_place_val.llval; + // We can't use `PlaceRef::load` here because the argument + // may have a type we don't treat as immediate, but the ABI + // used for this call is passing it by-value. In that case, + // the load would just produce `OperandValue::Ref` instead + // of the `OperandValue::Immediate` we need for the call. + llval = self.load(self.backend_type(arg.layout), llval, op_place_val.align); + if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr { + if scalar.is_bool() { + self.range_metadata(llval, WrappingRange { start: 0, end: 1 }); + } + // We store bools as `i8` so we need to truncate to `i1`. + llval = self.to_immediate_scalar(llval, scalar); + } + call_args.push(llval); + } + } + } + + // FIXME directly use the llvm intrinsic adjustment functions here + let llret = self.call(fn_ty, None, None, fn_ptr, &call_args, None, None); + if is_cleanup { + self.apply_attrs_to_cleanup_callsite(llret); + } + + llret + } + fn abort(&mut self) { let func = self.context.get_builtin_function("abort"); let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; @@ -641,7 +723,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc } fn va_end(&mut self, _va_list: RValue<'gcc>) -> RValue<'gcc> { - unimplemented!(); + // TODO(antoyo): implement. + self.context.new_rvalue_from_int(self.int_type, 0) } } diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/old_archs.rs b/compiler/rustc_codegen_gcc/src/intrinsic/old_archs.rs new file mode 100644 index 000000000000..8d3e3487b5cb --- /dev/null +++ b/compiler/rustc_codegen_gcc/src/intrinsic/old_archs.rs @@ -0,0 +1,1390 @@ +// All these translations used to be automatically generated in the past. However, since they never +// changed, we decided to simplify the translation generation script to move them directly into this +// file. +// +// So in short: avoid editing this file. + +pub(crate) enum ArchCheckResult { + Ok(&'static str), + UnknownIntrinsic, + UnknownArch, +} + +pub(crate) fn old_archs(arch: &str, name: &str) -> ArchCheckResult { + ArchCheckResult::Ok(match arch { + "AMDGPU" => match name { + "div.fixup.f32" => "__builtin_amdgpu_div_fixup", + "div.fixup.f64" => "__builtin_amdgpu_div_fixup", + "div.fixup.v2f64" => "__builtin_amdgpu_div_fixup", + "div.fixup.v4f32" => "__builtin_amdgpu_div_fixup", + "div.fmas.f32" => "__builtin_amdgpu_div_fmas", + "div.fmas.f64" => "__builtin_amdgpu_div_fmas", + "div.fmas.v2f64" => "__builtin_amdgpu_div_fmas", + "div.fmas.v4f32" => "__builtin_amdgpu_div_fmas", + "ldexp.f32" => "__builtin_amdgpu_ldexp", + "ldexp.f64" => "__builtin_amdgpu_ldexp", + "ldexp.v2f64" => "__builtin_amdgpu_ldexp", + "ldexp.v4f32" => "__builtin_amdgpu_ldexp", + "rcp.f32" => "__builtin_amdgpu_rcp", + "rcp.f64" => "__builtin_amdgpu_rcp", + "rcp.v2f64" => "__builtin_amdgpu_rcp", + "rcp.v4f32" => "__builtin_amdgpu_rcp", + "rsq.clamped.f32" => "__builtin_amdgpu_rsq_clamped", + "rsq.clamped.f64" => "__builtin_amdgpu_rsq_clamped", + "rsq.clamped.v2f64" => "__builtin_amdgpu_rsq_clamped", + "rsq.clamped.v4f32" => "__builtin_amdgpu_rsq_clamped", + "rsq.f32" => "__builtin_amdgpu_rsq", + "rsq.f64" => "__builtin_amdgpu_rsq", + "rsq.v2f64" => "__builtin_amdgpu_rsq", + "rsq.v4f32" => "__builtin_amdgpu_rsq", + "trig.preop.f32" => "__builtin_amdgpu_trig_preop", + "trig.preop.f64" => "__builtin_amdgpu_trig_preop", + "trig.preop.v2f64" => "__builtin_amdgpu_trig_preop", + "trig.preop.v4f32" => "__builtin_amdgpu_trig_preop", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "arm" => match name { + "mcrr" => "__builtin_arm_mcrr", + "mcrr2" => "__builtin_arm_mcrr2", + "thread.pointer" => "__builtin_thread_pointer", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "cuda" => match name { + "syncthreads" => "__syncthreads", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "hexagon" => match name { + "F2.dffixupd" => "__builtin_HEXAGON_F2_dffixupd", + "F2.dffixupn" => "__builtin_HEXAGON_F2_dffixupn", + "F2.dffixupr" => "__builtin_HEXAGON_F2_dffixupr", + "F2.dffma" => "__builtin_HEXAGON_F2_dffma", + "F2.dffma.lib" => "__builtin_HEXAGON_F2_dffma_lib", + "F2.dffma.sc" => "__builtin_HEXAGON_F2_dffma_sc", + "F2.dffms" => "__builtin_HEXAGON_F2_dffms", + "F2.dffms.lib" => "__builtin_HEXAGON_F2_dffms_lib", + "F2.dfmpy" => "__builtin_HEXAGON_F2_dfmpy", + "S2.cabacencbin" => "__builtin_HEXAGON_S2_cabacencbin", + "SI.to.SXTHI.asrh" => "__builtin_SI_to_SXTHI_asrh", + "V6.vlutb" => "__builtin_HEXAGON_V6_vlutb", + "V6.vlutb.128B" => "__builtin_HEXAGON_V6_vlutb_128B", + "V6.vlutb.acc" => "__builtin_HEXAGON_V6_vlutb_acc", + "V6.vlutb.acc.128B" => "__builtin_HEXAGON_V6_vlutb_acc_128B", + "V6.vlutb.dv" => "__builtin_HEXAGON_V6_vlutb_dv", + "V6.vlutb.dv.128B" => "__builtin_HEXAGON_V6_vlutb_dv_128B", + "V6.vlutb.dv.acc" => "__builtin_HEXAGON_V6_vlutb_dv_acc", + "V6.vlutb.dv.acc.128B" => "__builtin_HEXAGON_V6_vlutb_dv_acc_128B", + "brev.ldb" => "__builtin_brev_ldb", + "brev.ldd" => "__builtin_brev_ldd", + "brev.ldh" => "__builtin_brev_ldh", + "brev.ldub" => "__builtin_brev_ldub", + "brev.lduh" => "__builtin_brev_lduh", + "brev.ldw" => "__builtin_brev_ldw", + "brev.stb" => "__builtin_brev_stb", + "brev.std" => "__builtin_brev_std", + "brev.sth" => "__builtin_brev_sth", + "brev.sthhi" => "__builtin_brev_sthhi", + "brev.stw" => "__builtin_brev_stw", + "mm256i.vaddw" => "__builtin__mm256i_vaddw", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "nvvm" => match name { + "abs.i" => "__nvvm_abs_i", + "abs.ll" => "__nvvm_abs_ll", + "bar.sync" => "__nvvm_bar_sync", + "barrier0" => "__nvvm_bar0", + "bitcast.d2ll" => "__nvvm_bitcast_d2ll", + "bitcast.f2i" => "__nvvm_bitcast_f2i", + "bitcast.i2f" => "__nvvm_bitcast_i2f", + "bitcast.ll2d" => "__nvvm_bitcast_ll2d", + "brev32" => "__nvvm_brev32", + "brev64" => "__nvvm_brev64", + "clz.i" => "__nvvm_clz_i", + "clz.ll" => "__nvvm_clz_ll", + "ex2.approx.d" => "__nvvm_ex2_approx_d", + "ex2.approx.f" => "__nvvm_ex2_approx_f", + "ex2.approx.ftz.f" => "__nvvm_ex2_approx_ftz_f", + "fabs.d" => "__nvvm_fabs_d", + "fabs.f" => "__nvvm_fabs_f", + "fabs.ftz.f" => "__nvvm_fabs_ftz_f", + "h2f" => "__nvvm_h2f", + "max.i" => "__nvvm_max_i", + "max.ll" => "__nvvm_max_ll", + "max.ui" => "__nvvm_max_ui", + "max.ull" => "__nvvm_max_ull", + "min.i" => "__nvvm_min_i", + "min.ll" => "__nvvm_min_ll", + "min.ui" => "__nvvm_min_ui", + "min.ull" => "__nvvm_min_ull", + "popc.i" => "__nvvm_popc_i", + "popc.ll" => "__nvvm_popc_ll", + "rotate.b32" => "__nvvm_rotate_b32", + "rotate.b64" => "__nvvm_rotate_b64", + "rotate.right.b64" => "__nvvm_rotate_right_b64", + "swap.lo.hi.b64" => "__nvvm_swap_lo_hi_b64", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "ppc" => match name { + "qpx.qvfabs" => "__builtin_qpx_qvfabs", + "qpx.qvfadd" => "__builtin_qpx_qvfadd", + "qpx.qvfadds" => "__builtin_qpx_qvfadds", + "qpx.qvfcfid" => "__builtin_qpx_qvfcfid", + "qpx.qvfcfids" => "__builtin_qpx_qvfcfids", + "qpx.qvfcfidu" => "__builtin_qpx_qvfcfidu", + "qpx.qvfcfidus" => "__builtin_qpx_qvfcfidus", + "qpx.qvfcmpeq" => "__builtin_qpx_qvfcmpeq", + "qpx.qvfcmpgt" => "__builtin_qpx_qvfcmpgt", + "qpx.qvfcmplt" => "__builtin_qpx_qvfcmplt", + "qpx.qvfcpsgn" => "__builtin_qpx_qvfcpsgn", + "qpx.qvfctid" => "__builtin_qpx_qvfctid", + "qpx.qvfctidu" => "__builtin_qpx_qvfctidu", + "qpx.qvfctiduz" => "__builtin_qpx_qvfctiduz", + "qpx.qvfctidz" => "__builtin_qpx_qvfctidz", + "qpx.qvfctiw" => "__builtin_qpx_qvfctiw", + "qpx.qvfctiwu" => "__builtin_qpx_qvfctiwu", + "qpx.qvfctiwuz" => "__builtin_qpx_qvfctiwuz", + "qpx.qvfctiwz" => "__builtin_qpx_qvfctiwz", + "qpx.qvflogical" => "__builtin_qpx_qvflogical", + "qpx.qvfmadd" => "__builtin_qpx_qvfmadd", + "qpx.qvfmadds" => "__builtin_qpx_qvfmadds", + "qpx.qvfmsub" => "__builtin_qpx_qvfmsub", + "qpx.qvfmsubs" => "__builtin_qpx_qvfmsubs", + "qpx.qvfmul" => "__builtin_qpx_qvfmul", + "qpx.qvfmuls" => "__builtin_qpx_qvfmuls", + "qpx.qvfnabs" => "__builtin_qpx_qvfnabs", + "qpx.qvfneg" => "__builtin_qpx_qvfneg", + "qpx.qvfnmadd" => "__builtin_qpx_qvfnmadd", + "qpx.qvfnmadds" => "__builtin_qpx_qvfnmadds", + "qpx.qvfnmsub" => "__builtin_qpx_qvfnmsub", + "qpx.qvfnmsubs" => "__builtin_qpx_qvfnmsubs", + "qpx.qvfperm" => "__builtin_qpx_qvfperm", + "qpx.qvfre" => "__builtin_qpx_qvfre", + "qpx.qvfres" => "__builtin_qpx_qvfres", + "qpx.qvfrim" => "__builtin_qpx_qvfrim", + "qpx.qvfrin" => "__builtin_qpx_qvfrin", + "qpx.qvfrip" => "__builtin_qpx_qvfrip", + "qpx.qvfriz" => "__builtin_qpx_qvfriz", + "qpx.qvfrsp" => "__builtin_qpx_qvfrsp", + "qpx.qvfrsqrte" => "__builtin_qpx_qvfrsqrte", + "qpx.qvfrsqrtes" => "__builtin_qpx_qvfrsqrtes", + "qpx.qvfsel" => "__builtin_qpx_qvfsel", + "qpx.qvfsub" => "__builtin_qpx_qvfsub", + "qpx.qvfsubs" => "__builtin_qpx_qvfsubs", + "qpx.qvftstnan" => "__builtin_qpx_qvftstnan", + "qpx.qvfxmadd" => "__builtin_qpx_qvfxmadd", + "qpx.qvfxmadds" => "__builtin_qpx_qvfxmadds", + "qpx.qvfxmul" => "__builtin_qpx_qvfxmul", + "qpx.qvfxmuls" => "__builtin_qpx_qvfxmuls", + "qpx.qvfxxcpnmadd" => "__builtin_qpx_qvfxxcpnmadd", + "qpx.qvfxxcpnmadds" => "__builtin_qpx_qvfxxcpnmadds", + "qpx.qvfxxmadd" => "__builtin_qpx_qvfxxmadd", + "qpx.qvfxxmadds" => "__builtin_qpx_qvfxxmadds", + "qpx.qvfxxnpmadd" => "__builtin_qpx_qvfxxnpmadd", + "qpx.qvfxxnpmadds" => "__builtin_qpx_qvfxxnpmadds", + "qpx.qvgpci" => "__builtin_qpx_qvgpci", + "qpx.qvlfcd" => "__builtin_qpx_qvlfcd", + "qpx.qvlfcda" => "__builtin_qpx_qvlfcda", + "qpx.qvlfcs" => "__builtin_qpx_qvlfcs", + "qpx.qvlfcsa" => "__builtin_qpx_qvlfcsa", + "qpx.qvlfd" => "__builtin_qpx_qvlfd", + "qpx.qvlfda" => "__builtin_qpx_qvlfda", + "qpx.qvlfiwa" => "__builtin_qpx_qvlfiwa", + "qpx.qvlfiwaa" => "__builtin_qpx_qvlfiwaa", + "qpx.qvlfiwz" => "__builtin_qpx_qvlfiwz", + "qpx.qvlfiwza" => "__builtin_qpx_qvlfiwza", + "qpx.qvlfs" => "__builtin_qpx_qvlfs", + "qpx.qvlfsa" => "__builtin_qpx_qvlfsa", + "qpx.qvlpcld" => "__builtin_qpx_qvlpcld", + "qpx.qvlpcls" => "__builtin_qpx_qvlpcls", + "qpx.qvlpcrd" => "__builtin_qpx_qvlpcrd", + "qpx.qvlpcrs" => "__builtin_qpx_qvlpcrs", + "qpx.qvstfcd" => "__builtin_qpx_qvstfcd", + "qpx.qvstfcda" => "__builtin_qpx_qvstfcda", + "qpx.qvstfcs" => "__builtin_qpx_qvstfcs", + "qpx.qvstfcsa" => "__builtin_qpx_qvstfcsa", + "qpx.qvstfd" => "__builtin_qpx_qvstfd", + "qpx.qvstfda" => "__builtin_qpx_qvstfda", + "qpx.qvstfiw" => "__builtin_qpx_qvstfiw", + "qpx.qvstfiwa" => "__builtin_qpx_qvstfiwa", + "qpx.qvstfs" => "__builtin_qpx_qvstfs", + "qpx.qvstfsa" => "__builtin_qpx_qvstfsa", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "ptx" => match name { + "bar.sync" => "__builtin_ptx_bar_sync", + "read.clock" => "__builtin_ptx_read_clock", + "read.clock64" => "__builtin_ptx_read_clock64", + "read.gridid" => "__builtin_ptx_read_gridid", + "read.laneid" => "__builtin_ptx_read_laneid", + "read.lanemask.eq" => "__builtin_ptx_read_lanemask_eq", + "read.lanemask.ge" => "__builtin_ptx_read_lanemask_ge", + "read.lanemask.gt" => "__builtin_ptx_read_lanemask_gt", + "read.lanemask.le" => "__builtin_ptx_read_lanemask_le", + "read.lanemask.lt" => "__builtin_ptx_read_lanemask_lt", + "read.nsmid" => "__builtin_ptx_read_nsmid", + "read.nwarpid" => "__builtin_ptx_read_nwarpid", + "read.pm0" => "__builtin_ptx_read_pm0", + "read.pm1" => "__builtin_ptx_read_pm1", + "read.pm2" => "__builtin_ptx_read_pm2", + "read.pm3" => "__builtin_ptx_read_pm3", + "read.smid" => "__builtin_ptx_read_smid", + "read.warpid" => "__builtin_ptx_read_warpid", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + "x86" => match name { + "addcarry.u32" => "__builtin_ia32_addcarry_u32", + "addcarry.u64" => "__builtin_ia32_addcarry_u64", + "addcarryx.u32" => "__builtin_ia32_addcarryx_u32", + "addcarryx.u64" => "__builtin_ia32_addcarryx_u64", + "avx.blend.pd.256" => "__builtin_ia32_blendpd256", + "avx.blend.ps.256" => "__builtin_ia32_blendps256", + "avx.cmp.pd.256" => "__builtin_ia32_cmppd256", + "avx.cmp.ps.256" => "__builtin_ia32_cmpps256", + "avx.cvt.ps2.pd.256" => "__builtin_ia32_cvtps2pd256", + "avx.cvtdq2.pd.256" => "__builtin_ia32_cvtdq2pd256", + "avx.cvtdq2.ps.256" => "__builtin_ia32_cvtdq2ps256", + "avx.round.pd.256" => "__builtin_ia32_roundpd256", + "avx.round.ps.256" => "__builtin_ia32_roundps256", + "avx.sqrt.pd.256" => "__builtin_ia32_sqrtpd256", + "avx.sqrt.ps.256" => "__builtin_ia32_sqrtps256", + "avx.storeu.dq.256" => "__builtin_ia32_storedqu256", + "avx.storeu.pd.256" => "__builtin_ia32_storeupd256", + "avx.storeu.ps.256" => "__builtin_ia32_storeups256", + "avx.vbroadcastf128.pd.256" => "__builtin_ia32_vbroadcastf128_pd256", + "avx.vbroadcastf128.ps.256" => "__builtin_ia32_vbroadcastf128_ps256", + "avx.vextractf128.pd.256" => "__builtin_ia32_vextractf128_pd256", + "avx.vextractf128.ps.256" => "__builtin_ia32_vextractf128_ps256", + "avx.vextractf128.si.256" => "__builtin_ia32_vextractf128_si256", + "avx.vinsertf128.pd.256" => "__builtin_ia32_vinsertf128_pd256", + "avx.vinsertf128.ps.256" => "__builtin_ia32_vinsertf128_ps256", + "avx.vinsertf128.si.256" => "__builtin_ia32_vinsertf128_si256", + "avx.vperm2f128.pd.256" => "__builtin_ia32_vperm2f128_pd256", + "avx.vperm2f128.ps.256" => "__builtin_ia32_vperm2f128_ps256", + "avx.vperm2f128.si.256" => "__builtin_ia32_vperm2f128_si256", + "avx2.movntdqa" => "__builtin_ia32_movntdqa256", + "avx2.pabs.b" => "__builtin_ia32_pabsb256", + "avx2.pabs.d" => "__builtin_ia32_pabsd256", + "avx2.pabs.w" => "__builtin_ia32_pabsw256", + "avx2.padds.b" => "__builtin_ia32_paddsb256", + "avx2.padds.w" => "__builtin_ia32_paddsw256", + "avx2.paddus.b" => "__builtin_ia32_paddusb256", + "avx2.paddus.w" => "__builtin_ia32_paddusw256", + "avx2.pblendd.128" => "__builtin_ia32_pblendd128", + "avx2.pblendd.256" => "__builtin_ia32_pblendd256", + "avx2.pblendw" => "__builtin_ia32_pblendw256", + "avx2.pbroadcastb.128" => "__builtin_ia32_pbroadcastb128", + "avx2.pbroadcastb.256" => "__builtin_ia32_pbroadcastb256", + "avx2.pbroadcastd.128" => "__builtin_ia32_pbroadcastd128", + "avx2.pbroadcastd.256" => "__builtin_ia32_pbroadcastd256", + "avx2.pbroadcastq.128" => "__builtin_ia32_pbroadcastq128", + "avx2.pbroadcastq.256" => "__builtin_ia32_pbroadcastq256", + "avx2.pbroadcastw.128" => "__builtin_ia32_pbroadcastw128", + "avx2.pbroadcastw.256" => "__builtin_ia32_pbroadcastw256", + "avx2.pmaxs.b" => "__builtin_ia32_pmaxsb256", + "avx2.pmaxs.d" => "__builtin_ia32_pmaxsd256", + "avx2.pmaxs.w" => "__builtin_ia32_pmaxsw256", + "avx2.pmaxu.b" => "__builtin_ia32_pmaxub256", + "avx2.pmaxu.d" => "__builtin_ia32_pmaxud256", + "avx2.pmaxu.w" => "__builtin_ia32_pmaxuw256", + "avx2.pmins.b" => "__builtin_ia32_pminsb256", + "avx2.pmins.d" => "__builtin_ia32_pminsd256", + "avx2.pmins.w" => "__builtin_ia32_pminsw256", + "avx2.pminu.b" => "__builtin_ia32_pminub256", + "avx2.pminu.d" => "__builtin_ia32_pminud256", + "avx2.pminu.w" => "__builtin_ia32_pminuw256", + "avx2.pmovsxbd" => "__builtin_ia32_pmovsxbd256", + "avx2.pmovsxbq" => "__builtin_ia32_pmovsxbq256", + "avx2.pmovsxbw" => "__builtin_ia32_pmovsxbw256", + "avx2.pmovsxdq" => "__builtin_ia32_pmovsxdq256", + "avx2.pmovsxwd" => "__builtin_ia32_pmovsxwd256", + "avx2.pmovsxwq" => "__builtin_ia32_pmovsxwq256", + "avx2.pmovzxbd" => "__builtin_ia32_pmovzxbd256", + "avx2.pmovzxbq" => "__builtin_ia32_pmovzxbq256", + "avx2.pmovzxbw" => "__builtin_ia32_pmovzxbw256", + "avx2.pmovzxdq" => "__builtin_ia32_pmovzxdq256", + "avx2.pmovzxwd" => "__builtin_ia32_pmovzxwd256", + "avx2.pmovzxwq" => "__builtin_ia32_pmovzxwq256", + "avx2.pmul.dq" => "__builtin_ia32_pmuldq256", + "avx2.pmulu.dq" => "__builtin_ia32_pmuludq256", + "avx2.psll.dq" => "__builtin_ia32_pslldqi256", + "avx2.psll.dq.bs" => "__builtin_ia32_pslldqi256_byteshift", + "avx2.psrl.dq" => "__builtin_ia32_psrldqi256", + "avx2.psrl.dq.bs" => "__builtin_ia32_psrldqi256_byteshift", + "avx2.psubs.b" => "__builtin_ia32_psubsb256", + "avx2.psubs.w" => "__builtin_ia32_psubsw256", + "avx2.psubus.b" => "__builtin_ia32_psubusb256", + "avx2.psubus.w" => "__builtin_ia32_psubusw256", + "avx2.vbroadcast.sd.pd.256" => "__builtin_ia32_vbroadcastsd_pd256", + "avx2.vbroadcast.ss.ps" => "__builtin_ia32_vbroadcastss_ps", + "avx2.vbroadcast.ss.ps.256" => "__builtin_ia32_vbroadcastss_ps256", + "avx2.vextracti128" => "__builtin_ia32_extract128i256", + "avx2.vinserti128" => "__builtin_ia32_insert128i256", + "avx2.vperm2i128" => "__builtin_ia32_permti256", + "avx512.cvtb2mask.128" => "__builtin_ia32_cvtb2mask128", + "avx512.cvtb2mask.256" => "__builtin_ia32_cvtb2mask256", + "avx512.cvtb2mask.512" => "__builtin_ia32_cvtb2mask512", + "avx512.cvtd2mask.128" => "__builtin_ia32_cvtd2mask128", + "avx512.cvtd2mask.256" => "__builtin_ia32_cvtd2mask256", + "avx512.cvtd2mask.512" => "__builtin_ia32_cvtd2mask512", + "avx512.cvtmask2b.128" => "__builtin_ia32_cvtmask2b128", + "avx512.cvtmask2b.256" => "__builtin_ia32_cvtmask2b256", + "avx512.cvtmask2b.512" => "__builtin_ia32_cvtmask2b512", + "avx512.cvtmask2d.128" => "__builtin_ia32_cvtmask2d128", + "avx512.cvtmask2d.256" => "__builtin_ia32_cvtmask2d256", + "avx512.cvtmask2d.512" => "__builtin_ia32_cvtmask2d512", + "avx512.cvtmask2q.128" => "__builtin_ia32_cvtmask2q128", + "avx512.cvtmask2q.256" => "__builtin_ia32_cvtmask2q256", + "avx512.cvtmask2q.512" => "__builtin_ia32_cvtmask2q512", + "avx512.cvtmask2w.128" => "__builtin_ia32_cvtmask2w128", + "avx512.cvtmask2w.256" => "__builtin_ia32_cvtmask2w256", + "avx512.cvtmask2w.512" => "__builtin_ia32_cvtmask2w512", + "avx512.cvtq2mask.128" => "__builtin_ia32_cvtq2mask128", + "avx512.cvtq2mask.256" => "__builtin_ia32_cvtq2mask256", + "avx512.cvtq2mask.512" => "__builtin_ia32_cvtq2mask512", + "avx512.cvtsd2usi" => "__builtin_ia32_cvtsd2usi", + "avx512.cvtsd2usi64" => "__builtin_ia32_cvtsd2usi64", + "avx512.cvtsi2sd32" => "__builtin_ia32_cvtsi2sd32", + "avx512.cvtss2usi" => "__builtin_ia32_cvtss2usi", + "avx512.cvtss2usi64" => "__builtin_ia32_cvtss2usi64", + "avx512.cvtw2mask.128" => "__builtin_ia32_cvtw2mask128", + "avx512.cvtw2mask.256" => "__builtin_ia32_cvtw2mask256", + "avx512.cvtw2mask.512" => "__builtin_ia32_cvtw2mask512", + "avx512.exp2.pd" => "__builtin_ia32_exp2pd_mask", + "avx512.exp2.ps" => "__builtin_ia32_exp2ps_mask", + "avx512.gather.dpd.512" => "__builtin_ia32_gathersiv8df", + "avx512.gather.dpi.512" => "__builtin_ia32_gathersiv16si", + "avx512.gather.dpq.512" => "__builtin_ia32_gathersiv8di", + "avx512.gather.dps.512" => "__builtin_ia32_gathersiv16sf", + "avx512.gather.qpd.512" => "__builtin_ia32_gatherdiv8df", + "avx512.gather.qpi.512" => "__builtin_ia32_gatherdiv16si", + "avx512.gather.qpq.512" => "__builtin_ia32_gatherdiv8di", + "avx512.gather.qps.512" => "__builtin_ia32_gatherdiv16sf", + "avx512.gather3div2.df" => "__builtin_ia32_gather3div2df", + "avx512.gather3div2.di" => "__builtin_ia32_gather3div2di", + "avx512.gather3div4.df" => "__builtin_ia32_gather3div4df", + "avx512.gather3div4.di" => "__builtin_ia32_gather3div4di", + "avx512.gather3div4.sf" => "__builtin_ia32_gather3div4sf", + "avx512.gather3div4.si" => "__builtin_ia32_gather3div4si", + "avx512.gather3div8.sf" => "__builtin_ia32_gather3div8sf", + "avx512.gather3div8.si" => "__builtin_ia32_gather3div8si", + "avx512.gather3siv2.df" => "__builtin_ia32_gather3siv2df", + "avx512.gather3siv2.di" => "__builtin_ia32_gather3siv2di", + "avx512.gather3siv4.df" => "__builtin_ia32_gather3siv4df", + "avx512.gather3siv4.di" => "__builtin_ia32_gather3siv4di", + "avx512.gather3siv4.sf" => "__builtin_ia32_gather3siv4sf", + "avx512.gather3siv4.si" => "__builtin_ia32_gather3siv4si", + "avx512.gather3siv8.sf" => "__builtin_ia32_gather3siv8sf", + "avx512.gather3siv8.si" => "__builtin_ia32_gather3siv8si", + "avx512.gatherpf.dpd.512" => "__builtin_ia32_gatherpfdpd", + "avx512.gatherpf.dps.512" => "__builtin_ia32_gatherpfdps", + "avx512.gatherpf.qpd.512" => "__builtin_ia32_gatherpfqpd", + "avx512.gatherpf.qps.512" => "__builtin_ia32_gatherpfqps", + "avx512.kand.w" => "__builtin_ia32_kandhi", + "avx512.kandn.w" => "__builtin_ia32_kandnhi", + "avx512.knot.w" => "__builtin_ia32_knothi", + "avx512.kor.w" => "__builtin_ia32_korhi", + "avx512.kortestc.w" => "__builtin_ia32_kortestchi", + "avx512.kortestz.w" => "__builtin_ia32_kortestzhi", + "avx512.kunpck.bw" => "__builtin_ia32_kunpckhi", + "avx512.kunpck.dq" => "__builtin_ia32_kunpckdi", + "avx512.kunpck.wd" => "__builtin_ia32_kunpcksi", + "avx512.kxnor.w" => "__builtin_ia32_kxnorhi", + "avx512.kxor.w" => "__builtin_ia32_kxorhi", + "avx512.mask.add.pd.128" => "__builtin_ia32_addpd128_mask", + "avx512.mask.add.pd.256" => "__builtin_ia32_addpd256_mask", + "avx512.mask.add.pd.512" => "__builtin_ia32_addpd512_mask", + "avx512.mask.add.ps.128" => "__builtin_ia32_addps128_mask", + "avx512.mask.add.ps.256" => "__builtin_ia32_addps256_mask", + "avx512.mask.add.ps.512" => "__builtin_ia32_addps512_mask", + "avx512.mask.and.pd.128" => "__builtin_ia32_andpd128_mask", + "avx512.mask.and.pd.256" => "__builtin_ia32_andpd256_mask", + "avx512.mask.and.pd.512" => "__builtin_ia32_andpd512_mask", + "avx512.mask.and.ps.128" => "__builtin_ia32_andps128_mask", + "avx512.mask.and.ps.256" => "__builtin_ia32_andps256_mask", + "avx512.mask.and.ps.512" => "__builtin_ia32_andps512_mask", + "avx512.mask.andn.pd.128" => "__builtin_ia32_andnpd128_mask", + "avx512.mask.andn.pd.256" => "__builtin_ia32_andnpd256_mask", + "avx512.mask.andn.pd.512" => "__builtin_ia32_andnpd512_mask", + "avx512.mask.andn.ps.128" => "__builtin_ia32_andnps128_mask", + "avx512.mask.andn.ps.256" => "__builtin_ia32_andnps256_mask", + "avx512.mask.andn.ps.512" => "__builtin_ia32_andnps512_mask", + "avx512.mask.blend.d.512" => "__builtin_ia32_blendmd_512_mask", + "avx512.mask.blend.pd.512" => "__builtin_ia32_blendmpd_512_mask", + "avx512.mask.blend.ps.512" => "__builtin_ia32_blendmps_512_mask", + "avx512.mask.blend.q.512" => "__builtin_ia32_blendmq_512_mask", + "avx512.mask.broadcastf32x2.256" => "__builtin_ia32_broadcastf32x2_256_mask", + "avx512.mask.broadcastf32x2.512" => "__builtin_ia32_broadcastf32x2_512_mask", + "avx512.mask.broadcastf32x4.256" => "__builtin_ia32_broadcastf32x4_256_mask", + "avx512.mask.broadcastf32x4.512" => "__builtin_ia32_broadcastf32x4_512", + "avx512.mask.broadcastf32x8.512" => "__builtin_ia32_broadcastf32x8_512_mask", + "avx512.mask.broadcastf64x2.256" => "__builtin_ia32_broadcastf64x2_256_mask", + "avx512.mask.broadcastf64x2.512" => "__builtin_ia32_broadcastf64x2_512_mask", + "avx512.mask.broadcastf64x4.512" => "__builtin_ia32_broadcastf64x4_512", + "avx512.mask.broadcasti32x2.128" => "__builtin_ia32_broadcasti32x2_128_mask", + "avx512.mask.broadcasti32x2.256" => "__builtin_ia32_broadcasti32x2_256_mask", + "avx512.mask.broadcasti32x2.512" => "__builtin_ia32_broadcasti32x2_512_mask", + "avx512.mask.broadcasti32x4.256" => "__builtin_ia32_broadcasti32x4_256_mask", + "avx512.mask.broadcasti32x4.512" => "__builtin_ia32_broadcasti32x4_512", + "avx512.mask.broadcasti32x8.512" => "__builtin_ia32_broadcasti32x8_512_mask", + "avx512.mask.broadcasti64x2.256" => "__builtin_ia32_broadcasti64x2_256_mask", + "avx512.mask.broadcasti64x2.512" => "__builtin_ia32_broadcasti64x2_512_mask", + "avx512.mask.broadcasti64x4.512" => "__builtin_ia32_broadcasti64x4_512", + "avx512.mask.cmp.pd.128" => "__builtin_ia32_cmppd128_mask", + "avx512.mask.cmp.pd.256" => "__builtin_ia32_cmppd256_mask", + "avx512.mask.cmp.pd.512" => "__builtin_ia32_cmppd512_mask", + "avx512.mask.cmp.ps.128" => "__builtin_ia32_cmpps128_mask", + "avx512.mask.cmp.ps.256" => "__builtin_ia32_cmpps256_mask", + "avx512.mask.cmp.ps.512" => "__builtin_ia32_cmpps512_mask", + "avx512.mask.compress.d.128" => "__builtin_ia32_compresssi128_mask", + "avx512.mask.compress.d.256" => "__builtin_ia32_compresssi256_mask", + "avx512.mask.compress.d.512" => "__builtin_ia32_compresssi512_mask", + "avx512.mask.compress.pd.128" => "__builtin_ia32_compressdf128_mask", + "avx512.mask.compress.pd.256" => "__builtin_ia32_compressdf256_mask", + "avx512.mask.compress.pd.512" => "__builtin_ia32_compressdf512_mask", + "avx512.mask.compress.ps.128" => "__builtin_ia32_compresssf128_mask", + "avx512.mask.compress.ps.256" => "__builtin_ia32_compresssf256_mask", + "avx512.mask.compress.ps.512" => "__builtin_ia32_compresssf512_mask", + "avx512.mask.compress.q.128" => "__builtin_ia32_compressdi128_mask", + "avx512.mask.compress.q.256" => "__builtin_ia32_compressdi256_mask", + "avx512.mask.compress.q.512" => "__builtin_ia32_compressdi512_mask", + "avx512.mask.compress.store.d.128" => "__builtin_ia32_compressstoresi128_mask", + "avx512.mask.compress.store.d.256" => "__builtin_ia32_compressstoresi256_mask", + "avx512.mask.compress.store.d.512" => "__builtin_ia32_compressstoresi512_mask", + "avx512.mask.compress.store.pd.128" => "__builtin_ia32_compressstoredf128_mask", + "avx512.mask.compress.store.pd.256" => "__builtin_ia32_compressstoredf256_mask", + "avx512.mask.compress.store.pd.512" => "__builtin_ia32_compressstoredf512_mask", + "avx512.mask.compress.store.ps.128" => "__builtin_ia32_compressstoresf128_mask", + "avx512.mask.compress.store.ps.256" => "__builtin_ia32_compressstoresf256_mask", + "avx512.mask.compress.store.ps.512" => "__builtin_ia32_compressstoresf512_mask", + "avx512.mask.compress.store.q.128" => "__builtin_ia32_compressstoredi128_mask", + "avx512.mask.compress.store.q.256" => "__builtin_ia32_compressstoredi256_mask", + "avx512.mask.compress.store.q.512" => "__builtin_ia32_compressstoredi512_mask", + "avx512.mask.conflict.d.128" => "__builtin_ia32_vpconflictsi_128_mask", + "avx512.mask.conflict.d.256" => "__builtin_ia32_vpconflictsi_256_mask", + "avx512.mask.conflict.d.512" => "__builtin_ia32_vpconflictsi_512_mask", + "avx512.mask.conflict.q.128" => "__builtin_ia32_vpconflictdi_128_mask", + "avx512.mask.conflict.q.256" => "__builtin_ia32_vpconflictdi_256_mask", + "avx512.mask.conflict.q.512" => "__builtin_ia32_vpconflictdi_512_mask", + "avx512.mask.cvtdq2pd.128" => "__builtin_ia32_cvtdq2pd128_mask", + "avx512.mask.cvtdq2pd.256" => "__builtin_ia32_cvtdq2pd256_mask", + "avx512.mask.cvtdq2pd.512" => "__builtin_ia32_cvtdq2pd512_mask", + "avx512.mask.cvtdq2ps.128" => "__builtin_ia32_cvtdq2ps128_mask", + "avx512.mask.cvtdq2ps.256" => "__builtin_ia32_cvtdq2ps256_mask", + "avx512.mask.cvtdq2ps.512" => "__builtin_ia32_cvtdq2ps512_mask", + "avx512.mask.cvtpd2dq.256" => "__builtin_ia32_cvtpd2dq256_mask", + "avx512.mask.cvtps2pd.128" => "__builtin_ia32_cvtps2pd128_mask", + "avx512.mask.cvtps2pd.256" => "__builtin_ia32_cvtps2pd256_mask", + "avx512.mask.cvtqq2pd.128" => "__builtin_ia32_cvtqq2pd128_mask", + "avx512.mask.cvtqq2pd.256" => "__builtin_ia32_cvtqq2pd256_mask", + "avx512.mask.cvtqq2pd.512" => "__builtin_ia32_cvtqq2pd512_mask", + "avx512.mask.cvtqq2ps.256" => "__builtin_ia32_cvtqq2ps256_mask", + "avx512.mask.cvtqq2ps.512" => "__builtin_ia32_cvtqq2ps512_mask", + "avx512.mask.cvttpd2dq.256" => "__builtin_ia32_cvttpd2dq256_mask", + "avx512.mask.cvttps2dq.128" => "__builtin_ia32_cvttps2dq128_mask", + "avx512.mask.cvttps2dq.256" => "__builtin_ia32_cvttps2dq256_mask", + "avx512.mask.cvtudq2pd.128" => "__builtin_ia32_cvtudq2pd128_mask", + "avx512.mask.cvtudq2pd.256" => "__builtin_ia32_cvtudq2pd256_mask", + "avx512.mask.cvtudq2pd.512" => "__builtin_ia32_cvtudq2pd512_mask", + "avx512.mask.cvtudq2ps.128" => "__builtin_ia32_cvtudq2ps128_mask", + "avx512.mask.cvtudq2ps.256" => "__builtin_ia32_cvtudq2ps256_mask", + "avx512.mask.cvtudq2ps.512" => "__builtin_ia32_cvtudq2ps512_mask", + "avx512.mask.cvtuqq2pd.128" => "__builtin_ia32_cvtuqq2pd128_mask", + "avx512.mask.cvtuqq2pd.256" => "__builtin_ia32_cvtuqq2pd256_mask", + "avx512.mask.cvtuqq2pd.512" => "__builtin_ia32_cvtuqq2pd512_mask", + "avx512.mask.cvtuqq2ps.256" => "__builtin_ia32_cvtuqq2ps256_mask", + "avx512.mask.cvtuqq2ps.512" => "__builtin_ia32_cvtuqq2ps512_mask", + "avx512.mask.dbpsadbw.128" => "__builtin_ia32_dbpsadbw128_mask", + "avx512.mask.dbpsadbw.256" => "__builtin_ia32_dbpsadbw256_mask", + "avx512.mask.dbpsadbw.512" => "__builtin_ia32_dbpsadbw512_mask", + "avx512.mask.div.pd.128" => "__builtin_ia32_divpd_mask", + "avx512.mask.div.pd.256" => "__builtin_ia32_divpd256_mask", + "avx512.mask.div.pd.512" => "__builtin_ia32_divpd512_mask", + "avx512.mask.div.ps.128" => "__builtin_ia32_divps_mask", + "avx512.mask.div.ps.256" => "__builtin_ia32_divps256_mask", + "avx512.mask.div.ps.512" => "__builtin_ia32_divps512_mask", + "avx512.mask.expand.d.128" => "__builtin_ia32_expandsi128_mask", + "avx512.mask.expand.d.256" => "__builtin_ia32_expandsi256_mask", + "avx512.mask.expand.d.512" => "__builtin_ia32_expandsi512_mask", + "avx512.mask.expand.load.d.128" => "__builtin_ia32_expandloadsi128_mask", + "avx512.mask.expand.load.d.256" => "__builtin_ia32_expandloadsi256_mask", + "avx512.mask.expand.load.d.512" => "__builtin_ia32_expandloadsi512_mask", + "avx512.mask.expand.load.pd.128" => "__builtin_ia32_expandloaddf128_mask", + "avx512.mask.expand.load.pd.256" => "__builtin_ia32_expandloaddf256_mask", + "avx512.mask.expand.load.pd.512" => "__builtin_ia32_expandloaddf512_mask", + "avx512.mask.expand.load.ps.128" => "__builtin_ia32_expandloadsf128_mask", + "avx512.mask.expand.load.ps.256" => "__builtin_ia32_expandloadsf256_mask", + "avx512.mask.expand.load.ps.512" => "__builtin_ia32_expandloadsf512_mask", + "avx512.mask.expand.load.q.128" => "__builtin_ia32_expandloaddi128_mask", + "avx512.mask.expand.load.q.256" => "__builtin_ia32_expandloaddi256_mask", + "avx512.mask.expand.load.q.512" => "__builtin_ia32_expandloaddi512_mask", + "avx512.mask.expand.pd.128" => "__builtin_ia32_expanddf128_mask", + "avx512.mask.expand.pd.256" => "__builtin_ia32_expanddf256_mask", + "avx512.mask.expand.pd.512" => "__builtin_ia32_expanddf512_mask", + "avx512.mask.expand.ps.128" => "__builtin_ia32_expandsf128_mask", + "avx512.mask.expand.ps.256" => "__builtin_ia32_expandsf256_mask", + "avx512.mask.expand.ps.512" => "__builtin_ia32_expandsf512_mask", + "avx512.mask.expand.q.128" => "__builtin_ia32_expanddi128_mask", + "avx512.mask.expand.q.256" => "__builtin_ia32_expanddi256_mask", + "avx512.mask.expand.q.512" => "__builtin_ia32_expanddi512_mask", + "avx512.mask.fpclass.pd.128" => "__builtin_ia32_fpclasspd128_mask", + "avx512.mask.fpclass.pd.256" => "__builtin_ia32_fpclasspd256_mask", + "avx512.mask.fpclass.pd.512" => "__builtin_ia32_fpclasspd512_mask", + "avx512.mask.fpclass.ps.128" => "__builtin_ia32_fpclassps128_mask", + "avx512.mask.fpclass.ps.256" => "__builtin_ia32_fpclassps256_mask", + "avx512.mask.fpclass.ps.512" => "__builtin_ia32_fpclassps512_mask", + "avx512.mask.insertf32x4.256" => "__builtin_ia32_insertf32x4_256_mask", + "avx512.mask.insertf32x4.512" => "__builtin_ia32_insertf32x4_mask", + "avx512.mask.insertf32x8.512" => "__builtin_ia32_insertf32x8_mask", + "avx512.mask.insertf64x2.256" => "__builtin_ia32_insertf64x2_256_mask", + "avx512.mask.insertf64x2.512" => "__builtin_ia32_insertf64x2_512_mask", + "avx512.mask.insertf64x4.512" => "__builtin_ia32_insertf64x4_mask", + "avx512.mask.inserti32x4.256" => "__builtin_ia32_inserti32x4_256_mask", + "avx512.mask.inserti32x4.512" => "__builtin_ia32_inserti32x4_mask", + "avx512.mask.inserti32x8.512" => "__builtin_ia32_inserti32x8_mask", + "avx512.mask.inserti64x2.256" => "__builtin_ia32_inserti64x2_256_mask", + "avx512.mask.inserti64x2.512" => "__builtin_ia32_inserti64x2_512_mask", + "avx512.mask.inserti64x4.512" => "__builtin_ia32_inserti64x4_mask", + "avx512.mask.loadu.d.512" => "__builtin_ia32_loaddqusi512_mask", + "avx512.mask.loadu.pd.512" => "__builtin_ia32_loadupd512_mask", + "avx512.mask.loadu.ps.512" => "__builtin_ia32_loadups512_mask", + "avx512.mask.loadu.q.512" => "__builtin_ia32_loaddqudi512_mask", + "avx512.mask.lzcnt.d.512" => "__builtin_ia32_vplzcntd_512_mask", + "avx512.mask.lzcnt.q.512" => "__builtin_ia32_vplzcntq_512_mask", + "avx512.mask.max.pd.128" => "__builtin_ia32_maxpd_mask", + "avx512.mask.max.pd.256" => "__builtin_ia32_maxpd256_mask", + "avx512.mask.max.pd.512" => "__builtin_ia32_maxpd512_mask", + "avx512.mask.max.ps.128" => "__builtin_ia32_maxps_mask", + "avx512.mask.max.ps.256" => "__builtin_ia32_maxps256_mask", + "avx512.mask.max.ps.512" => "__builtin_ia32_maxps512_mask", + "avx512.mask.min.pd.128" => "__builtin_ia32_minpd_mask", + "avx512.mask.min.pd.256" => "__builtin_ia32_minpd256_mask", + "avx512.mask.min.pd.512" => "__builtin_ia32_minpd512_mask", + "avx512.mask.min.ps.128" => "__builtin_ia32_minps_mask", + "avx512.mask.min.ps.256" => "__builtin_ia32_minps256_mask", + "avx512.mask.min.ps.512" => "__builtin_ia32_minps512_mask", + "avx512.mask.move.sd" => "__builtin_ia32_movsd_mask", + "avx512.mask.move.ss" => "__builtin_ia32_movss_mask", + "avx512.mask.mul.pd.128" => "__builtin_ia32_mulpd_mask", + "avx512.mask.mul.pd.256" => "__builtin_ia32_mulpd256_mask", + "avx512.mask.mul.pd.512" => "__builtin_ia32_mulpd512_mask", + "avx512.mask.mul.ps.128" => "__builtin_ia32_mulps_mask", + "avx512.mask.mul.ps.256" => "__builtin_ia32_mulps256_mask", + "avx512.mask.mul.ps.512" => "__builtin_ia32_mulps512_mask", + "avx512.mask.or.pd.128" => "__builtin_ia32_orpd128_mask", + "avx512.mask.or.pd.256" => "__builtin_ia32_orpd256_mask", + "avx512.mask.or.pd.512" => "__builtin_ia32_orpd512_mask", + "avx512.mask.or.ps.128" => "__builtin_ia32_orps128_mask", + "avx512.mask.or.ps.256" => "__builtin_ia32_orps256_mask", + "avx512.mask.or.ps.512" => "__builtin_ia32_orps512_mask", + "avx512.mask.pabs.b.128" => "__builtin_ia32_pabsb128_mask", + "avx512.mask.pabs.b.256" => "__builtin_ia32_pabsb256_mask", + "avx512.mask.pabs.b.512" => "__builtin_ia32_pabsb512_mask", + "avx512.mask.pabs.d.128" => "__builtin_ia32_pabsd128_mask", + "avx512.mask.pabs.d.256" => "__builtin_ia32_pabsd256_mask", + "avx512.mask.pabs.d.512" => "__builtin_ia32_pabsd512_mask", + "avx512.mask.pabs.q.128" => "__builtin_ia32_pabsq128_mask", + "avx512.mask.pabs.q.256" => "__builtin_ia32_pabsq256_mask", + "avx512.mask.pabs.q.512" => "__builtin_ia32_pabsq512_mask", + "avx512.mask.pabs.w.128" => "__builtin_ia32_pabsw128_mask", + "avx512.mask.pabs.w.256" => "__builtin_ia32_pabsw256_mask", + "avx512.mask.pabs.w.512" => "__builtin_ia32_pabsw512_mask", + "avx512.mask.packssdw.128" => "__builtin_ia32_packssdw128_mask", + "avx512.mask.packssdw.256" => "__builtin_ia32_packssdw256_mask", + "avx512.mask.packssdw.512" => "__builtin_ia32_packssdw512_mask", + "avx512.mask.packsswb.128" => "__builtin_ia32_packsswb128_mask", + "avx512.mask.packsswb.256" => "__builtin_ia32_packsswb256_mask", + "avx512.mask.packsswb.512" => "__builtin_ia32_packsswb512_mask", + "avx512.mask.packusdw.128" => "__builtin_ia32_packusdw128_mask", + "avx512.mask.packusdw.256" => "__builtin_ia32_packusdw256_mask", + "avx512.mask.packusdw.512" => "__builtin_ia32_packusdw512_mask", + "avx512.mask.packuswb.128" => "__builtin_ia32_packuswb128_mask", + "avx512.mask.packuswb.256" => "__builtin_ia32_packuswb256_mask", + "avx512.mask.packuswb.512" => "__builtin_ia32_packuswb512_mask", + "avx512.mask.padd.b.128" => "__builtin_ia32_paddb128_mask", + "avx512.mask.padd.b.256" => "__builtin_ia32_paddb256_mask", + "avx512.mask.padd.b.512" => "__builtin_ia32_paddb512_mask", + "avx512.mask.padd.d.128" => "__builtin_ia32_paddd128_mask", + "avx512.mask.padd.d.256" => "__builtin_ia32_paddd256_mask", + "avx512.mask.padd.d.512" => "__builtin_ia32_paddd512_mask", + "avx512.mask.padd.q.128" => "__builtin_ia32_paddq128_mask", + "avx512.mask.padd.q.256" => "__builtin_ia32_paddq256_mask", + "avx512.mask.padd.q.512" => "__builtin_ia32_paddq512_mask", + "avx512.mask.padd.w.128" => "__builtin_ia32_paddw128_mask", + "avx512.mask.padd.w.256" => "__builtin_ia32_paddw256_mask", + "avx512.mask.padd.w.512" => "__builtin_ia32_paddw512_mask", + "avx512.mask.padds.b.128" => "__builtin_ia32_paddsb128_mask", + "avx512.mask.padds.b.256" => "__builtin_ia32_paddsb256_mask", + "avx512.mask.padds.b.512" => "__builtin_ia32_paddsb512_mask", + "avx512.mask.padds.w.128" => "__builtin_ia32_paddsw128_mask", + "avx512.mask.padds.w.256" => "__builtin_ia32_paddsw256_mask", + "avx512.mask.padds.w.512" => "__builtin_ia32_paddsw512_mask", + "avx512.mask.paddus.b.128" => "__builtin_ia32_paddusb128_mask", + "avx512.mask.paddus.b.256" => "__builtin_ia32_paddusb256_mask", + "avx512.mask.paddus.b.512" => "__builtin_ia32_paddusb512_mask", + "avx512.mask.paddus.w.128" => "__builtin_ia32_paddusw128_mask", + "avx512.mask.paddus.w.256" => "__builtin_ia32_paddusw256_mask", + "avx512.mask.paddus.w.512" => "__builtin_ia32_paddusw512_mask", + "avx512.mask.pand.d.512" => "__builtin_ia32_pandd512_mask", + "avx512.mask.pand.q.512" => "__builtin_ia32_pandq512_mask", + "avx512.mask.pavg.b.128" => "__builtin_ia32_pavgb128_mask", + "avx512.mask.pavg.b.256" => "__builtin_ia32_pavgb256_mask", + "avx512.mask.pavg.b.512" => "__builtin_ia32_pavgb512_mask", + "avx512.mask.pavg.w.128" => "__builtin_ia32_pavgw128_mask", + "avx512.mask.pavg.w.256" => "__builtin_ia32_pavgw256_mask", + "avx512.mask.pavg.w.512" => "__builtin_ia32_pavgw512_mask", + "avx512.mask.pbroadcast.b.gpr.128" => "__builtin_ia32_pbroadcastb128_gpr_mask", + "avx512.mask.pbroadcast.b.gpr.256" => "__builtin_ia32_pbroadcastb256_gpr_mask", + "avx512.mask.pbroadcast.b.gpr.512" => "__builtin_ia32_pbroadcastb512_gpr_mask", + "avx512.mask.pbroadcast.d.gpr.128" => "__builtin_ia32_pbroadcastd128_gpr_mask", + "avx512.mask.pbroadcast.d.gpr.256" => "__builtin_ia32_pbroadcastd256_gpr_mask", + "avx512.mask.pbroadcast.d.gpr.512" => "__builtin_ia32_pbroadcastd512_gpr_mask", + "avx512.mask.pbroadcast.q.gpr.128" => "__builtin_ia32_pbroadcastq128_gpr_mask", + "avx512.mask.pbroadcast.q.gpr.256" => "__builtin_ia32_pbroadcastq256_gpr_mask", + "avx512.mask.pbroadcast.q.gpr.512" => "__builtin_ia32_pbroadcastq512_gpr_mask", + "avx512.mask.pbroadcast.q.mem.512" => "__builtin_ia32_pbroadcastq512_mem_mask", + "avx512.mask.pbroadcast.w.gpr.128" => "__builtin_ia32_pbroadcastw128_gpr_mask", + "avx512.mask.pbroadcast.w.gpr.256" => "__builtin_ia32_pbroadcastw256_gpr_mask", + "avx512.mask.pbroadcast.w.gpr.512" => "__builtin_ia32_pbroadcastw512_gpr_mask", + "avx512.mask.pcmpeq.b.128" => "__builtin_ia32_pcmpeqb128_mask", + "avx512.mask.pcmpeq.b.256" => "__builtin_ia32_pcmpeqb256_mask", + "avx512.mask.pcmpeq.b.512" => "__builtin_ia32_pcmpeqb512_mask", + "avx512.mask.pcmpeq.d.128" => "__builtin_ia32_pcmpeqd128_mask", + "avx512.mask.pcmpeq.d.256" => "__builtin_ia32_pcmpeqd256_mask", + "avx512.mask.pcmpeq.d.512" => "__builtin_ia32_pcmpeqd512_mask", + "avx512.mask.pcmpeq.q.128" => "__builtin_ia32_pcmpeqq128_mask", + "avx512.mask.pcmpeq.q.256" => "__builtin_ia32_pcmpeqq256_mask", + "avx512.mask.pcmpeq.q.512" => "__builtin_ia32_pcmpeqq512_mask", + "avx512.mask.pcmpeq.w.128" => "__builtin_ia32_pcmpeqw128_mask", + "avx512.mask.pcmpeq.w.256" => "__builtin_ia32_pcmpeqw256_mask", + "avx512.mask.pcmpeq.w.512" => "__builtin_ia32_pcmpeqw512_mask", + "avx512.mask.pcmpgt.b.128" => "__builtin_ia32_pcmpgtb128_mask", + "avx512.mask.pcmpgt.b.256" => "__builtin_ia32_pcmpgtb256_mask", + "avx512.mask.pcmpgt.b.512" => "__builtin_ia32_pcmpgtb512_mask", + "avx512.mask.pcmpgt.d.128" => "__builtin_ia32_pcmpgtd128_mask", + "avx512.mask.pcmpgt.d.256" => "__builtin_ia32_pcmpgtd256_mask", + "avx512.mask.pcmpgt.d.512" => "__builtin_ia32_pcmpgtd512_mask", + "avx512.mask.pcmpgt.q.128" => "__builtin_ia32_pcmpgtq128_mask", + "avx512.mask.pcmpgt.q.256" => "__builtin_ia32_pcmpgtq256_mask", + "avx512.mask.pcmpgt.q.512" => "__builtin_ia32_pcmpgtq512_mask", + "avx512.mask.pcmpgt.w.128" => "__builtin_ia32_pcmpgtw128_mask", + "avx512.mask.pcmpgt.w.256" => "__builtin_ia32_pcmpgtw256_mask", + "avx512.mask.pcmpgt.w.512" => "__builtin_ia32_pcmpgtw512_mask", + "avx512.mask.permvar.df.256" => "__builtin_ia32_permvardf256_mask", + "avx512.mask.permvar.df.512" => "__builtin_ia32_permvardf512_mask", + "avx512.mask.permvar.di.256" => "__builtin_ia32_permvardi256_mask", + "avx512.mask.permvar.di.512" => "__builtin_ia32_permvardi512_mask", + "avx512.mask.permvar.hi.128" => "__builtin_ia32_permvarhi128_mask", + "avx512.mask.permvar.hi.256" => "__builtin_ia32_permvarhi256_mask", + "avx512.mask.permvar.hi.512" => "__builtin_ia32_permvarhi512_mask", + "avx512.mask.permvar.qi.128" => "__builtin_ia32_permvarqi128_mask", + "avx512.mask.permvar.qi.256" => "__builtin_ia32_permvarqi256_mask", + "avx512.mask.permvar.qi.512" => "__builtin_ia32_permvarqi512_mask", + "avx512.mask.permvar.sf.256" => "__builtin_ia32_permvarsf256_mask", + "avx512.mask.permvar.sf.512" => "__builtin_ia32_permvarsf512_mask", + "avx512.mask.permvar.si.256" => "__builtin_ia32_permvarsi256_mask", + "avx512.mask.permvar.si.512" => "__builtin_ia32_permvarsi512_mask", + "avx512.mask.pmaddubs.w.128" => "__builtin_ia32_pmaddubsw128_mask", + "avx512.mask.pmaddubs.w.256" => "__builtin_ia32_pmaddubsw256_mask", + "avx512.mask.pmaddubs.w.512" => "__builtin_ia32_pmaddubsw512_mask", + "avx512.mask.pmaddw.d.128" => "__builtin_ia32_pmaddwd128_mask", + "avx512.mask.pmaddw.d.256" => "__builtin_ia32_pmaddwd256_mask", + "avx512.mask.pmaddw.d.512" => "__builtin_ia32_pmaddwd512_mask", + "avx512.mask.pmaxs.b.128" => "__builtin_ia32_pmaxsb128_mask", + "avx512.mask.pmaxs.b.256" => "__builtin_ia32_pmaxsb256_mask", + "avx512.mask.pmaxs.b.512" => "__builtin_ia32_pmaxsb512_mask", + "avx512.mask.pmaxs.d.128" => "__builtin_ia32_pmaxsd128_mask", + "avx512.mask.pmaxs.d.256" => "__builtin_ia32_pmaxsd256_mask", + "avx512.mask.pmaxs.d.512" => "__builtin_ia32_pmaxsd512_mask", + "avx512.mask.pmaxs.q.128" => "__builtin_ia32_pmaxsq128_mask", + "avx512.mask.pmaxs.q.256" => "__builtin_ia32_pmaxsq256_mask", + "avx512.mask.pmaxs.q.512" => "__builtin_ia32_pmaxsq512_mask", + "avx512.mask.pmaxs.w.128" => "__builtin_ia32_pmaxsw128_mask", + "avx512.mask.pmaxs.w.256" => "__builtin_ia32_pmaxsw256_mask", + "avx512.mask.pmaxs.w.512" => "__builtin_ia32_pmaxsw512_mask", + "avx512.mask.pmaxu.b.128" => "__builtin_ia32_pmaxub128_mask", + "avx512.mask.pmaxu.b.256" => "__builtin_ia32_pmaxub256_mask", + "avx512.mask.pmaxu.b.512" => "__builtin_ia32_pmaxub512_mask", + "avx512.mask.pmaxu.d.128" => "__builtin_ia32_pmaxud128_mask", + "avx512.mask.pmaxu.d.256" => "__builtin_ia32_pmaxud256_mask", + "avx512.mask.pmaxu.d.512" => "__builtin_ia32_pmaxud512_mask", + "avx512.mask.pmaxu.q.128" => "__builtin_ia32_pmaxuq128_mask", + "avx512.mask.pmaxu.q.256" => "__builtin_ia32_pmaxuq256_mask", + "avx512.mask.pmaxu.q.512" => "__builtin_ia32_pmaxuq512_mask", + "avx512.mask.pmaxu.w.128" => "__builtin_ia32_pmaxuw128_mask", + "avx512.mask.pmaxu.w.256" => "__builtin_ia32_pmaxuw256_mask", + "avx512.mask.pmaxu.w.512" => "__builtin_ia32_pmaxuw512_mask", + "avx512.mask.pmins.b.128" => "__builtin_ia32_pminsb128_mask", + "avx512.mask.pmins.b.256" => "__builtin_ia32_pminsb256_mask", + "avx512.mask.pmins.b.512" => "__builtin_ia32_pminsb512_mask", + "avx512.mask.pmins.d.128" => "__builtin_ia32_pminsd128_mask", + "avx512.mask.pmins.d.256" => "__builtin_ia32_pminsd256_mask", + "avx512.mask.pmins.d.512" => "__builtin_ia32_pminsd512_mask", + "avx512.mask.pmins.q.128" => "__builtin_ia32_pminsq128_mask", + "avx512.mask.pmins.q.256" => "__builtin_ia32_pminsq256_mask", + "avx512.mask.pmins.q.512" => "__builtin_ia32_pminsq512_mask", + "avx512.mask.pmins.w.128" => "__builtin_ia32_pminsw128_mask", + "avx512.mask.pmins.w.256" => "__builtin_ia32_pminsw256_mask", + "avx512.mask.pmins.w.512" => "__builtin_ia32_pminsw512_mask", + "avx512.mask.pminu.b.128" => "__builtin_ia32_pminub128_mask", + "avx512.mask.pminu.b.256" => "__builtin_ia32_pminub256_mask", + "avx512.mask.pminu.b.512" => "__builtin_ia32_pminub512_mask", + "avx512.mask.pminu.d.128" => "__builtin_ia32_pminud128_mask", + "avx512.mask.pminu.d.256" => "__builtin_ia32_pminud256_mask", + "avx512.mask.pminu.d.512" => "__builtin_ia32_pminud512_mask", + "avx512.mask.pminu.q.128" => "__builtin_ia32_pminuq128_mask", + "avx512.mask.pminu.q.256" => "__builtin_ia32_pminuq256_mask", + "avx512.mask.pminu.q.512" => "__builtin_ia32_pminuq512_mask", + "avx512.mask.pminu.w.128" => "__builtin_ia32_pminuw128_mask", + "avx512.mask.pminu.w.256" => "__builtin_ia32_pminuw256_mask", + "avx512.mask.pminu.w.512" => "__builtin_ia32_pminuw512_mask", + "avx512.mask.pmov.db.512" => "__builtin_ia32_pmovdb512_mask", + "avx512.mask.pmov.dw.512" => "__builtin_ia32_pmovdw512_mask", + "avx512.mask.pmov.qd.256" => "__builtin_ia32_pmovqd256_mask", + "avx512.mask.pmov.qd.512" => "__builtin_ia32_pmovqd512_mask", + "avx512.mask.pmov.qw.512" => "__builtin_ia32_pmovqw512_mask", + "avx512.mask.pmov.wb.256" => "__builtin_ia32_pmovwb256_mask", + "avx512.mask.pmov.wb.512" => "__builtin_ia32_pmovwb512_mask", + "avx512.mask.pmovsxb.d.128" => "__builtin_ia32_pmovsxbd128_mask", + "avx512.mask.pmovsxb.d.256" => "__builtin_ia32_pmovsxbd256_mask", + "avx512.mask.pmovsxb.d.512" => "__builtin_ia32_pmovsxbd512_mask", + "avx512.mask.pmovsxb.q.128" => "__builtin_ia32_pmovsxbq128_mask", + "avx512.mask.pmovsxb.q.256" => "__builtin_ia32_pmovsxbq256_mask", + "avx512.mask.pmovsxb.q.512" => "__builtin_ia32_pmovsxbq512_mask", + "avx512.mask.pmovsxb.w.128" => "__builtin_ia32_pmovsxbw128_mask", + "avx512.mask.pmovsxb.w.256" => "__builtin_ia32_pmovsxbw256_mask", + "avx512.mask.pmovsxb.w.512" => "__builtin_ia32_pmovsxbw512_mask", + "avx512.mask.pmovsxd.q.128" => "__builtin_ia32_pmovsxdq128_mask", + "avx512.mask.pmovsxd.q.256" => "__builtin_ia32_pmovsxdq256_mask", + "avx512.mask.pmovsxd.q.512" => "__builtin_ia32_pmovsxdq512_mask", + "avx512.mask.pmovsxw.d.128" => "__builtin_ia32_pmovsxwd128_mask", + "avx512.mask.pmovsxw.d.256" => "__builtin_ia32_pmovsxwd256_mask", + "avx512.mask.pmovsxw.d.512" => "__builtin_ia32_pmovsxwd512_mask", + "avx512.mask.pmovsxw.q.128" => "__builtin_ia32_pmovsxwq128_mask", + "avx512.mask.pmovsxw.q.256" => "__builtin_ia32_pmovsxwq256_mask", + "avx512.mask.pmovsxw.q.512" => "__builtin_ia32_pmovsxwq512_mask", + "avx512.mask.pmovzxb.d.128" => "__builtin_ia32_pmovzxbd128_mask", + "avx512.mask.pmovzxb.d.256" => "__builtin_ia32_pmovzxbd256_mask", + "avx512.mask.pmovzxb.d.512" => "__builtin_ia32_pmovzxbd512_mask", + "avx512.mask.pmovzxb.q.128" => "__builtin_ia32_pmovzxbq128_mask", + "avx512.mask.pmovzxb.q.256" => "__builtin_ia32_pmovzxbq256_mask", + "avx512.mask.pmovzxb.q.512" => "__builtin_ia32_pmovzxbq512_mask", + "avx512.mask.pmovzxb.w.128" => "__builtin_ia32_pmovzxbw128_mask", + "avx512.mask.pmovzxb.w.256" => "__builtin_ia32_pmovzxbw256_mask", + "avx512.mask.pmovzxb.w.512" => "__builtin_ia32_pmovzxbw512_mask", + "avx512.mask.pmovzxd.q.128" => "__builtin_ia32_pmovzxdq128_mask", + "avx512.mask.pmovzxd.q.256" => "__builtin_ia32_pmovzxdq256_mask", + "avx512.mask.pmovzxd.q.512" => "__builtin_ia32_pmovzxdq512_mask", + "avx512.mask.pmovzxw.d.128" => "__builtin_ia32_pmovzxwd128_mask", + "avx512.mask.pmovzxw.d.256" => "__builtin_ia32_pmovzxwd256_mask", + "avx512.mask.pmovzxw.d.512" => "__builtin_ia32_pmovzxwd512_mask", + "avx512.mask.pmovzxw.q.128" => "__builtin_ia32_pmovzxwq128_mask", + "avx512.mask.pmovzxw.q.256" => "__builtin_ia32_pmovzxwq256_mask", + "avx512.mask.pmovzxw.q.512" => "__builtin_ia32_pmovzxwq512_mask", + "avx512.mask.pmul.dq.128" => "__builtin_ia32_pmuldq128_mask", + "avx512.mask.pmul.dq.256" => "__builtin_ia32_pmuldq256_mask", + "avx512.mask.pmul.dq.512" => "__builtin_ia32_pmuldq512_mask", + "avx512.mask.pmul.hr.sw.128" => "__builtin_ia32_pmulhrsw128_mask", + "avx512.mask.pmul.hr.sw.256" => "__builtin_ia32_pmulhrsw256_mask", + "avx512.mask.pmul.hr.sw.512" => "__builtin_ia32_pmulhrsw512_mask", + "avx512.mask.pmulh.w.128" => "__builtin_ia32_pmulhw128_mask", + "avx512.mask.pmulh.w.256" => "__builtin_ia32_pmulhw256_mask", + "avx512.mask.pmulh.w.512" => "__builtin_ia32_pmulhw512_mask", + "avx512.mask.pmulhu.w.128" => "__builtin_ia32_pmulhuw128_mask", + "avx512.mask.pmulhu.w.256" => "__builtin_ia32_pmulhuw256_mask", + "avx512.mask.pmulhu.w.512" => "__builtin_ia32_pmulhuw512_mask", + "avx512.mask.pmull.d.128" => "__builtin_ia32_pmulld128_mask", + "avx512.mask.pmull.d.256" => "__builtin_ia32_pmulld256_mask", + "avx512.mask.pmull.d.512" => "__builtin_ia32_pmulld512_mask", + "avx512.mask.pmull.q.128" => "__builtin_ia32_pmullq128_mask", + "avx512.mask.pmull.q.256" => "__builtin_ia32_pmullq256_mask", + "avx512.mask.pmull.q.512" => "__builtin_ia32_pmullq512_mask", + "avx512.mask.pmull.w.128" => "__builtin_ia32_pmullw128_mask", + "avx512.mask.pmull.w.256" => "__builtin_ia32_pmullw256_mask", + "avx512.mask.pmull.w.512" => "__builtin_ia32_pmullw512_mask", + "avx512.mask.pmultishift.qb.128" => "__builtin_ia32_vpmultishiftqb128_mask", + "avx512.mask.pmultishift.qb.256" => "__builtin_ia32_vpmultishiftqb256_mask", + "avx512.mask.pmultishift.qb.512" => "__builtin_ia32_vpmultishiftqb512_mask", + "avx512.mask.pmulu.dq.128" => "__builtin_ia32_pmuludq128_mask", + "avx512.mask.pmulu.dq.256" => "__builtin_ia32_pmuludq256_mask", + "avx512.mask.pmulu.dq.512" => "__builtin_ia32_pmuludq512_mask", + "avx512.mask.prol.d.128" => "__builtin_ia32_prold128_mask", + "avx512.mask.prol.d.256" => "__builtin_ia32_prold256_mask", + "avx512.mask.prol.d.512" => "__builtin_ia32_prold512_mask", + "avx512.mask.prol.q.128" => "__builtin_ia32_prolq128_mask", + "avx512.mask.prol.q.256" => "__builtin_ia32_prolq256_mask", + "avx512.mask.prol.q.512" => "__builtin_ia32_prolq512_mask", + "avx512.mask.prolv.d.128" => "__builtin_ia32_prolvd128_mask", + "avx512.mask.prolv.d.256" => "__builtin_ia32_prolvd256_mask", + "avx512.mask.prolv.d.512" => "__builtin_ia32_prolvd512_mask", + "avx512.mask.prolv.q.128" => "__builtin_ia32_prolvq128_mask", + "avx512.mask.prolv.q.256" => "__builtin_ia32_prolvq256_mask", + "avx512.mask.prolv.q.512" => "__builtin_ia32_prolvq512_mask", + "avx512.mask.pror.d.128" => "__builtin_ia32_prord128_mask", + "avx512.mask.pror.d.256" => "__builtin_ia32_prord256_mask", + "avx512.mask.pror.d.512" => "__builtin_ia32_prord512_mask", + "avx512.mask.pror.q.128" => "__builtin_ia32_prorq128_mask", + "avx512.mask.pror.q.256" => "__builtin_ia32_prorq256_mask", + "avx512.mask.pror.q.512" => "__builtin_ia32_prorq512_mask", + "avx512.mask.prorv.d.128" => "__builtin_ia32_prorvd128_mask", + "avx512.mask.prorv.d.256" => "__builtin_ia32_prorvd256_mask", + "avx512.mask.prorv.d.512" => "__builtin_ia32_prorvd512_mask", + "avx512.mask.prorv.q.128" => "__builtin_ia32_prorvq128_mask", + "avx512.mask.prorv.q.256" => "__builtin_ia32_prorvq256_mask", + "avx512.mask.prorv.q.512" => "__builtin_ia32_prorvq512_mask", + "avx512.mask.pshuf.b.128" => "__builtin_ia32_pshufb128_mask", + "avx512.mask.pshuf.b.256" => "__builtin_ia32_pshufb256_mask", + "avx512.mask.pshuf.b.512" => "__builtin_ia32_pshufb512_mask", + "avx512.mask.psll.d" => "__builtin_ia32_pslld512_mask", + "avx512.mask.psll.d.128" => "__builtin_ia32_pslld128_mask", + "avx512.mask.psll.d.256" => "__builtin_ia32_pslld256_mask", + "avx512.mask.psll.di.128" => "__builtin_ia32_pslldi128_mask", + "avx512.mask.psll.di.256" => "__builtin_ia32_pslldi256_mask", + "avx512.mask.psll.di.512" => "__builtin_ia32_pslldi512_mask", + "avx512.mask.psll.q" => "__builtin_ia32_psllq512_mask", + "avx512.mask.psll.q.128" => "__builtin_ia32_psllq128_mask", + "avx512.mask.psll.q.256" => "__builtin_ia32_psllq256_mask", + "avx512.mask.psll.qi.128" => "__builtin_ia32_psllqi128_mask", + "avx512.mask.psll.qi.256" => "__builtin_ia32_psllqi256_mask", + "avx512.mask.psll.qi.512" => "__builtin_ia32_psllqi512_mask", + "avx512.mask.psll.w.128" => "__builtin_ia32_psllw128_mask", + "avx512.mask.psll.w.256" => "__builtin_ia32_psllw256_mask", + "avx512.mask.psll.w.512" => "__builtin_ia32_psllw512_mask", + "avx512.mask.psll.wi.128" => "__builtin_ia32_psllwi128_mask", + "avx512.mask.psll.wi.256" => "__builtin_ia32_psllwi256_mask", + "avx512.mask.psll.wi.512" => "__builtin_ia32_psllwi512_mask", + "avx512.mask.psllv.d" => "__builtin_ia32_psllv16si_mask", + "avx512.mask.psllv.q" => "__builtin_ia32_psllv8di_mask", + "avx512.mask.psllv16.hi" => "__builtin_ia32_psllv16hi_mask", + "avx512.mask.psllv2.di" => "__builtin_ia32_psllv2di_mask", + "avx512.mask.psllv32hi" => "__builtin_ia32_psllv32hi_mask", + "avx512.mask.psllv4.di" => "__builtin_ia32_psllv4di_mask", + "avx512.mask.psllv4.si" => "__builtin_ia32_psllv4si_mask", + "avx512.mask.psllv8.hi" => "__builtin_ia32_psllv8hi_mask", + "avx512.mask.psllv8.si" => "__builtin_ia32_psllv8si_mask", + "avx512.mask.psra.d" => "__builtin_ia32_psrad512_mask", + "avx512.mask.psra.d.128" => "__builtin_ia32_psrad128_mask", + "avx512.mask.psra.d.256" => "__builtin_ia32_psrad256_mask", + "avx512.mask.psra.di.128" => "__builtin_ia32_psradi128_mask", + "avx512.mask.psra.di.256" => "__builtin_ia32_psradi256_mask", + "avx512.mask.psra.di.512" => "__builtin_ia32_psradi512_mask", + "avx512.mask.psra.q" => "__builtin_ia32_psraq512_mask", + "avx512.mask.psra.q.128" => "__builtin_ia32_psraq128_mask", + "avx512.mask.psra.q.256" => "__builtin_ia32_psraq256_mask", + "avx512.mask.psra.qi.128" => "__builtin_ia32_psraqi128_mask", + "avx512.mask.psra.qi.256" => "__builtin_ia32_psraqi256_mask", + "avx512.mask.psra.qi.512" => "__builtin_ia32_psraqi512_mask", + "avx512.mask.psra.w.128" => "__builtin_ia32_psraw128_mask", + "avx512.mask.psra.w.256" => "__builtin_ia32_psraw256_mask", + "avx512.mask.psra.w.512" => "__builtin_ia32_psraw512_mask", + "avx512.mask.psra.wi.128" => "__builtin_ia32_psrawi128_mask", + "avx512.mask.psra.wi.256" => "__builtin_ia32_psrawi256_mask", + "avx512.mask.psra.wi.512" => "__builtin_ia32_psrawi512_mask", + "avx512.mask.psrav.d" => "__builtin_ia32_psrav16si_mask", + "avx512.mask.psrav.q" => "__builtin_ia32_psrav8di_mask", + "avx512.mask.psrav.q.128" => "__builtin_ia32_psravq128_mask", + "avx512.mask.psrav.q.256" => "__builtin_ia32_psravq256_mask", + "avx512.mask.psrav16.hi" => "__builtin_ia32_psrav16hi_mask", + "avx512.mask.psrav32.hi" => "__builtin_ia32_psrav32hi_mask", + "avx512.mask.psrav4.si" => "__builtin_ia32_psrav4si_mask", + "avx512.mask.psrav8.hi" => "__builtin_ia32_psrav8hi_mask", + "avx512.mask.psrav8.si" => "__builtin_ia32_psrav8si_mask", + "avx512.mask.psrl.d" => "__builtin_ia32_psrld512_mask", + "avx512.mask.psrl.d.128" => "__builtin_ia32_psrld128_mask", + "avx512.mask.psrl.d.256" => "__builtin_ia32_psrld256_mask", + "avx512.mask.psrl.di.128" => "__builtin_ia32_psrldi128_mask", + "avx512.mask.psrl.di.256" => "__builtin_ia32_psrldi256_mask", + "avx512.mask.psrl.di.512" => "__builtin_ia32_psrldi512_mask", + "avx512.mask.psrl.q" => "__builtin_ia32_psrlq512_mask", + "avx512.mask.psrl.q.128" => "__builtin_ia32_psrlq128_mask", + "avx512.mask.psrl.q.256" => "__builtin_ia32_psrlq256_mask", + "avx512.mask.psrl.qi.128" => "__builtin_ia32_psrlqi128_mask", + "avx512.mask.psrl.qi.256" => "__builtin_ia32_psrlqi256_mask", + "avx512.mask.psrl.qi.512" => "__builtin_ia32_psrlqi512_mask", + "avx512.mask.psrl.w.128" => "__builtin_ia32_psrlw128_mask", + "avx512.mask.psrl.w.256" => "__builtin_ia32_psrlw256_mask", + "avx512.mask.psrl.w.512" => "__builtin_ia32_psrlw512_mask", + "avx512.mask.psrl.wi.128" => "__builtin_ia32_psrlwi128_mask", + "avx512.mask.psrl.wi.256" => "__builtin_ia32_psrlwi256_mask", + "avx512.mask.psrl.wi.512" => "__builtin_ia32_psrlwi512_mask", + "avx512.mask.psrlv.d" => "__builtin_ia32_psrlv16si_mask", + "avx512.mask.psrlv.q" => "__builtin_ia32_psrlv8di_mask", + "avx512.mask.psrlv16.hi" => "__builtin_ia32_psrlv16hi_mask", + "avx512.mask.psrlv2.di" => "__builtin_ia32_psrlv2di_mask", + "avx512.mask.psrlv32hi" => "__builtin_ia32_psrlv32hi_mask", + "avx512.mask.psrlv4.di" => "__builtin_ia32_psrlv4di_mask", + "avx512.mask.psrlv4.si" => "__builtin_ia32_psrlv4si_mask", + "avx512.mask.psrlv8.hi" => "__builtin_ia32_psrlv8hi_mask", + "avx512.mask.psrlv8.si" => "__builtin_ia32_psrlv8si_mask", + "avx512.mask.psub.b.128" => "__builtin_ia32_psubb128_mask", + "avx512.mask.psub.b.256" => "__builtin_ia32_psubb256_mask", + "avx512.mask.psub.b.512" => "__builtin_ia32_psubb512_mask", + "avx512.mask.psub.d.128" => "__builtin_ia32_psubd128_mask", + "avx512.mask.psub.d.256" => "__builtin_ia32_psubd256_mask", + "avx512.mask.psub.d.512" => "__builtin_ia32_psubd512_mask", + "avx512.mask.psub.q.128" => "__builtin_ia32_psubq128_mask", + "avx512.mask.psub.q.256" => "__builtin_ia32_psubq256_mask", + "avx512.mask.psub.q.512" => "__builtin_ia32_psubq512_mask", + "avx512.mask.psub.w.128" => "__builtin_ia32_psubw128_mask", + "avx512.mask.psub.w.256" => "__builtin_ia32_psubw256_mask", + "avx512.mask.psub.w.512" => "__builtin_ia32_psubw512_mask", + "avx512.mask.psubs.b.128" => "__builtin_ia32_psubsb128_mask", + "avx512.mask.psubs.b.256" => "__builtin_ia32_psubsb256_mask", + "avx512.mask.psubs.b.512" => "__builtin_ia32_psubsb512_mask", + "avx512.mask.psubs.w.128" => "__builtin_ia32_psubsw128_mask", + "avx512.mask.psubs.w.256" => "__builtin_ia32_psubsw256_mask", + "avx512.mask.psubs.w.512" => "__builtin_ia32_psubsw512_mask", + "avx512.mask.psubus.b.128" => "__builtin_ia32_psubusb128_mask", + "avx512.mask.psubus.b.256" => "__builtin_ia32_psubusb256_mask", + "avx512.mask.psubus.b.512" => "__builtin_ia32_psubusb512_mask", + "avx512.mask.psubus.w.128" => "__builtin_ia32_psubusw128_mask", + "avx512.mask.psubus.w.256" => "__builtin_ia32_psubusw256_mask", + "avx512.mask.psubus.w.512" => "__builtin_ia32_psubusw512_mask", + "avx512.mask.pternlog.d.128" => "__builtin_ia32_pternlogd128_mask", + "avx512.mask.pternlog.d.256" => "__builtin_ia32_pternlogd256_mask", + "avx512.mask.pternlog.d.512" => "__builtin_ia32_pternlogd512_mask", + "avx512.mask.pternlog.q.128" => "__builtin_ia32_pternlogq128_mask", + "avx512.mask.pternlog.q.256" => "__builtin_ia32_pternlogq256_mask", + "avx512.mask.pternlog.q.512" => "__builtin_ia32_pternlogq512_mask", + "avx512.mask.ptestm.d.512" => "__builtin_ia32_ptestmd512", + "avx512.mask.ptestm.q.512" => "__builtin_ia32_ptestmq512", + "avx512.mask.shuf.f32x4" => "__builtin_ia32_shuf_f32x4_mask", + "avx512.mask.shuf.f32x4.256" => "__builtin_ia32_shuf_f32x4_256_mask", + "avx512.mask.shuf.f64x2" => "__builtin_ia32_shuf_f64x2_mask", + "avx512.mask.shuf.f64x2.256" => "__builtin_ia32_shuf_f64x2_256_mask", + "avx512.mask.shuf.i32x4" => "__builtin_ia32_shuf_i32x4_mask", + "avx512.mask.shuf.i32x4.256" => "__builtin_ia32_shuf_i32x4_256_mask", + "avx512.mask.shuf.i64x2" => "__builtin_ia32_shuf_i64x2_mask", + "avx512.mask.shuf.i64x2.256" => "__builtin_ia32_shuf_i64x2_256_mask", + "avx512.mask.shuf.pd.128" => "__builtin_ia32_shufpd128_mask", + "avx512.mask.shuf.pd.256" => "__builtin_ia32_shufpd256_mask", + "avx512.mask.shuf.pd.512" => "__builtin_ia32_shufpd512_mask", + "avx512.mask.shuf.ps.128" => "__builtin_ia32_shufps128_mask", + "avx512.mask.shuf.ps.256" => "__builtin_ia32_shufps256_mask", + "avx512.mask.shuf.ps.512" => "__builtin_ia32_shufps512_mask", + "avx512.mask.sqrt.pd.128" => "__builtin_ia32_sqrtpd128_mask", + "avx512.mask.sqrt.pd.256" => "__builtin_ia32_sqrtpd256_mask", + "avx512.mask.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", + "avx512.mask.sqrt.ps.128" => "__builtin_ia32_sqrtps128_mask", + "avx512.mask.sqrt.ps.256" => "__builtin_ia32_sqrtps256_mask", + "avx512.mask.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", + "avx512.mask.store.ss" => "__builtin_ia32_storess_mask", + "avx512.mask.storeu.d.512" => "__builtin_ia32_storedqusi512_mask", + "avx512.mask.storeu.pd.512" => "__builtin_ia32_storeupd512_mask", + "avx512.mask.storeu.ps.512" => "__builtin_ia32_storeups512_mask", + "avx512.mask.storeu.q.512" => "__builtin_ia32_storedqudi512_mask", + "avx512.mask.sub.pd.128" => "__builtin_ia32_subpd128_mask", + "avx512.mask.sub.pd.256" => "__builtin_ia32_subpd256_mask", + "avx512.mask.sub.pd.512" => "__builtin_ia32_subpd512_mask", + "avx512.mask.sub.ps.128" => "__builtin_ia32_subps128_mask", + "avx512.mask.sub.ps.256" => "__builtin_ia32_subps256_mask", + "avx512.mask.sub.ps.512" => "__builtin_ia32_subps512_mask", + "avx512.mask.valign.d.128" => "__builtin_ia32_alignd128_mask", + "avx512.mask.valign.d.256" => "__builtin_ia32_alignd256_mask", + "avx512.mask.valign.d.512" => "__builtin_ia32_alignd512_mask", + "avx512.mask.valign.q.128" => "__builtin_ia32_alignq128_mask", + "avx512.mask.valign.q.256" => "__builtin_ia32_alignq256_mask", + "avx512.mask.valign.q.512" => "__builtin_ia32_alignq512_mask", + "avx512.mask.vcvtph2ps.128" => "__builtin_ia32_vcvtph2ps_mask", + "avx512.mask.vcvtph2ps.256" => "__builtin_ia32_vcvtph2ps256_mask", + "avx512.mask.vcvtph2ps.512" => "__builtin_ia32_vcvtph2ps512_mask", + "avx512.mask.vextractf32x4.256" => "__builtin_ia32_extractf32x4_256_mask", + "avx512.mask.vextractf32x4.512" => "__builtin_ia32_extractf32x4_mask", + "avx512.mask.vextractf32x8.512" => "__builtin_ia32_extractf32x8_mask", + "avx512.mask.vextractf64x2.256" => "__builtin_ia32_extractf64x2_256_mask", + "avx512.mask.vextractf64x2.512" => "__builtin_ia32_extractf64x2_512_mask", + "avx512.mask.vextractf64x4.512" => "__builtin_ia32_extractf64x4_mask", + "avx512.mask.vextracti32x4.256" => "__builtin_ia32_extracti32x4_256_mask", + "avx512.mask.vextracti32x4.512" => "__builtin_ia32_extracti32x4_mask", + "avx512.mask.vextracti32x8.512" => "__builtin_ia32_extracti32x8_mask", + "avx512.mask.vextracti64x2.256" => "__builtin_ia32_extracti64x2_256_mask", + "avx512.mask.vextracti64x2.512" => "__builtin_ia32_extracti64x2_512_mask", + "avx512.mask.vextracti64x4.512" => "__builtin_ia32_extracti64x4_mask", + "avx512.mask.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask", + "avx512.mask.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask", + "avx512.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", + "avx512.mask.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask", + "avx512.mask.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask", + "avx512.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", + "avx512.mask.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask", + "avx512.mask.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask", + "avx512.mask.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask", + "avx512.mask.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask", + "avx512.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", + "avx512.mask.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask", + "avx512.mask.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask", + "avx512.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", + "avx512.mask.vfnmadd.pd.128" => "__builtin_ia32_vfnmaddpd128_mask", + "avx512.mask.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256_mask", + "avx512.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", + "avx512.mask.vfnmadd.ps.128" => "__builtin_ia32_vfnmaddps128_mask", + "avx512.mask.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256_mask", + "avx512.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", + "avx512.mask.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask", + "avx512.mask.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask", + "avx512.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", + "avx512.mask.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask", + "avx512.mask.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask", + "avx512.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", + "avx512.mask.vpermi2var.d.128" => "__builtin_ia32_vpermi2vard128_mask", + "avx512.mask.vpermi2var.d.256" => "__builtin_ia32_vpermi2vard256_mask", + "avx512.mask.vpermi2var.d.512" => "__builtin_ia32_vpermi2vard512_mask", + "avx512.mask.vpermi2var.hi.128" => "__builtin_ia32_vpermi2varhi128_mask", + "avx512.mask.vpermi2var.hi.256" => "__builtin_ia32_vpermi2varhi256_mask", + "avx512.mask.vpermi2var.hi.512" => "__builtin_ia32_vpermi2varhi512_mask", + "avx512.mask.vpermi2var.pd.128" => "__builtin_ia32_vpermi2varpd128_mask", + "avx512.mask.vpermi2var.pd.256" => "__builtin_ia32_vpermi2varpd256_mask", + "avx512.mask.vpermi2var.pd.512" => "__builtin_ia32_vpermi2varpd512_mask", + "avx512.mask.vpermi2var.ps.128" => "__builtin_ia32_vpermi2varps128_mask", + "avx512.mask.vpermi2var.ps.256" => "__builtin_ia32_vpermi2varps256_mask", + "avx512.mask.vpermi2var.ps.512" => "__builtin_ia32_vpermi2varps512_mask", + "avx512.mask.vpermi2var.q.128" => "__builtin_ia32_vpermi2varq128_mask", + "avx512.mask.vpermi2var.q.256" => "__builtin_ia32_vpermi2varq256_mask", + "avx512.mask.vpermi2var.q.512" => "__builtin_ia32_vpermi2varq512_mask", + "avx512.mask.vpermi2var.qi.128" => "__builtin_ia32_vpermi2varqi128_mask", + "avx512.mask.vpermi2var.qi.256" => "__builtin_ia32_vpermi2varqi256_mask", + "avx512.mask.vpermi2var.qi.512" => "__builtin_ia32_vpermi2varqi512_mask", + "avx512.mask.vpermilvar.pd.128" => "__builtin_ia32_vpermilvarpd_mask", + "avx512.mask.vpermilvar.pd.256" => "__builtin_ia32_vpermilvarpd256_mask", + "avx512.mask.vpermilvar.pd.512" => "__builtin_ia32_vpermilvarpd512_mask", + "avx512.mask.vpermilvar.ps.128" => "__builtin_ia32_vpermilvarps_mask", + "avx512.mask.vpermilvar.ps.256" => "__builtin_ia32_vpermilvarps256_mask", + "avx512.mask.vpermilvar.ps.512" => "__builtin_ia32_vpermilvarps512_mask", + "avx512.mask.vpermt.d.512" => "__builtin_ia32_vpermt2vard512_mask", + "avx512.mask.vpermt.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", + "avx512.mask.vpermt.ps.512" => "__builtin_ia32_vpermt2varps512_mask", + "avx512.mask.vpermt.q.512" => "__builtin_ia32_vpermt2varq512_mask", + "avx512.mask.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_mask", + "avx512.mask.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_mask", + "avx512.mask.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_mask", + "avx512.mask.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_mask", + "avx512.mask.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_mask", + "avx512.mask.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_mask", + "avx512.mask.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_mask", + "avx512.mask.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_mask", + "avx512.mask.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_mask", + "avx512.mask.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_mask", + "avx512.mask.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_mask", + "avx512.mask.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_mask", + "avx512.mask.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_mask", + "avx512.mask.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_mask", + "avx512.mask.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_mask", + "avx512.mask.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_mask", + "avx512.mask.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_mask", + "avx512.mask.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_mask", + "avx512.mask.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_mask", + "avx512.mask.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_mask", + "avx512.mask.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_mask", + "avx512.mask.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_mask", + "avx512.mask.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_mask", + "avx512.mask.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_mask", + "avx512.mask.xor.pd.128" => "__builtin_ia32_xorpd128_mask", + "avx512.mask.xor.pd.256" => "__builtin_ia32_xorpd256_mask", + "avx512.mask.xor.pd.512" => "__builtin_ia32_xorpd512_mask", + "avx512.mask.xor.ps.128" => "__builtin_ia32_xorps128_mask", + "avx512.mask.xor.ps.256" => "__builtin_ia32_xorps256_mask", + "avx512.mask.xor.ps.512" => "__builtin_ia32_xorps512_mask", + "avx512.mask3.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_mask3", + "avx512.mask3.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_mask3", + "avx512.mask3.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask3", + "avx512.mask3.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_mask3", + "avx512.mask3.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_mask3", + "avx512.mask3.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask3", + "avx512.mask3.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_mask3", + "avx512.mask3.vfmadd.ss" => "__builtin_ia32_vfmaddss3_mask3", + "avx512.mask3.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_mask3", + "avx512.mask3.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_mask3", + "avx512.mask3.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask3", + "avx512.mask3.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_mask3", + "avx512.mask3.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_mask3", + "avx512.mask3.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask3", + "avx512.mask3.vfmsub.pd.128" => "__builtin_ia32_vfmsubpd128_mask3", + "avx512.mask3.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256_mask3", + "avx512.mask3.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask3", + "avx512.mask3.vfmsub.ps.128" => "__builtin_ia32_vfmsubps128_mask3", + "avx512.mask3.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256_mask3", + "avx512.mask3.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask3", + "avx512.mask3.vfmsubadd.pd.128" => "__builtin_ia32_vfmsubaddpd128_mask3", + "avx512.mask3.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256_mask3", + "avx512.mask3.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask3", + "avx512.mask3.vfmsubadd.ps.128" => "__builtin_ia32_vfmsubaddps128_mask3", + "avx512.mask3.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256_mask3", + "avx512.mask3.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask3", + "avx512.mask3.vfnmsub.pd.128" => "__builtin_ia32_vfnmsubpd128_mask3", + "avx512.mask3.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256_mask3", + "avx512.mask3.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask3", + "avx512.mask3.vfnmsub.ps.128" => "__builtin_ia32_vfnmsubps128_mask3", + "avx512.mask3.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256_mask3", + "avx512.mask3.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask3", + "avx512.maskz.pternlog.d.128" => "__builtin_ia32_pternlogd128_maskz", + "avx512.maskz.pternlog.d.256" => "__builtin_ia32_pternlogd256_maskz", + "avx512.maskz.pternlog.d.512" => "__builtin_ia32_pternlogd512_maskz", + "avx512.maskz.pternlog.q.128" => "__builtin_ia32_pternlogq128_maskz", + "avx512.maskz.pternlog.q.256" => "__builtin_ia32_pternlogq256_maskz", + "avx512.maskz.pternlog.q.512" => "__builtin_ia32_pternlogq512_maskz", + "avx512.maskz.vfmadd.pd.128" => "__builtin_ia32_vfmaddpd128_maskz", + "avx512.maskz.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256_maskz", + "avx512.maskz.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_maskz", + "avx512.maskz.vfmadd.ps.128" => "__builtin_ia32_vfmaddps128_maskz", + "avx512.maskz.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256_maskz", + "avx512.maskz.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_maskz", + "avx512.maskz.vfmadd.sd" => "__builtin_ia32_vfmaddsd3_maskz", + "avx512.maskz.vfmadd.ss" => "__builtin_ia32_vfmaddss3_maskz", + "avx512.maskz.vfmaddsub.pd.128" => "__builtin_ia32_vfmaddsubpd128_maskz", + "avx512.maskz.vfmaddsub.pd.256" => "__builtin_ia32_vfmaddsubpd256_maskz", + "avx512.maskz.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_maskz", + "avx512.maskz.vfmaddsub.ps.128" => "__builtin_ia32_vfmaddsubps128_maskz", + "avx512.maskz.vfmaddsub.ps.256" => "__builtin_ia32_vfmaddsubps256_maskz", + "avx512.maskz.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_maskz", + "avx512.maskz.vpermt2var.d.128" => "__builtin_ia32_vpermt2vard128_maskz", + "avx512.maskz.vpermt2var.d.256" => "__builtin_ia32_vpermt2vard256_maskz", + "avx512.maskz.vpermt2var.d.512" => "__builtin_ia32_vpermt2vard512_maskz", + "avx512.maskz.vpermt2var.hi.128" => "__builtin_ia32_vpermt2varhi128_maskz", + "avx512.maskz.vpermt2var.hi.256" => "__builtin_ia32_vpermt2varhi256_maskz", + "avx512.maskz.vpermt2var.hi.512" => "__builtin_ia32_vpermt2varhi512_maskz", + "avx512.maskz.vpermt2var.pd.128" => "__builtin_ia32_vpermt2varpd128_maskz", + "avx512.maskz.vpermt2var.pd.256" => "__builtin_ia32_vpermt2varpd256_maskz", + "avx512.maskz.vpermt2var.pd.512" => "__builtin_ia32_vpermt2varpd512_maskz", + "avx512.maskz.vpermt2var.ps.128" => "__builtin_ia32_vpermt2varps128_maskz", + "avx512.maskz.vpermt2var.ps.256" => "__builtin_ia32_vpermt2varps256_maskz", + "avx512.maskz.vpermt2var.ps.512" => "__builtin_ia32_vpermt2varps512_maskz", + "avx512.maskz.vpermt2var.q.128" => "__builtin_ia32_vpermt2varq128_maskz", + "avx512.maskz.vpermt2var.q.256" => "__builtin_ia32_vpermt2varq256_maskz", + "avx512.maskz.vpermt2var.q.512" => "__builtin_ia32_vpermt2varq512_maskz", + "avx512.maskz.vpermt2var.qi.128" => "__builtin_ia32_vpermt2varqi128_maskz", + "avx512.maskz.vpermt2var.qi.256" => "__builtin_ia32_vpermt2varqi256_maskz", + "avx512.maskz.vpermt2var.qi.512" => "__builtin_ia32_vpermt2varqi512_maskz", + "avx512.maskz.vpmadd52h.uq.128" => "__builtin_ia32_vpmadd52huq128_maskz", + "avx512.maskz.vpmadd52h.uq.256" => "__builtin_ia32_vpmadd52huq256_maskz", + "avx512.maskz.vpmadd52h.uq.512" => "__builtin_ia32_vpmadd52huq512_maskz", + "avx512.maskz.vpmadd52l.uq.128" => "__builtin_ia32_vpmadd52luq128_maskz", + "avx512.maskz.vpmadd52l.uq.256" => "__builtin_ia32_vpmadd52luq256_maskz", + "avx512.maskz.vpmadd52l.uq.512" => "__builtin_ia32_vpmadd52luq512_maskz", + "avx512.movntdqa" => "__builtin_ia32_movntdqa512", + "avx512.pbroadcastd.512" => "__builtin_ia32_pbroadcastd512", + "avx512.pbroadcastq.512" => "__builtin_ia32_pbroadcastq512", + "avx512.pmovzxbd" => "__builtin_ia32_pmovzxbd512", + "avx512.pmovzxbq" => "__builtin_ia32_pmovzxbq512", + "avx512.pmovzxdq" => "__builtin_ia32_pmovzxdq512", + "avx512.pmovzxwd" => "__builtin_ia32_pmovzxwd512", + "avx512.pmovzxwq" => "__builtin_ia32_pmovzxwq512", + "avx512.psll.dq" => "__builtin_ia32_pslldqi512", + "avx512.psll.dq.bs" => "__builtin_ia32_pslldqi512_byteshift", + "avx512.psrl.dq" => "__builtin_ia32_psrldqi512", + "avx512.psrl.dq.bs" => "__builtin_ia32_psrldqi512_byteshift", + "avx512.ptestm.b.128" => "__builtin_ia32_ptestmb128", + "avx512.ptestm.b.256" => "__builtin_ia32_ptestmb256", + "avx512.ptestm.b.512" => "__builtin_ia32_ptestmb512", + "avx512.ptestm.d.128" => "__builtin_ia32_ptestmd128", + "avx512.ptestm.d.256" => "__builtin_ia32_ptestmd256", + "avx512.ptestm.d.512" => "__builtin_ia32_ptestmd512", + "avx512.ptestm.q.128" => "__builtin_ia32_ptestmq128", + "avx512.ptestm.q.256" => "__builtin_ia32_ptestmq256", + "avx512.ptestm.q.512" => "__builtin_ia32_ptestmq512", + "avx512.ptestm.w.128" => "__builtin_ia32_ptestmw128", + "avx512.ptestm.w.256" => "__builtin_ia32_ptestmw256", + "avx512.ptestm.w.512" => "__builtin_ia32_ptestmw512", + "avx512.ptestnm.b.128" => "__builtin_ia32_ptestnmb128", + "avx512.ptestnm.b.256" => "__builtin_ia32_ptestnmb256", + "avx512.ptestnm.b.512" => "__builtin_ia32_ptestnmb512", + "avx512.ptestnm.d.128" => "__builtin_ia32_ptestnmd128", + "avx512.ptestnm.d.256" => "__builtin_ia32_ptestnmd256", + "avx512.ptestnm.d.512" => "__builtin_ia32_ptestnmd512", + "avx512.ptestnm.q.128" => "__builtin_ia32_ptestnmq128", + "avx512.ptestnm.q.256" => "__builtin_ia32_ptestnmq256", + "avx512.ptestnm.q.512" => "__builtin_ia32_ptestnmq512", + "avx512.ptestnm.w.128" => "__builtin_ia32_ptestnmw128", + "avx512.ptestnm.w.256" => "__builtin_ia32_ptestnmw256", + "avx512.ptestnm.w.512" => "__builtin_ia32_ptestnmw512", + "avx512.rcp28.pd" => "__builtin_ia32_rcp28pd_mask", + "avx512.rcp28.ps" => "__builtin_ia32_rcp28ps_mask", + "avx512.rcp28.sd" => "__builtin_ia32_rcp28sd_mask", + "avx512.rcp28.ss" => "__builtin_ia32_rcp28ss_mask", + "avx512.rndscale.sd" => "__builtin_ia32_rndscalesd", + "avx512.rndscale.ss" => "__builtin_ia32_rndscaless", + "avx512.rsqrt28.pd" => "__builtin_ia32_rsqrt28pd_mask", + "avx512.rsqrt28.ps" => "__builtin_ia32_rsqrt28ps_mask", + "avx512.rsqrt28.sd" => "__builtin_ia32_rsqrt28sd_mask", + "avx512.rsqrt28.ss" => "__builtin_ia32_rsqrt28ss_mask", + "avx512.scatter.dpd.512" => "__builtin_ia32_scattersiv8df", + "avx512.scatter.dpi.512" => "__builtin_ia32_scattersiv16si", + "avx512.scatter.dpq.512" => "__builtin_ia32_scattersiv8di", + "avx512.scatter.dps.512" => "__builtin_ia32_scattersiv16sf", + "avx512.scatter.qpd.512" => "__builtin_ia32_scatterdiv8df", + "avx512.scatter.qpi.512" => "__builtin_ia32_scatterdiv16si", + "avx512.scatter.qpq.512" => "__builtin_ia32_scatterdiv8di", + "avx512.scatter.qps.512" => "__builtin_ia32_scatterdiv16sf", + "avx512.scatterdiv2.df" => "__builtin_ia32_scatterdiv2df", + "avx512.scatterdiv2.di" => "__builtin_ia32_scatterdiv2di", + "avx512.scatterdiv4.df" => "__builtin_ia32_scatterdiv4df", + "avx512.scatterdiv4.di" => "__builtin_ia32_scatterdiv4di", + "avx512.scatterdiv4.sf" => "__builtin_ia32_scatterdiv4sf", + "avx512.scatterdiv4.si" => "__builtin_ia32_scatterdiv4si", + "avx512.scatterdiv8.sf" => "__builtin_ia32_scatterdiv8sf", + "avx512.scatterdiv8.si" => "__builtin_ia32_scatterdiv8si", + "avx512.scatterpf.dpd.512" => "__builtin_ia32_scatterpfdpd", + "avx512.scatterpf.dps.512" => "__builtin_ia32_scatterpfdps", + "avx512.scatterpf.qpd.512" => "__builtin_ia32_scatterpfqpd", + "avx512.scatterpf.qps.512" => "__builtin_ia32_scatterpfqps", + "avx512.scattersiv2.df" => "__builtin_ia32_scattersiv2df", + "avx512.scattersiv2.di" => "__builtin_ia32_scattersiv2di", + "avx512.scattersiv4.df" => "__builtin_ia32_scattersiv4df", + "avx512.scattersiv4.di" => "__builtin_ia32_scattersiv4di", + "avx512.scattersiv4.sf" => "__builtin_ia32_scattersiv4sf", + "avx512.scattersiv4.si" => "__builtin_ia32_scattersiv4si", + "avx512.scattersiv8.sf" => "__builtin_ia32_scattersiv8sf", + "avx512.scattersiv8.si" => "__builtin_ia32_scattersiv8si", + "avx512.sqrt.pd.512" => "__builtin_ia32_sqrtpd512_mask", + "avx512.sqrt.ps.512" => "__builtin_ia32_sqrtps512_mask", + "avx512.sqrt.sd" => "__builtin_ia32_sqrtrndsd", + "avx512.sqrt.ss" => "__builtin_ia32_sqrtrndss", + "avx512.vbroadcast.sd.512" => "__builtin_ia32_vbroadcastsd512", + "avx512.vbroadcast.sd.pd.512" => "__builtin_ia32_vbroadcastsd_pd512", + "avx512.vbroadcast.ss.512" => "__builtin_ia32_vbroadcastss512", + "avx512.vbroadcast.ss.ps.512" => "__builtin_ia32_vbroadcastss_ps512", + "fma.mask.vfmadd.pd.512" => "__builtin_ia32_vfmaddpd512_mask", + "fma.mask.vfmadd.ps.512" => "__builtin_ia32_vfmaddps512_mask", + "fma.mask.vfmaddsub.pd.512" => "__builtin_ia32_vfmaddsubpd512_mask", + "fma.mask.vfmaddsub.ps.512" => "__builtin_ia32_vfmaddsubps512_mask", + "fma.mask.vfmsub.pd.512" => "__builtin_ia32_vfmsubpd512_mask", + "fma.mask.vfmsub.ps.512" => "__builtin_ia32_vfmsubps512_mask", + "fma.mask.vfmsubadd.pd.512" => "__builtin_ia32_vfmsubaddpd512_mask", + "fma.mask.vfmsubadd.ps.512" => "__builtin_ia32_vfmsubaddps512_mask", + "fma.mask.vfnmadd.pd.512" => "__builtin_ia32_vfnmaddpd512_mask", + "fma.mask.vfnmadd.ps.512" => "__builtin_ia32_vfnmaddps512_mask", + "fma.mask.vfnmsub.pd.512" => "__builtin_ia32_vfnmsubpd512_mask", + "fma.mask.vfnmsub.ps.512" => "__builtin_ia32_vfnmsubps512_mask", + "fma.vfmadd.pd" => "__builtin_ia32_vfmaddpd", + "fma.vfmadd.pd.256" => "__builtin_ia32_vfmaddpd256", + "fma.vfmadd.ps" => "__builtin_ia32_vfmaddps", + "fma.vfmadd.ps.256" => "__builtin_ia32_vfmaddps256", + "fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd", + "fma.vfmadd.ss" => "__builtin_ia32_vfmaddss", + "fma.vfmsub.pd" => "__builtin_ia32_vfmsubpd", + "fma.vfmsub.pd.256" => "__builtin_ia32_vfmsubpd256", + "fma.vfmsub.ps" => "__builtin_ia32_vfmsubps", + "fma.vfmsub.ps.256" => "__builtin_ia32_vfmsubps256", + "fma.vfmsub.sd" => "__builtin_ia32_vfmsubsd", + "fma.vfmsub.ss" => "__builtin_ia32_vfmsubss", + "fma.vfmsubadd.pd" => "__builtin_ia32_vfmsubaddpd", + "fma.vfmsubadd.pd.256" => "__builtin_ia32_vfmsubaddpd256", + "fma.vfmsubadd.ps" => "__builtin_ia32_vfmsubaddps", + "fma.vfmsubadd.ps.256" => "__builtin_ia32_vfmsubaddps256", + "fma.vfnmadd.pd" => "__builtin_ia32_vfnmaddpd", + "fma.vfnmadd.pd.256" => "__builtin_ia32_vfnmaddpd256", + "fma.vfnmadd.ps" => "__builtin_ia32_vfnmaddps", + "fma.vfnmadd.ps.256" => "__builtin_ia32_vfnmaddps256", + "fma.vfnmadd.sd" => "__builtin_ia32_vfnmaddsd", + "fma.vfnmadd.ss" => "__builtin_ia32_vfnmaddss", + "fma.vfnmsub.pd" => "__builtin_ia32_vfnmsubpd", + "fma.vfnmsub.pd.256" => "__builtin_ia32_vfnmsubpd256", + "fma.vfnmsub.ps" => "__builtin_ia32_vfnmsubps", + "fma.vfnmsub.ps.256" => "__builtin_ia32_vfnmsubps256", + "fma.vfnmsub.sd" => "__builtin_ia32_vfnmsubsd", + "fma.vfnmsub.ss" => "__builtin_ia32_vfnmsubss", + "mmx.femms" => "__builtin_ia32_femms", + "rdtscp" => "__builtin_ia32_rdtscp", + "sse.add.ss" => "__builtin_ia32_addss", + "sse.cmp.ps" => "__builtin_ia32_cmpps", + "sse.cvtsi2ss" => "__builtin_ia32_cvtsi2ss", + "sse.cvtsi642ss" => "__builtin_ia32_cvtsi642ss", + "sse.div.ss" => "__builtin_ia32_divss", + "sse.mul.ss" => "__builtin_ia32_mulss", + "sse.sqrt.ps" => "__builtin_ia32_sqrtps", + "sse.sqrt.ss" => "__builtin_ia32_sqrtss", + "sse.storeu.ps" => "__builtin_ia32_storeups", + "sse.sub.ss" => "__builtin_ia32_subss", + "sse2.add.sd" => "__builtin_ia32_addsd", + "sse2.cmp.pd" => "__builtin_ia32_cmppd", + "sse2.cvtdq2pd" => "__builtin_ia32_cvtdq2pd", + "sse2.cvtdq2ps" => "__builtin_ia32_cvtdq2ps", + "sse2.cvtps2pd" => "__builtin_ia32_cvtps2pd", + "sse2.cvtsi2sd" => "__builtin_ia32_cvtsi2sd", + "sse2.cvtsi642sd" => "__builtin_ia32_cvtsi642sd", + "sse2.cvtss2sd" => "__builtin_ia32_cvtss2sd", + "sse2.div.sd" => "__builtin_ia32_divsd", + "sse2.mul.sd" => "__builtin_ia32_mulsd", + "sse2.padds.b" => "__builtin_ia32_paddsb128", + "sse2.padds.w" => "__builtin_ia32_paddsw128", + "sse2.paddus.b" => "__builtin_ia32_paddusb128", + "sse2.paddus.w" => "__builtin_ia32_paddusw128", + "sse2.pmaxs.w" => "__builtin_ia32_pmaxsw128", + "sse2.pmaxu.b" => "__builtin_ia32_pmaxub128", + "sse2.pmins.w" => "__builtin_ia32_pminsw128", + "sse2.pminu.b" => "__builtin_ia32_pminub128", + "sse2.pmulu.dq" => "__builtin_ia32_pmuludq128", + "sse2.pshuf.d" => "__builtin_ia32_pshufd", + "sse2.pshufh.w" => "__builtin_ia32_pshufhw", + "sse2.pshufl.w" => "__builtin_ia32_pshuflw", + "sse2.psll.dq" => "__builtin_ia32_pslldqi128", + "sse2.psll.dq.bs" => "__builtin_ia32_pslldqi128_byteshift", + "sse2.psrl.dq" => "__builtin_ia32_psrldqi128", + "sse2.psrl.dq.bs" => "__builtin_ia32_psrldqi128_byteshift", + "sse2.psubs.b" => "__builtin_ia32_psubsb128", + "sse2.psubs.w" => "__builtin_ia32_psubsw128", + "sse2.psubus.b" => "__builtin_ia32_psubusb128", + "sse2.psubus.w" => "__builtin_ia32_psubusw128", + "sse2.sqrt.pd" => "__builtin_ia32_sqrtpd", + "sse2.sqrt.sd" => "__builtin_ia32_sqrtsd", + "sse2.storel.dq" => "__builtin_ia32_storelv4si", + "sse2.storeu.dq" => "__builtin_ia32_storedqu", + "sse2.storeu.pd" => "__builtin_ia32_storeupd", + "sse2.sub.sd" => "__builtin_ia32_subsd", + "sse41.blendpd" => "__builtin_ia32_blendpd", + "sse41.blendps" => "__builtin_ia32_blendps", + "sse41.extractps" => "__builtin_ia32_extractps128", + "sse41.movntdqa" => "__builtin_ia32_movntdqa", + "sse41.pblendw" => "__builtin_ia32_pblendw128", + "sse41.pmaxsb" => "__builtin_ia32_pmaxsb128", + "sse41.pmaxsd" => "__builtin_ia32_pmaxsd128", + "sse41.pmaxud" => "__builtin_ia32_pmaxud128", + "sse41.pmaxuw" => "__builtin_ia32_pmaxuw128", + "sse41.pminsb" => "__builtin_ia32_pminsb128", + "sse41.pminsd" => "__builtin_ia32_pminsd128", + "sse41.pminud" => "__builtin_ia32_pminud128", + "sse41.pminuw" => "__builtin_ia32_pminuw128", + "sse41.pmovsxbd" => "__builtin_ia32_pmovsxbd128", + "sse41.pmovsxbq" => "__builtin_ia32_pmovsxbq128", + "sse41.pmovsxbw" => "__builtin_ia32_pmovsxbw128", + "sse41.pmovsxdq" => "__builtin_ia32_pmovsxdq128", + "sse41.pmovsxwd" => "__builtin_ia32_pmovsxwd128", + "sse41.pmovsxwq" => "__builtin_ia32_pmovsxwq128", + "sse41.pmovzxbd" => "__builtin_ia32_pmovzxbd128", + "sse41.pmovzxbq" => "__builtin_ia32_pmovzxbq128", + "sse41.pmovzxbw" => "__builtin_ia32_pmovzxbw128", + "sse41.pmovzxdq" => "__builtin_ia32_pmovzxdq128", + "sse41.pmovzxwd" => "__builtin_ia32_pmovzxwd128", + "sse41.pmovzxwq" => "__builtin_ia32_pmovzxwq128", + "sse41.pmuldq" => "__builtin_ia32_pmuldq128", + "sse41.round.pd" => "__builtin_ia32_roundpd", + "sse41.round.ps" => "__builtin_ia32_roundps", + "sse41.round.sd" => "__builtin_ia32_roundsd", + "sse41.round.ss" => "__builtin_ia32_roundss", + "sse4a.movnt.sd" => "__builtin_ia32_movntsd", + "sse4a.movnt.ss" => "__builtin_ia32_movntss", + "ssse3.pabs.b.128" => "__builtin_ia32_pabsb128", + "ssse3.pabs.d.128" => "__builtin_ia32_pabsd128", + "ssse3.pabs.w.128" => "__builtin_ia32_pabsw128", + "subborrow.u32" => "__builtin_ia32_subborrow_u32", + "subborrow.u64" => "__builtin_ia32_subborrow_u64", + "xop.vpcmov" => "__builtin_ia32_vpcmov", + "xop.vpcmov.256" => "__builtin_ia32_vpcmov_256", + "xop.vpcomb" => "__builtin_ia32_vpcomb", + "xop.vpcomd" => "__builtin_ia32_vpcomd", + "xop.vpcomq" => "__builtin_ia32_vpcomq", + "xop.vpcomub" => "__builtin_ia32_vpcomub", + "xop.vpcomud" => "__builtin_ia32_vpcomud", + "xop.vpcomuq" => "__builtin_ia32_vpcomuq", + "xop.vpcomuw" => "__builtin_ia32_vpcomuw", + "xop.vpcomw" => "__builtin_ia32_vpcomw", + "xop.vprotb" => "__builtin_ia32_vprotb", + "xop.vprotbi" => "__builtin_ia32_vprotbi", + "xop.vprotd" => "__builtin_ia32_vprotd", + "xop.vprotdi" => "__builtin_ia32_vprotdi", + "xop.vprotq" => "__builtin_ia32_vprotq", + "xop.vprotqi" => "__builtin_ia32_vprotqi", + "xop.vprotw" => "__builtin_ia32_vprotw", + "xop.vprotwi" => "__builtin_ia32_vprotwi", + _ => return ArchCheckResult::UnknownIntrinsic, + }, + _ => return ArchCheckResult::UnknownArch, + }) +} diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index c7ed887b30d0..eab067a02b7b 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -121,6 +121,42 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Ok(bx.vector_select(vector_mask, arg1, args[2].immediate())); } + #[cfg(feature = "master")] + if name == sym::simd_splat { + let (out_len, out_ty) = require_simd2!(ret_ty, SimdReturn); + + require!( + args[0].layout.ty == out_ty, + InvalidMonomorphization::ExpectedVectorElementType { + span, + name, + expected_element: out_ty, + vector_type: ret_ty, + } + ); + + let vec_ty = llret_ty.unqualified().dyncast_vector().expect("vector return type"); + let elem_ty = vec_ty.get_element_type(); + + // Cast pointer type to usize (GCC does not support pointer SIMD vectors). + let value = args[0]; + let scalar = if value.layout.ty.is_numeric() { + value.immediate() + } else if value.layout.ty.is_raw_ptr() { + bx.ptrtoint(value.immediate(), elem_ty) + } else { + return_error!(InvalidMonomorphization::UnsupportedOperation { + span, + name, + in_ty: ret_ty, + in_elem: value.layout.ty + }); + }; + + let elements = vec![scalar; out_len as usize]; + return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &elements)); + } + // every intrinsic below takes a SIMD vector as its first argument require_simd!( args[0].layout.ty, @@ -774,24 +810,23 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>( return Err(()); }}; } - let (elem_ty_str, elem_ty, cast_type) = if let ty::Float(ref f) = *in_elem.kind() { - let elem_ty = bx.cx.type_float_from_ty(*f); - match f.bit_width() { - 16 => ("", elem_ty, Some(bx.cx.double_type)), - 32 => ("f", elem_ty, None), - 64 => ("", elem_ty, None), - _ => { - return_error!(InvalidMonomorphization::FloatingPointVector { - span, - name, - f_ty: *f, - in_ty - }); - } - } - } else { + let ty::Float(ref f) = *in_elem.kind() else { return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); }; + let elem_ty = bx.cx.type_float_from_ty(*f); + let (elem_ty_str, elem_ty, cast_type) = match f.bit_width() { + 16 => ("", elem_ty, Some(bx.cx.double_type)), + 32 => ("f", elem_ty, None), + 64 => ("", elem_ty, None), + _ => { + return_error!(InvalidMonomorphization::FloatingPointVector { + span, + name, + f_ty: *f, + in_ty + }); + } + }; let vec_ty = bx.cx.type_vector(elem_ty, in_len); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index c1506ee6176f..5d03d2406870 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -27,7 +27,6 @@ extern crate rustc_ast; extern crate rustc_codegen_ssa; extern crate rustc_data_structures; extern crate rustc_errors; -extern crate rustc_fluent_macro; extern crate rustc_fs_util; extern crate rustc_hir; extern crate rustc_index; @@ -77,20 +76,22 @@ use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; -use back::lto::{ThinBuffer, ThinData}; use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ - CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, + CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; -use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; +use rustc_codegen_ssa::traits::{ + CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods, +}; use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_errors::DiagCtxtHandle; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -105,8 +106,6 @@ use tempfile::TempDir; use crate::back::lto::ModuleBuffer; use crate::gcc_util::{target_cpu, to_gcc_features}; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub struct PrintOnPanic String>(pub F); impl String> Drop for PrintOnPanic { @@ -179,20 +178,12 @@ pub struct GccCodegenBackend { lto_supported: Arc, } -static LTO_SUPPORTED: AtomicBool = AtomicBool::new(false); - -fn libgccjit_path(sysroot_path: &Path) -> PathBuf { - let sysroot_lib_dir = sysroot_path.join("lib"); - sysroot_lib_dir.join("libgccjit.so") -} - -fn load_libgccjit_if_needed(sysroot_path: &Path) { +fn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) { if gccjit::is_loaded() { // Do not load a libgccjit second time. return; } - let libgccjit_target_lib_file = libgccjit_path(sysroot_path); let path = libgccjit_target_lib_file.to_str().expect("libgccjit path"); let string = CString::new(path).expect("string to libgccjit path"); @@ -203,28 +194,47 @@ fn load_libgccjit_if_needed(sysroot_path: &Path) { } impl CodegenBackend for GccCodegenBackend { - fn locale_resource(&self) -> &'static str { - crate::DEFAULT_LOCALE_RESOURCE - } - fn name(&self) -> &'static str { "gcc" } fn init(&self, sess: &Session) { + fn file_path(sysroot_path: &Path, sess: &Session) -> PathBuf { + let rustlib_path = + rustc_target::relative_target_rustlib_path(sysroot_path, &sess.host.llvm_target); + sysroot_path + .join(rustlib_path) + .join("codegen-backends") + .join("lib") + .join(sess.target.llvm_target.as_ref()) + .join("libgccjit.so") + } + // We use all_paths() instead of only path() in case the path specified by --sysroot is // invalid. // This is the case for instance in Rust for Linux where they specify --sysroot=/dev/null. for path in sess.opts.sysroot.all_paths() { - let libgccjit_target_lib_file = libgccjit_path(path); - if let Ok(true) = fs::exists(libgccjit_target_lib_file) { - load_libgccjit_if_needed(path); + let libgccjit_target_lib_file = file_path(path, sess); + if let Ok(true) = fs::exists(&libgccjit_target_lib_file) { + load_libgccjit_if_needed(&libgccjit_target_lib_file); break; } } + if !gccjit::is_loaded() { + let mut paths = vec![]; + for path in sess.opts.sysroot.all_paths() { + let libgccjit_target_lib_file = file_path(path, sess); + paths.push(libgccjit_target_lib_file); + } + + panic!("Could not load libgccjit.so. Attempted paths: {:#?}", paths); + } + #[cfg(feature = "master")] { + gccjit::set_lang_name(c"GNU Rust"); + let target_cpu = target_cpu(sess); // Get the second TargetInfo with the correct CPU features by setting the arch. @@ -240,7 +250,6 @@ impl CodegenBackend for GccCodegenBackend { #[cfg(feature = "master")] { let lto_supported = gccjit::is_lto_supported(); - LTO_SUPPORTED.store(lto_supported, Ordering::SeqCst); self.lto_supported.store(lto_supported, Ordering::SeqCst); gccjit::set_global_personality_function_name(b"rust_eh_personality\0"); @@ -270,8 +279,13 @@ impl CodegenBackend for GccCodegenBackend { } } + fn thin_lto_supported(&self) -> bool { + false + } + fn provide(&self, providers: &mut Providers) { - providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess) + providers.queries.global_backend_features = + |tcx, ()| gcc_util::global_gcc_features(tcx.sess) } fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { @@ -365,7 +379,7 @@ impl ExtraBackendMethods for GccCodegenBackend { _features: &[String], ) -> TargetMachineFactoryFn { // TODO(antoyo): set opt level. - Arc::new(|_| Ok(())) + Arc::new(|_, _| ()) } } @@ -409,33 +423,45 @@ unsafe impl Send for SyncContext {} // FIXME(antoyo): that shouldn't be Sync. Parallel compilation is currently disabled with "CodegenBackend::supports_parallel()". unsafe impl Sync for SyncContext {} +pub struct ThinBuffer; + +impl ThinBufferMethods for ThinBuffer { + fn data(&self) -> &[u8] { + &[] + } +} + impl WriteBackendMethods for GccCodegenBackend { type Module = GccContext; type TargetMachine = (); - type TargetMachineError = (); type ModuleBuffer = ModuleBuffer; - type ThinData = ThinData; + type ThinData = (); type ThinBuffer = ThinBuffer; fn run_and_optimize_fat_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, + _tm_factory: TargetMachineFactoryFn, // FIXME(bjorn3): Limit LTO exports to these symbols _exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - back::lto::run_fat(cgcx, each_linked_rlib_for_lto, modules) + back::lto::run_fat(cgcx, prof, shared_emitter, each_linked_rlib_for_lto, modules) } fn run_thin_lto( - cgcx: &CodegenContext, + _cgcx: &CodegenContext, + _prof: &SelfProfilerRef, + _dcx: DiagCtxtHandle<'_>, // FIXME(bjorn3): Limit LTO exports to these symbols _exported_symbols_for_lto: &[String], - each_linked_rlib_for_lto: &[PathBuf], - modules: Vec<(String, Self::ThinBuffer)>, - cached_modules: Vec<(SerializedModule, WorkProduct)>, + _each_linked_rlib_for_lto: &[PathBuf], + _modules: Vec<(String, Self::ThinBuffer)>, + _cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> (Vec>, Vec) { - back::lto::run_thin(cgcx, each_linked_rlib_for_lto, modules, cached_modules) + unreachable!() } fn print_pass_timings(&self) { @@ -447,8 +473,9 @@ impl WriteBackendMethods for GccCodegenBackend { } fn optimize( - _cgcx: &CodegenContext, - _dcx: DiagCtxtHandle<'_>, + _cgcx: &CodegenContext, + _prof: &SelfProfilerRef, + _shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ) { @@ -456,22 +483,27 @@ impl WriteBackendMethods for GccCodegenBackend { } fn optimize_thin( - cgcx: &CodegenContext, - thin: ThinModule, + _cgcx: &CodegenContext, + _prof: &SelfProfilerRef, + _shared_emitter: &SharedEmitter, + _tm_factory: TargetMachineFactoryFn, + _thin: ThinModule, ) -> ModuleCodegen { - back::lto::optimize_thin_module(thin, cgcx) + unreachable!() } fn codegen( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - back::write::codegen(cgcx, module, config) + back::write::codegen(cgcx, prof, shared_emitter, module, config) } - fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer) { - back::lto::prepare_thin(module) + fn prepare_thin(_module: ModuleCodegen) -> (String, Self::ThinBuffer) { + unreachable!() } fn serialize_module(_module: ModuleCodegen) -> (String, Self::ModuleBuffer) { diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs index d356b6af260a..3b1ee53f8336 100644 --- a/compiler/rustc_codegen_gcc/src/type_.rs +++ b/compiler/rustc_codegen_gcc/src/type_.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::{bug, ty}; use crate::common::TypeReflection; -use crate::context::CodegenCx; +use crate::context::{CodegenCx, new_array_type}; use crate::type_of::LayoutGccExt; impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { @@ -311,7 +311,7 @@ impl<'gcc, 'tcx> BaseTypeCodegenMethods for CodegenCx<'gcc, 'tcx> { len = 0; } - self.context.new_array_type(None, ty, len) + new_array_type(self.context, None, ty, len) } } diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 93202483eed8..68fca5a17ad3 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -85,6 +85,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( ); } BackendRepr::Memory { .. } => {} + BackendRepr::ScalableVector { .. } => todo!(), } let name = match *layout.ty.kind() { @@ -179,6 +180,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { fn is_gcc_immediate(&self) -> bool { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, + // FIXME(rustc_scalable_vector): Not yet implemented in rustc_codegen_gcc. + BackendRepr::ScalableVector { .. } => todo!(), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -188,6 +191,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { BackendRepr::ScalarPair(..) => true, BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt index 822aaec0edeb..528ee1df9f58 100644 --- a/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt +++ b/compiler/rustc_codegen_gcc/tests/failing-run-make-tests.txt @@ -11,4 +11,4 @@ tests/run-make/foreign-exceptions/ tests/run-make/glibc-staticlib-args/ tests/run-make/lto-smoke-c/ tests/run-make/return-non-c-like-enum/ - +tests/run-make/short-ice diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests-without-128bit-integers.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests-without-128bit-integers.txt new file mode 100644 index 000000000000..1dc3859b335e --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests-without-128bit-integers.txt @@ -0,0 +1 @@ +tests/ui/simd/intrinsic/splat.rs diff --git a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt index 2380bd0fc137..8589929d2fbc 100644 --- a/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt +++ b/compiler/rustc_codegen_gcc/tests/failing-ui-tests.txt @@ -88,3 +88,14 @@ tests/ui/test-attrs/test-panic-while-printing.rs tests/ui/thir-print/offset_of.rs tests/ui/iterators/rangefrom-overflow-debug.rs tests/ui/iterators/rangefrom-overflow-overflow-checks.rs +tests/ui/iterators/iter-filter-count-debug-check.rs +tests/ui/eii/linking/codegen_single_crate.rs +tests/ui/eii/linking/codegen_cross_crate.rs +tests/ui/eii/default/local_crate.rs +tests/ui/eii/duplicate/multiple_impls.rs +tests/ui/eii/default/call_default.rs +tests/ui/eii/linking/same-symbol.rs +tests/ui/eii/privacy1.rs +tests/ui/eii/default/call_impl.rs +tests/ui/c-variadic/copy.rs +tests/ui/asm/x86_64/global_asm_escape.rs diff --git a/compiler/rustc_codegen_gcc/tests/run/call-llvm-intrinsics.rs b/compiler/rustc_codegen_gcc/tests/run/call-llvm-intrinsics.rs new file mode 100644 index 000000000000..86e041c3a2fb --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/call-llvm-intrinsics.rs @@ -0,0 +1,38 @@ +// Compiler: +// +// Run-time: +// status: 0 + +// FIXME: Remove this test once rustc's `./tests/codegen/riscv-abi/call-llvm-intrinsics.rs` +// stops ignoring GCC backend. + +#![feature(link_llvm_intrinsics)] +#![allow(internal_features)] + +struct A; + +impl Drop for A { + fn drop(&mut self) { + println!("A"); + } +} + +extern "C" { + #[link_name = "llvm.sqrt.f32"] + fn sqrt(x: f32) -> f32; +} + +pub fn do_call() { + let _a = A; + + unsafe { + // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them + // CHECK: store float 4.000000e+00, float* %{{.}}, align 4 + // CHECK: call float @llvm.sqrt.f32(float %{{.}} + sqrt(4.0); + } +} + +fn main() { + do_call(); +} diff --git a/compiler/rustc_codegen_gcc/tests/run/simd-ffi.rs b/compiler/rustc_codegen_gcc/tests/run/simd-ffi.rs new file mode 100644 index 000000000000..67cc2e5b96e3 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/simd-ffi.rs @@ -0,0 +1,102 @@ +// Compiler: +// +// Run-time: +// status: 0 + +// FIXME: Remove this test once stops +// ignoring GCC backend. + +#![allow(internal_features, non_camel_case_types)] +// we can compile to a variety of platforms, because we don't need +// cross-compiled standard libraries. +#![feature(no_core, auto_traits)] +#![no_core] +#![feature(repr_simd, simd_ffi, link_llvm_intrinsics, lang_items, rustc_attrs)] + +#[derive(Copy)] +#[repr(simd)] +pub struct f32x4([f32; 4]); + +extern "C" { + #[link_name = "llvm.sqrt.v4f32"] + fn vsqrt(x: f32x4) -> f32x4; +} + +pub fn foo(x: f32x4) -> f32x4 { + unsafe { vsqrt(x) } +} + +#[derive(Copy)] +#[repr(simd)] +pub struct i32x4([i32; 4]); + +extern "C" { + // _mm_sll_epi32 + #[cfg(all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"))] + #[link_name = "llvm.x86.sse2.psll.d"] + fn integer(a: i32x4, b: i32x4) -> i32x4; + + // vmaxq_s32 + #[cfg(target_arch = "arm")] + #[link_name = "llvm.arm.neon.vmaxs.v4i32"] + fn integer(a: i32x4, b: i32x4) -> i32x4; + // vmaxq_s32 + #[cfg(target_arch = "aarch64")] + #[link_name = "llvm.aarch64.neon.maxs.v4i32"] + fn integer(a: i32x4, b: i32x4) -> i32x4; + + // Use a generic LLVM intrinsic to do type checking on other platforms + #[cfg(not(any( + all(any(target_arch = "x86", target_arch = "x86-64"), target_feature = "sse2"), + target_arch = "arm", + target_arch = "aarch64" + )))] + #[link_name = "llvm.smax.v4i32"] + fn integer(a: i32x4, b: i32x4) -> i32x4; +} + +pub fn bar(a: i32x4, b: i32x4) -> i32x4 { + unsafe { integer(a, b) } +} + +#[lang = "pointee_sized"] +pub trait PointeeSized {} + +#[lang = "meta_sized"] +pub trait MetaSized: PointeeSized {} + +#[lang = "sized"] +pub trait Sized: MetaSized {} + +#[lang = "copy"] +pub trait Copy {} + +impl Copy for f32 {} +impl Copy for i32 {} +impl Copy for [f32; 4] {} +impl Copy for [i32; 4] {} + +pub mod marker { + pub use Copy; +} + +#[lang = "freeze"] +auto trait Freeze {} + +#[macro_export] +#[rustc_builtin_macro] +macro_rules! Copy { + () => {}; +} +#[macro_export] +#[rustc_builtin_macro] +macro_rules! derive { + () => {}; +} + +#[lang = "start"] +fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize { + 0 +} + +fn main() {} diff --git a/compiler/rustc_codegen_gcc/tests/run/unreachable-function.rs b/compiler/rustc_codegen_gcc/tests/run/unreachable-function.rs new file mode 100644 index 000000000000..0a975487dd78 --- /dev/null +++ b/compiler/rustc_codegen_gcc/tests/run/unreachable-function.rs @@ -0,0 +1,27 @@ +// Compiler: +// +// Run-time: +// status: 0 + +use std::arch::asm; + +fn exit_syscall(status: i32) -> ! { + #[cfg(target_arch = "x86_64")] + unsafe { + asm!( + "syscall", + in("rax") 60, + in("rdi") status, + options(noreturn) + ); + } + + #[cfg(not(target_arch = "x86_64"))] + std::process::exit(status); +} + +fn main() { + // Used to crash with rustc_codegen_gcc. + exit_syscall(0); + std::process::exit(1); +} diff --git a/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py b/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py index 767082c23cce..539032340777 100644 --- a/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py +++ b/compiler/rustc_codegen_gcc/tools/generate_intrinsics.py @@ -12,7 +12,7 @@ def run_command(command, cwd=None): sys.exit(1) -def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None): +def clone_repository(repo_name, path, repo_url, sub_paths): if os.path.exists(path): while True: choice = input("There is already a `{}` folder, do you want to update it? [y/N]".format(path)) @@ -21,18 +21,15 @@ def clone_repository(repo_name, path, repo_url, branch="master", sub_paths=None) return elif choice.lower() == "y": print("Updating repository...") - run_command(["git", "pull", "origin", branch], cwd=path) + run_command(["git", "pull", "origin", "main"], cwd=path) return else: print("Didn't understand answer...") print("Cloning {} repository...".format(repo_name)) - if sub_paths is None: - run_command(["git", "clone", repo_url, "--depth", "1", path]) - else: - run_command(["git", "clone", repo_url, "--filter=tree:0", "--no-checkout", path]) - run_command(["git", "sparse-checkout", "init"], cwd=path) - run_command(["git", "sparse-checkout", "set", *sub_paths], cwd=path) - run_command(["git", "checkout"], cwd=path) + run_command(["git", "clone", repo_url, "--filter=tree:0", "--no-checkout", path]) + run_command(["git", "sparse-checkout", "init"], cwd=path) + run_command(["git", "sparse-checkout", "set", *sub_paths], cwd=path) + run_command(["git", "checkout"], cwd=path) def append_intrinsic(array, intrinsic_name, translation): @@ -45,121 +42,36 @@ def convert_to_string(content): return content -def extract_intrinsics_from_llvm(llvm_path, intrinsics): - command = ["llvm-tblgen", "llvm/IR/Intrinsics.td"] +def extract_intrinsics_from_llvm(llvm_path): + intrinsics = {} + command = ["llvm-tblgen", "llvm/IR/Intrinsics.td", "--dump-json"] cwd = os.path.join(llvm_path, "llvm/include") print("=> Running command `{}` from `{}`".format(command, cwd)) p = subprocess.Popen(command, cwd=cwd, stdout=subprocess.PIPE) output, err = p.communicate() - lines = convert_to_string(output).splitlines() - pos = 0 - while pos < len(lines): - line = lines[pos] - if not line.startswith("def "): - pos += 1 + content = json.loads(convert_to_string(output)) + for intrinsic in content: + data = content[intrinsic] + if not isinstance(data, dict): continue - intrinsic = line.split(" ")[1].strip() - content = line - while pos < len(lines): - line = lines[pos].split(" // ")[0].strip() - content += line - pos += 1 - if line == "}": - break - entries = re.findall('string ClangBuiltinName = "(\\w+)";', content) - current_arch = re.findall('string TargetPrefix = "(\\w+)";', content) - if len(entries) == 1 and len(current_arch) == 1: - current_arch = current_arch[0] - intrinsic = intrinsic.split("_") - if len(intrinsic) < 2 or intrinsic[0] != "int": - continue - intrinsic[0] = "llvm" - intrinsic = ".".join(intrinsic) - if current_arch not in intrinsics: - intrinsics[current_arch] = [] - append_intrinsic(intrinsics[current_arch], intrinsic, entries[0]) - - -def append_translation(json_data, p, array): - it = json_data["index"][p] - content = it["docs"].split('`') - if len(content) != 5: - return - append_intrinsic(array, content[1], content[3]) - - -def extract_intrinsics_from_llvmint(llvmint, intrinsics): - archs = [ - "AMDGPU", - "aarch64", - "arm", - "cuda", - "hexagon", - "mips", - "nvvm", - "ppc", - "ptx", - "x86", - "xcore", - ] - - json_file = os.path.join(llvmint, "target/doc/llvmint.json") - # We need to regenerate the documentation! - run_command( - ["cargo", "rustdoc", "--", "-Zunstable-options", "--output-format", "json"], - cwd=llvmint, - ) - with open(json_file, "r", encoding="utf8") as f: - json_data = json.loads(f.read()) - for p in json_data["paths"]: - it = json_data["paths"][p] - if it["crate_id"] != 0: - # This is from an external crate. + current_arch = data.get("TargetPrefix") + builtin_name = data.get("ClangBuiltinName") + if current_arch is None or current_arch == "" or builtin_name is None: continue - if it["kind"] != "function": - # We're only looking for functions. + intrinsic = intrinsic.split("_") + if len(intrinsic) < 2 or intrinsic[0] != "int": continue - # if len(it["path"]) == 2: - # # This is a "general" intrinsic, not bound to a specific arch. - # append_translation(json_data, p, general) - # continue - if len(it["path"]) != 3 or it["path"][1] not in archs: - continue - arch = it["path"][1] - if arch not in intrinsics: - intrinsics[arch] = [] - append_translation(json_data, p, intrinsics[arch]) + intrinsic[0] = "llvm" + intrinsic = ".".join(intrinsic) + if current_arch not in intrinsics: + intrinsics[current_arch] = [] + append_intrinsic(intrinsics[current_arch], intrinsic, builtin_name) + + return intrinsics -def fill_intrinsics(intrinsics, from_intrinsics, all_intrinsics): - for arch in from_intrinsics: - if arch not in intrinsics: - intrinsics[arch] = [] - for entry in from_intrinsics[arch]: - if entry[0] in all_intrinsics: - if all_intrinsics[entry[0]] == entry[1]: - # This is a "full" duplicate, both the LLVM instruction and the GCC - # translation are the same. - continue - intrinsics[arch].append((entry[0], entry[1], True)) - else: - intrinsics[arch].append((entry[0], entry[1], False)) - all_intrinsics[entry[0]] = entry[1] - - -def update_intrinsics(llvm_path, llvmint, llvmint2): - intrinsics_llvm = {} - intrinsics_llvmint = {} - all_intrinsics = {} - - extract_intrinsics_from_llvm(llvm_path, intrinsics_llvm) - extract_intrinsics_from_llvmint(llvmint, intrinsics_llvmint) - extract_intrinsics_from_llvmint(llvmint2, intrinsics_llvmint) - - intrinsics = {} - # We give priority to translations from LLVM over the ones from llvmint. - fill_intrinsics(intrinsics, intrinsics_llvm, all_intrinsics) - fill_intrinsics(intrinsics, intrinsics_llvmint, all_intrinsics) +def update_intrinsics(llvm_path): + intrinsics = extract_intrinsics_from_llvm(llvm_path) archs = [arch for arch in intrinsics] archs.sort() @@ -173,33 +85,41 @@ def update_intrinsics(llvm_path, llvmint, llvmint2): # Since all intrinsic names start with "llvm.", we skip that prefix. print("Updating content of `{}`...".format(output_file)) with open(output_file, "w", encoding="utf8") as out: - out.write("// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py`\n") - out.write("// DO NOT EDIT IT!\n") - out.write("/// Translate a given LLVM intrinsic name to an equivalent GCC one.\n") - out.write("fn map_arch_intrinsic(full_name:&str)->&'static str{\n") - out.write('let Some(name) = full_name.strip_prefix("llvm.") else { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) };\n') - out.write('let Some((arch, name)) = name.split_once(\'.\') else { unimplemented!("***** unsupported LLVM intrinsic {}", name) };\n') - out.write("match arch {\n") + out.write("""// File generated by `rustc_codegen_gcc/tools/generate_intrinsics.py` +// DO NOT EDIT IT! +/// Translate a given LLVM intrinsic name to an equivalent GCC one. +fn map_arch_intrinsic(full_name:&str)-> &'static str { + let Some(name) = full_name.strip_prefix("llvm.") else { unimplemented!("***** unsupported LLVM intrinsic {}", full_name) }; + let Some((arch, name)) = name.split_once('.') else { unimplemented!("***** unsupported LLVM intrinsic llvm.{}", name) }; + let old_arch_res = old_archs(arch, name); + if let ArchCheckResult::Ok(res) = old_arch_res { + return res; + } +match arch {""") for arch in archs: if len(intrinsics[arch]) == 0: continue attribute = "#[expect(non_snake_case)]" if arch[0].isupper() else "" out.write("\"{}\" => {{ {} fn {}(name: &str,full_name:&str) -> &'static str {{ match name {{".format(arch, attribute, arch)) - intrinsics[arch].sort(key=lambda x: (x[0], x[2])) + intrinsics[arch].sort(key=lambda x: (x[0], x[1])) out.write(' // {}\n'.format(arch)) for entry in intrinsics[arch]: llvm_name = entry[0].removeprefix("llvm."); llvm_name = llvm_name.removeprefix(arch); llvm_name = llvm_name.removeprefix("."); - if entry[2] is True: # if it is a duplicate - out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(llvm_name, entry[1])) - elif "_round_mask" in entry[1]: + if "_round_mask" in entry[1]: out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(llvm_name, entry[1])) else: out.write(' "{}" => "{}",\n'.format(llvm_name, entry[1])) out.write(' _ => unimplemented!("***** unsupported LLVM intrinsic {full_name}"),\n') out.write("}} }} {}(name,full_name) }}\n,".format(arch)) - out.write(' _ => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic:{full_name}"),\n') + out.write(""" _ => { + match old_arch_res { + ArchCheckResult::UnknownIntrinsic => unimplemented!("***** unsupported LLVM intrinsic {full_name}"), + ArchCheckResult::UnknownArch => unimplemented!("***** unsupported LLVM architecture {arch}, intrinsic: {full_name}"), + ArchCheckResult::Ok(_) => unreachable!(), + } + }""") out.write("}\n}") subprocess.call(["rustfmt", output_file]) print("Done!") @@ -210,35 +130,21 @@ def main(): os.path.dirname(os.path.abspath(__file__)), "llvm-project", ) - llvmint_path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - "llvmint", - ) - llvmint2_path = os.path.join( - os.path.dirname(os.path.abspath(__file__)), - "llvmint-2", - ) # First, we clone the LLVM repository if it's not already here. clone_repository( "llvm-project", llvm_path, "https://github.com/llvm/llvm-project", - branch="main", - sub_paths=["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"], + ["llvm/include/llvm/IR", "llvm/include/llvm/CodeGen/"], ) - clone_repository( - "llvmint", - llvmint_path, - "https://github.com/GuillaumeGomez/llvmint", - ) - clone_repository( - "llvmint2", - llvmint2_path, - "https://github.com/antoyo/llvmint", - ) - update_intrinsics(llvm_path, llvmint_path, llvmint2_path) + update_intrinsics(llvm_path) +# llvm-tblgen can be built with: +# +# mkdir llvm-tblgen-build && cd llvm-tblgen-build +# cmake -G Ninja -DLLVM_ENABLE_PROJECTS="llvm" -DCMAKE_BUILD_TYPE=Release ../llvm +# ninja llvm-tblgen if __name__ == "__main__": sys.exit(main()) diff --git a/compiler/rustc_codegen_gcc/triagebot.toml b/compiler/rustc_codegen_gcc/triagebot.toml index 13da0a87def3..eb0c7b011f60 100644 --- a/compiler/rustc_codegen_gcc/triagebot.toml +++ b/compiler/rustc_codegen_gcc/triagebot.toml @@ -2,6 +2,3 @@ # Prevents un-canonicalized issue links (to avoid wrong issues being linked in r-l/rust) [issue-links] - -# Prevents mentions in commits to avoid users being spammed -[no-mentions] diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 0544a94fd59f..0ffff2d331b1 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -14,6 +14,7 @@ bitflags = "2.4.1" gimli = "0.31" itertools = "0.12" libc = "0.2" +libloading = { version = "0.9.0" } measureme = "12.0.1" object = { version = "0.37.0", default-features = false, features = ["std", "read"] } rustc-demangle = "0.1.21" @@ -22,7 +23,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } @@ -31,14 +31,11 @@ rustc_llvm = { path = "../rustc_llvm" } rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } -rustc_query_system = { path = "../rustc_query_system" } rustc_sanitizers = { path = "../rustc_sanitizers" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_target = { path = "../rustc_target" } -serde = { version = "1", features = ["derive"] } -serde_json = "1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl deleted file mode 100644 index 0e7b00d0bcb7..000000000000 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ /dev/null @@ -1,66 +0,0 @@ -codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable -codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml - -codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err} - - -codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture - -codegen_llvm_from_llvm_diag = {$message} - -codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message} - -codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}" -codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err} - -codegen_llvm_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$err}) - -codegen_llvm_mismatch_data_layout = - data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}` - -codegen_llvm_offload_without_enable = using the offload feature requires -Z offload=Enable -codegen_llvm_offload_without_fat_lto = using the offload feature requires -C lto=fat - -codegen_llvm_parse_bitcode = failed to parse bitcode for LTO module -codegen_llvm_parse_bitcode_with_llvm_err = failed to parse bitcode for LTO module: {$llvm_err} - -codegen_llvm_parse_target_machine_config = - failed to parse target machine config to target machine: {$error} - -codegen_llvm_prepare_autodiff = failed to prepare autodiff: src: {$src}, target: {$target}, {$error} -codegen_llvm_prepare_autodiff_with_llvm_err = failed to prepare autodiff: {$llvm_err}, src: {$src}, target: {$target}, {$error} -codegen_llvm_prepare_thin_lto_context = failed to prepare thin LTO context -codegen_llvm_prepare_thin_lto_context_with_llvm_err = failed to prepare thin LTO context: {$llvm_err} - -codegen_llvm_prepare_thin_lto_module = failed to prepare thin LTO module -codegen_llvm_prepare_thin_lto_module_with_llvm_err = failed to prepare thin LTO module: {$llvm_err} - -codegen_llvm_run_passes = failed to run LLVM passes -codegen_llvm_run_passes_with_llvm_err = failed to run LLVM passes: {$llvm_err} - -codegen_llvm_sanitizer_kcfi_arity_requires_llvm_21_0_0 = `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later. - -codegen_llvm_sanitizer_memtag_requires_mte = - `-Zsanitizer=memtag` requires `-Ctarget-feature=+mte` - -codegen_llvm_serialize_module = failed to serialize module {$name} -codegen_llvm_serialize_module_with_llvm_err = failed to serialize module {$name}: {$llvm_err} - -codegen_llvm_symbol_already_defined = - symbol `{$symbol_name}` is already defined - -codegen_llvm_target_machine = could not create LLVM TargetMachine for triple: {$triple} -codegen_llvm_target_machine_with_llvm_err = could not create LLVM TargetMachine for triple: {$triple}: {$llvm_err} - -codegen_llvm_unknown_debuginfo_compression = unknown debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo - -codegen_llvm_write_bytecode = failed to write bytecode to {$path}: {$err} - -codegen_llvm_write_ir = failed to write LLVM IR to {$path} -codegen_llvm_write_ir_with_llvm_err = failed to write LLVM IR to {$path}: {$llvm_err} - -codegen_llvm_write_output = could not write output to {$path} -codegen_llvm_write_output_with_llvm_err = could not write output to {$path}: {$llvm_err} - -codegen_llvm_write_thinlto_key = error while writing ThinLTO key data: {$err} -codegen_llvm_write_thinlto_key_with_llvm_err = error while writing ThinLTO key data: {$err}: {$llvm_err} diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index c3c1caf086f0..994077251acc 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -694,6 +694,10 @@ pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm: match abi { CanonAbi::C | CanonAbi::Rust => llvm::CCallConv, CanonAbi::RustCold => llvm::PreserveMost, + CanonAbi::RustPreserveNone => match &sess.target.arch { + Arch::X86_64 | Arch::AArch64 => llvm::PreserveNone, + _ => llvm::CCallConv, + }, // Functions with this calling convention can only be called from assembly, but it is // possible to declare an `extern "custom"` block, so the backend still needs a calling // convention for declaring foreign functions. diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index de0b85ebb63b..24b2bd37aa46 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -7,13 +7,13 @@ use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::ty::TyCtxt; -use rustc_session::config::{DebugInfo, OomStrategy}; +use rustc_session::config::DebugInfo; use rustc_symbol_mangling::mangle_internal_symbol; use crate::attributes::llfn_attrs_from_instance; use crate::builder::SBuilder; use crate::declare::declare_simple_fn; -use crate::llvm::{self, FALSE, FromGeneric, TRUE, Type, Value}; +use crate::llvm::{self, FromGeneric, TRUE, Type}; use crate::{SimpleCx, attributes, debuginfo}; pub(crate) unsafe fn codegen( @@ -28,7 +28,6 @@ pub(crate) unsafe fn codegen( 64 => cx.type_i64(), tws => bug!("Unsupported target word size for int: {}", tws), }; - let i8 = cx.type_i8(); let i8p = cx.type_ptr(); for method in methods { @@ -87,17 +86,6 @@ pub(crate) unsafe fn codegen( ); } - // __rust_alloc_error_handler_should_panic_v2 - create_const_value_function( - tcx, - &cx, - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - &i8, - unsafe { - llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, FALSE) - }, - ); - // __rust_no_alloc_shim_is_unstable_v2 create_wrapper_function( tcx, @@ -117,34 +105,6 @@ pub(crate) unsafe fn codegen( } } -fn create_const_value_function( - tcx: TyCtxt<'_>, - cx: &SimpleCx<'_>, - name: &str, - output: &Type, - value: &Value, -) { - let ty = cx.type_func(&[], output); - let llfn = declare_simple_fn( - &cx, - name, - llvm::CallConv::CCallConv, - llvm::UnnamedAddr::Global, - llvm::Visibility::from_generic(tcx.sess.default_visibility()), - ty, - ); - - attributes::apply_to_llfn( - llfn, - llvm::AttributePlace::Function, - &[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)], - ); - - let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) }; - let mut bx = SBuilder::build(&cx, llbb); - bx.ret(value); -} - fn create_wrapper_function( tcx: TyCtxt<'_>, cx: &SimpleCx<'_>, diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index ee1b6d45e149..80d77be1cc38 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -1,9 +1,8 @@ -use std::assert_matches::assert_matches; - use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_codegen_ssa::mir::operand::OperandValue; use rustc_codegen_ssa::traits::*; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::Instance; use rustc_middle::ty::layout::TyAndLayout; @@ -400,7 +399,8 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { for piece in template { match *piece { InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s), - InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => { + InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => { + use rustc_codegen_ssa::back::symbol_export::escape_symbol_name; match operands[operand_idx] { GlobalAsmOperandRef::Const { ref string } => { // Const operands get injected directly into the @@ -415,7 +415,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { llvm::LLVMRustGetMangledName(llval, s); }) .expect("symbol is not valid UTF-8"); - template_str.push_str(&symbol); + template_str.push_str(&escape_symbol_name(self.tcx, &symbol, span)); } GlobalAsmOperandRef::SymStatic { def_id } => { let llval = self @@ -429,7 +429,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { llvm::LLVMRustGetMangledName(llval, s); }) .expect("symbol is not valid UTF-8"); - template_str.push_str(&symbol); + template_str.push_str(&escape_symbol_name(self.tcx, &symbol, span)); } } } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index a25ce9e5a90a..b5ab26aea492 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,6 +1,7 @@ //! Set and unset common attributes on LLVM values. use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr, RtsanSetting}; use rustc_hir::def_id::DefId; +use rustc_hir::find_attr; use rustc_middle::middle::codegen_fn_attrs::{ CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; @@ -300,17 +301,6 @@ fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll A Some(sspattr.create_attr(cx.llcx)) } -fn backchain_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { - if sess.target.arch != Arch::S390x { - return None; - } - - let requested_features = sess.opts.cg.target_feature.split(','); - let found_positive = requested_features.clone().any(|r| r == "+backchain"); - - if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None } -} - pub(crate) fn target_cpu_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> &'ll Attribute { let target_cpu = llvm_util::target_cpu(sess); llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu) @@ -369,7 +359,7 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute { llvm::CreateAttrStringValue(llcx, "alloc-family", "__rust_alloc") } -/// Helper for `FnAbi::apply_attrs_llfn`: +/// Helper for `FnAbiLlvmExt::apply_attrs_llfn`: /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( @@ -470,9 +460,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( { to_add.push(create_alloc_family_attr(cx.llcx)); if let Some(instance) = instance - && let Some(zv) = - tcx.get_attr(instance.def_id(), rustc_span::sym::rustc_allocator_zeroed_variant) - && let Some(name) = zv.value_str() + && let Some(name) = find_attr!(tcx.get_all_attrs(instance.def_id()), rustc_hir::attrs::AttributeKind::RustcAllocatorZeroedVariant {name} => name) { to_add.push(llvm::CreateAttrStringValue( cx.llcx, @@ -517,14 +505,20 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( to_add.push(llvm::CreateAllocKindAttr(cx.llcx, AllocKindFlags::Free)); // applies to argument place instead of function place let allocated_pointer = AttributeKind::AllocatedPointer.create_attr(cx.llcx); - attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), &[allocated_pointer]); + let attrs: &[_] = if llvm_util::get_version() >= (21, 0, 0) { + // "Does not capture provenance" means "if the function call stashes the pointer somewhere, + // accessing that pointer after the function returns is UB". That is definitely the case here since + // freeing will destroy the provenance. + let captures_addr = AttributeKind::CapturesAddress.create_attr(cx.llcx); + &[allocated_pointer, captures_addr] + } else { + &[allocated_pointer] + }; + attributes::apply_to_llfn(llfn, AttributePlace::Argument(0), attrs); } if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align); } - if let Some(backchain) = backchain_attr(cx, sess) { - to_add.push(backchain); - } to_add.extend(patchable_function_entry_attrs( cx, sess, diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 482e95413855..5d272d10930b 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -9,12 +9,15 @@ use std::{io, iter, slice}; use object::read::archive::ArchiveFile; use object::{Object, ObjectSection}; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared}; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; +use rustc_codegen_ssa::back::write::{ + CodegenContext, FatLtoInput, SharedEmitter, TargetMachineFactoryFn, +}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::memmap::Mmap; -use rustc_errors::DiagCtxtHandle; +use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_hir::attrs::SanitizerSet; use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; @@ -33,7 +36,7 @@ use crate::{LlvmCodegenBackend, ModuleLlvm}; const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin"; fn prepare_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], dcx: DiagCtxtHandle<'_>, @@ -123,7 +126,7 @@ fn prepare_lto( fn get_bitcode_slice_from_object_data<'a>( obj: &'a [u8], - cgcx: &CodegenContext, + cgcx: &CodegenContext, ) -> Result<&'a [u8], LtoBitcodeFromRlib> { // We're about to assume the data here is an object file with sections, but if it's raw LLVM IR // that won't work. Fortunately, if that's what we have we can just return the object directly, @@ -149,43 +152,55 @@ fn get_bitcode_slice_from_object_data<'a>( /// Performs fat LTO by merging all modules into a single one and returning it /// for further optimization. pub(crate) fn run_fat( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, + tm_factory: TargetMachineFactoryFn, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, dcx); let symbols_below_threshold = symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>(); - fat_lto(cgcx, dcx, modules, upstream_modules, &symbols_below_threshold) + fat_lto( + cgcx, + prof, + dcx, + shared_emitter, + tm_factory, + modules, + upstream_modules, + &symbols_below_threshold, + ) } /// Performs thin LTO by performing necessary global analysis and returning two /// lists, one of the modules that need optimization and another for modules that /// can simply be copied over from the incr. comp. cache. pub(crate) fn run_thin( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, ThinBuffer)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, ) -> (Vec>, Vec) { - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); let (symbols_below_threshold, upstream_modules) = prepare_lto(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, dcx); let symbols_below_threshold = symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::>(); - if cgcx.opts.cg.linker_plugin_lto.enabled() { + if cgcx.use_linker_plugin_lto { unreachable!( "We should never reach this case if the LTO step \ is deferred to the linker" ); } - thin_lto(cgcx, dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold) + thin_lto(cgcx, prof, dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold) } pub(crate) fn prepare_thin(module: ModuleCodegen) -> (String, ThinBuffer) { @@ -195,13 +210,16 @@ pub(crate) fn prepare_thin(module: ModuleCodegen) -> (String, ThinBu } fn fat_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, dcx: DiagCtxtHandle<'_>, + shared_emitter: &SharedEmitter, + tm_factory: TargetMachineFactoryFn, modules: Vec>, mut serialized_modules: Vec<(SerializedModule, CString)>, symbols_below_threshold: &[*const libc::c_char], ) -> ModuleCodegen { - let _timer = cgcx.prof.generic_activity("LLVM_fat_lto_build_monolithic_module"); + let _timer = prof.generic_activity("LLVM_fat_lto_build_monolithic_module"); info!("going for a fat lto"); // Sort out all our lists of incoming modules into two lists. @@ -251,7 +269,7 @@ fn fat_lto( assert!(!serialized_modules.is_empty(), "must have at least one serialized module"); let (buffer, name) = serialized_modules.remove(0); info!("no in-memory regular modules to choose from, parsing {:?}", name); - let llvm_module = ModuleLlvm::parse(cgcx, &name, buffer.data(), dcx); + let llvm_module = ModuleLlvm::parse(cgcx, tm_factory, &name, buffer.data(), dcx); ModuleCodegen::new_regular(name.into_string().unwrap(), llvm_module) } }; @@ -265,8 +283,13 @@ fn fat_lto( // The linking steps below may produce errors and diagnostics within LLVM // which we'd like to handle and print, so set up our diagnostic handlers // (which get unregistered when they go out of scope below). - let _handler = - DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::LTO); + let _handler = DiagnosticHandlers::new( + cgcx, + shared_emitter, + llcx, + &module, + CodegenDiagnosticsStage::LTO, + ); // For all other modules we codegened we'll need to link them into our own // bitcode. All modules were codegened in their own LLVM context, however, @@ -285,8 +308,7 @@ fn fat_lto( // above, this is all mostly handled in C++. let mut linker = Linker::new(llmod); for (bc_decoded, name) in serialized_modules { - let _timer = cgcx - .prof + let _timer = prof .generic_activity_with_arg_recorder("LLVM_fat_lto_link_module", |recorder| { recorder.record_arg(format!("{name:?}")) }); @@ -375,14 +397,15 @@ impl Drop for Linker<'_> { /// all of the `LtoModuleCodegen` units returned below and destroyed once /// they all go out of scope. fn thin_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, dcx: DiagCtxtHandle<'_>, modules: Vec<(String, ThinBuffer)>, serialized_modules: Vec<(SerializedModule, CString)>, cached_modules: Vec<(SerializedModule, WorkProduct)>, symbols_below_threshold: &[*const libc::c_char], ) -> (Vec>, Vec) { - let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis"); + let _timer = prof.generic_activity("LLVM_thin_lto_global_analysis"); unsafe { info!("going for that thin, thin LTO"); @@ -528,31 +551,33 @@ fn thin_lto( } } -fn enable_autodiff_settings(ad: &[config::AutoDiff]) { +pub(crate) fn enable_autodiff_settings(ad: &[config::AutoDiff]) { + let mut enzyme = llvm::EnzymeWrapper::get_instance(); + for val in ad { // We intentionally don't use a wildcard, to not forget handling anything new. match val { config::AutoDiff::PrintPerf => { - llvm::set_print_perf(true); + enzyme.set_print_perf(true); } config::AutoDiff::PrintAA => { - llvm::set_print_activity(true); + enzyme.set_print_activity(true); } config::AutoDiff::PrintTA => { - llvm::set_print_type(true); + enzyme.set_print_type(true); } config::AutoDiff::PrintTAFn(fun) => { - llvm::set_print_type(true); // Enable general type printing - llvm::set_print_type_fun(&fun); // Set specific function to analyze + enzyme.set_print_type(true); // Enable general type printing + enzyme.set_print_type_fun(&fun); // Set specific function to analyze } config::AutoDiff::Inline => { - llvm::set_inline(true); + enzyme.set_inline(true); } config::AutoDiff::LooseTypes => { - llvm::set_loose_types(true); + enzyme.set_loose_types(true); } config::AutoDiff::PrintSteps => { - llvm::set_print(true); + enzyme.set_print(true); } // We handle this in the PassWrapper.cpp config::AutoDiff::PrintPasses => {} @@ -571,18 +596,19 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff]) { } } // This helps with handling enums for now. - llvm::set_strict_aliasing(false); + enzyme.set_strict_aliasing(false); // FIXME(ZuseZ4): Test this, since it was added a long time ago. - llvm::set_rust_rules(true); + enzyme.set_rust_rules(true); } pub(crate) fn run_pass_manager( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, dcx: DiagCtxtHandle<'_>, module: &mut ModuleCodegen, thin: bool, ) { - let _timer = cgcx.prof.generic_activity_with_arg("LLVM_lto_optimize", &*module.name); + let _timer = prof.generic_activity_with_arg("LLVM_lto_optimize", &*module.name); let config = &cgcx.module_config; // Now we have one massive module inside of llmod. Time to run the @@ -607,12 +633,8 @@ pub(crate) fn run_pass_manager( if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD } }; - if enable_ad { - enable_autodiff_settings(&config.autodiff); - } - unsafe { - write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage); + write::llvm_optimize(cgcx, prof, dcx, module, None, config, opt_level, opt_stage, stage); } if cfg!(feature = "llvm_enzyme") && enable_ad && !thin { @@ -620,7 +642,9 @@ pub(crate) fn run_pass_manager( let stage = write::AutodiffStage::PostAD; if !config.autodiff.contains(&config::AutoDiff::NoPostopt) { unsafe { - write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage); + write::llvm_optimize( + cgcx, prof, dcx, module, None, config, opt_level, opt_stage, stage, + ); } } @@ -722,10 +746,13 @@ impl Drop for ThinBuffer { } pub(crate) fn optimize_thin_module( + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, + tm_factory: TargetMachineFactoryFn, thin_module: ThinModule, - cgcx: &CodegenContext, ) -> ModuleCodegen { - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); let module_name = &thin_module.shared.module_names[thin_module.idx]; @@ -735,7 +762,7 @@ pub(crate) fn optimize_thin_module( // into that context. One day, however, we may do this for upstream // crates but for locally codegened modules we may be able to reuse // that LLVM Context and Module. - let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx); + let module_llvm = ModuleLlvm::parse(cgcx, tm_factory, module_name, thin_module.data(), dcx); let mut module = ModuleCodegen::new_regular(thin_module.name(), module_llvm); // Given that the newly created module lacks a thinlto buffer for embedding, we need to re-add it here. if cgcx.module_config.embed_bitcode() { @@ -755,8 +782,7 @@ pub(crate) fn optimize_thin_module( // You can find some more comments about these functions in the LLVM // bindings we've got (currently `PassWrapper.cpp`) { - let _timer = - cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name()); + let _timer = prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name()); unsafe { llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target.raw()) }; @@ -764,9 +790,8 @@ pub(crate) fn optimize_thin_module( } { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name()); + let _timer = + prof.generic_activity_with_arg("LLVM_thin_lto_resolve_weak", thin_module.name()); if unsafe { !llvm::LLVMRustPrepareThinLTOResolveWeak(thin_module.shared.data.0, llmod) } { write::llvm_err(dcx, LlvmError::PrepareThinLtoModule); @@ -775,9 +800,8 @@ pub(crate) fn optimize_thin_module( } { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name()); + let _timer = + prof.generic_activity_with_arg("LLVM_thin_lto_internalize", thin_module.name()); if unsafe { !llvm::LLVMRustPrepareThinLTOInternalize(thin_module.shared.data.0, llmod) } { write::llvm_err(dcx, LlvmError::PrepareThinLtoModule); @@ -786,8 +810,7 @@ pub(crate) fn optimize_thin_module( } { - let _timer = - cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name()); + let _timer = prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name()); if unsafe { !llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target.raw()) } { @@ -803,7 +826,7 @@ pub(crate) fn optimize_thin_module( // little differently. { info!("running thin lto passes over {}", module.name); - run_pass_manager(cgcx, dcx, &mut module, true); + run_pass_manager(cgcx, prof, dcx, &mut module, true); save_temp_bitcode(cgcx, &module, "thin-lto-after-pm"); } } diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index f88932d43d2a..65cf4cad24bd 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -39,6 +39,7 @@ impl OwnedTargetMachine { debug_info_compression: llvm::CompressionKind, use_emulated_tls: bool, use_wasm_eh: bool, + large_data_threshold: u64, ) -> Result> { // SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data let tm_ptr = unsafe { @@ -65,6 +66,7 @@ impl OwnedTargetMachine { debug_info_compression, use_emulated_tls, use_wasm_eh, + large_data_threshold, ) }; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index b131de1df8ba..3e3ccd39e674 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -9,22 +9,21 @@ use libc::{c_char, c_int, c_void, size_t}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::back::write::{ - BitcodeSection, CodegenContext, EmitObj, InlineAsmError, ModuleConfig, + BitcodeSection, CodegenContext, EmitObj, InlineAsmError, ModuleConfig, SharedEmitter, TargetMachineFactoryConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::wants_wasm_eh; +use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_errors::{DiagCtxtHandle, Level}; +use rustc_errors::{DiagCtxt, DiagCtxtHandle, Level}; use rustc_fs_util::{link_or_copy, path_to_c_string}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_session::config::{ - self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath, -}; -use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext, sym}; +use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath}; +use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext, sym}; use rustc_target::spec::{ Arch, CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel, }; @@ -35,10 +34,12 @@ use crate::back::owned_target_machine::OwnedTargetMachine; use crate::back::profiling::{ LlvmSelfProfiler, selfprofile_after_pass_callback, selfprofile_before_pass_callback, }; +use crate::builder::SBuilder; +use crate::builder::gpu_offload::scalar_width; use crate::common::AsCCharPtr; use crate::errors::{ - CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, UnknownCompression, - WithLlvmError, WriteBytecode, + CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, ParseTargetMachineConfig, + UnknownCompression, WithLlvmError, WriteBytecode, }; use crate::llvm::diagnostic::OptimizationDiagnosticKind::*; use crate::llvm::{self, DiagnosticInfo}; @@ -110,8 +111,7 @@ pub(crate) fn create_informational_target_machine( // Can't use query system here quite yet because this function is invoked before the query // system/tcx is set up. let features = llvm_util::global_llvm_features(sess, only_base_features); - target_machine_factory(sess, config::OptLevel::No, &features)(config) - .unwrap_or_else(|err| llvm_err(sess.dcx(), err)) + target_machine_factory(sess, config::OptLevel::No, &features)(sess.dcx(), config) } pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine { @@ -137,8 +137,7 @@ pub(crate) fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTar tcx.sess, tcx.backend_optimization_level(()), tcx.global_backend_features(()), - )(config) - .unwrap_or_else(|err| llvm_err(tcx.dcx(), err)) + )(tcx.dcx(), config) } fn to_llvm_opt_settings(cfg: config::OptLevel) -> (llvm::CodeGenOptLevel, llvm::CodeGenOptSize) { @@ -248,10 +247,11 @@ pub(crate) fn target_machine_factory( !sess.opts.unstable_opts.use_ctors_section.unwrap_or(sess.target.use_ctors_section); let path_mapping = sess.source_map().path_mapping().clone(); + let working_dir = sess.source_map().working_dir().clone(); let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated); - let debuginfo_compression = match sess.opts.debuginfo_compression { + let debuginfo_compression = match sess.opts.unstable_opts.debuginfo_compression { config::DebugInfoCompression::None => llvm::CompressionKind::None, config::DebugInfoCompression::Zlib => { if llvm::LLVMRustLLVMHasZlibCompression() { @@ -271,21 +271,21 @@ pub(crate) fn target_machine_factory( } }; - let file_name_display_preference = - sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO); - let use_wasm_eh = wants_wasm_eh(sess); + let large_data_threshold = sess.opts.unstable_opts.large_data_threshold.unwrap_or(0); + let prof = SelfProfilerRef::clone(&sess.prof); - Arc::new(move |config: TargetMachineFactoryConfig| { + Arc::new(move |dcx: DiagCtxtHandle<'_>, config: TargetMachineFactoryConfig| { // Self-profile timer for invoking a factory to create a target machine. let _prof_timer = prof.generic_activity("target_machine_factory_inner"); let path_to_cstring_helper = |path: Option| -> CString { let path = path.unwrap_or_default(); let path = path_mapping - .to_real_filename(path) - .to_string_lossy(file_name_display_preference) + .to_real_filename(&working_dir, path) + .path(RemapPathScopeComponents::DEBUGINFO) + .to_string_lossy() .into_owned(); CString::new(path).unwrap() }; @@ -316,12 +316,14 @@ pub(crate) fn target_machine_factory( debuginfo_compression, use_emulated_tls, use_wasm_eh, + large_data_threshold, ) + .unwrap_or_else(|err| dcx.emit_fatal(ParseTargetMachineConfig(err))) }) } pub(crate) fn save_temp_bitcode( - cgcx: &CodegenContext, + cgcx: &CodegenContext, module: &ModuleCodegen, name: &str, ) { @@ -356,15 +358,15 @@ pub(crate) enum CodegenDiagnosticsStage { } pub(crate) struct DiagnosticHandlers<'a> { - data: *mut (&'a CodegenContext, DiagCtxtHandle<'a>), + data: *mut (&'a CodegenContext, &'a SharedEmitter), llcx: &'a llvm::Context, old_handler: Option<&'a llvm::DiagnosticHandler>, } impl<'a> DiagnosticHandlers<'a> { pub(crate) fn new( - cgcx: &'a CodegenContext, - dcx: DiagCtxtHandle<'a>, + cgcx: &'a CodegenContext, + shared_emitter: &'a SharedEmitter, llcx: &'a llvm::Context, module: &ModuleCodegen, stage: CodegenDiagnosticsStage, @@ -398,8 +400,8 @@ impl<'a> DiagnosticHandlers<'a> { }) .and_then(|dir| dir.to_str().and_then(|p| CString::new(p).ok())); - let pgo_available = cgcx.opts.cg.profile_use.is_some(); - let data = Box::into_raw(Box::new((cgcx, dcx))); + let pgo_available = cgcx.module_config.pgo_use.is_some(); + let data = Box::into_raw(Box::new((cgcx, shared_emitter))); unsafe { let old_handler = llvm::LLVMRustContextGetDiagnosticHandler(llcx); llvm::LLVMRustContextConfigureDiagnosticHandler( @@ -429,7 +431,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> { } fn report_inline_asm( - cgcx: &CodegenContext, + cgcx: &CodegenContext, msg: String, level: llvm::DiagnosticLevel, cookie: u64, @@ -461,12 +463,15 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void if user.is_null() { return; } - let (cgcx, dcx) = - unsafe { *(user as *const (&CodegenContext, DiagCtxtHandle<'_>)) }; + let (cgcx, shared_emitter) = unsafe { *(user as *const (&CodegenContext, &SharedEmitter)) }; + + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); match unsafe { llvm::diagnostic::Diagnostic::unpack(info) } { llvm::diagnostic::InlineAsm(inline) => { - cgcx.diag_emitter.inline_asm_error(report_inline_asm( + // FIXME use dcx + shared_emitter.inline_asm_error(report_inline_asm( cgcx, inline.message, inline.level, @@ -554,7 +559,8 @@ pub(crate) enum AutodiffStage { } pub(crate) unsafe fn llvm_optimize( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, dcx: DiagCtxtHandle<'_>, module: &ModuleCodegen, thin_lto_buffer: Option<&mut *mut llvm::ThinLTOBuffer>, @@ -571,8 +577,7 @@ pub(crate) unsafe fn llvm_optimize( // FIXME(ZuseZ4): In a future update we could figure out how to only optimize individual functions getting // differentiated. - let consider_ad = - cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable); + let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable); let run_enzyme = autodiff_stage == AutodiffStage::DuringAD; let print_before_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModBefore); let print_after_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModAfter); @@ -673,7 +678,17 @@ pub(crate) unsafe fn llvm_optimize( // Create the new parameter list, with ptr as the first argument let mut new_param_types = Vec::with_capacity(old_param_count as usize + 1); new_param_types.push(cx.type_ptr()); - new_param_types.extend(old_param_types); + + // This relies on undocumented LLVM knowledge that scalars must be passed as i64 + for &old_ty in &old_param_types { + let new_ty = match cx.type_kind(old_ty) { + TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::Integer => { + cx.type_i64() + } + _ => old_ty, + }; + new_param_types.push(new_ty); + } // Create the new function type let ret_ty = unsafe { llvm::LLVMGetReturnType(old_fn_ty) }; @@ -686,10 +701,33 @@ pub(crate) unsafe fn llvm_optimize( let a0 = llvm::get_param(new_fn, 0); llvm::set_value_name(a0, CString::new("dyn_ptr").unwrap().as_bytes()); + let bb = SBuilder::append_block(cx, new_fn, "entry"); + let mut builder = SBuilder::build(cx, bb); + + let mut old_args_rebuilt = Vec::with_capacity(old_param_types.len()); + + for (i, &old_ty) in old_param_types.iter().enumerate() { + let new_arg = llvm::get_param(new_fn, (i + 1) as u32); + + let rebuilt = match cx.type_kind(old_ty) { + TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::Integer => { + let num_bits = scalar_width(cx, old_ty); + + let trunc = builder.trunc(new_arg, cx.type_ix(num_bits)); + builder.bitcast(trunc, old_ty) + } + _ => new_arg, + }; + + old_args_rebuilt.push(rebuilt); + } + + builder.ret_void(); + // Here we map the old arguments to the new arguments, with an offset of 1 to make sure // that we don't use the newly added `%dyn_ptr`. unsafe { - llvm::LLVMRustOffloadMapper(old_fn, new_fn); + llvm::LLVMRustOffloadMapper(old_fn, new_fn, old_args_rebuilt.as_ptr()); } llvm::set_linkage(new_fn, llvm::get_linkage(old_fn)); @@ -707,11 +745,9 @@ pub(crate) unsafe fn llvm_optimize( llvm::set_value_name(new_fn, &name); } - if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) { + if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Device) { let cx = SimpleCx::new(module.module_llvm.llmod(), module.module_llvm.llcx, cgcx.pointer_size); - // For now we only support up to 10 kernels named kernel_0 ... kernel_9, a follow-up PR is - // introducing a proper offload intrinsic to solve this limitation. for func in cx.get_functions() { let offload_kernel = "offload-kernel"; if attributes::has_string_attr(func, offload_kernel) { @@ -721,10 +757,9 @@ pub(crate) unsafe fn llvm_optimize( } } - let mut llvm_profiler = cgcx - .prof + let mut llvm_profiler = prof .llvm_recording_enabled() - .then(|| LlvmSelfProfiler::new(cgcx.prof.get_self_profiler().unwrap())); + .then(|| LlvmSelfProfiler::new(prof.get_self_profiler().unwrap())); let llvm_selfprofiler = llvm_profiler.as_mut().map(|s| s as *mut _ as *mut c_void).unwrap_or(std::ptr::null_mut()); @@ -733,13 +768,20 @@ pub(crate) unsafe fn llvm_optimize( let llvm_plugins = config.llvm_plugins.join(","); + let enzyme_fn = if consider_ad { + let wrapper = llvm::EnzymeWrapper::get_instance(); + wrapper.registerEnzymeAndPassPipeline + } else { + std::ptr::null() + }; + let result = unsafe { llvm::LLVMRustOptimize( module.module_llvm.llmod(), &*module.module_llvm.tm.raw(), to_pass_builder_opt_level(opt_level), opt_stage, - cgcx.opts.cg.linker_plugin_lto.enabled(), + cgcx.use_linker_plugin_lto, config.no_prepopulate_passes, config.verify_llvm_ir, config.lint_llvm_ir, @@ -752,7 +794,7 @@ pub(crate) unsafe fn llvm_optimize( vectorize_loop, config.no_builtins, config.emit_lifetime_markers, - run_enzyme, + enzyme_fn, print_before_enzyme, print_after_enzyme, print_passes, @@ -773,26 +815,96 @@ pub(crate) unsafe fn llvm_optimize( ) }; - if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) { + if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Device) { + let device_path = cgcx.output_filenames.path(OutputType::Object); + let device_dir = device_path.parent().unwrap(); + let device_out = device_dir.join("host.out"); + let device_out_c = path_to_c_string(device_out.as_path()); unsafe { - llvm::LLVMRustBundleImages(module.module_llvm.llmod(), module.module_llvm.tm.raw()); + // 1) Bundle device module into offload image host.out (device TM) + let ok = llvm::LLVMRustBundleImages( + module.module_llvm.llmod(), + module.module_llvm.tm.raw(), + device_out_c.as_ptr(), + ); + if !ok || !device_out.exists() { + dcx.emit_err(crate::errors::OffloadBundleImagesFailed); + } } } + // This assumes that we previously compiled our kernels for a gpu target, which created a + // `host.out` artifact. The user is supposed to provide us with a path to this artifact, we + // don't need any other artifacts from the previous run. We will embed this artifact into our + // LLVM-IR host module, to create a `host.o` ObjectFile, which we will write to disk. + // The last, not yet automated steps uses the `clang-linker-wrapper` to process `host.o`. + if !cgcx.target_is_like_gpu { + if let Some(device_path) = config + .offload + .iter() + .find_map(|o| if let config::Offload::Host(path) = o { Some(path) } else { None }) + { + let device_pathbuf = PathBuf::from(device_path); + if device_pathbuf.is_relative() { + dcx.emit_err(crate::errors::OffloadWithoutAbsPath); + } else if device_pathbuf + .file_name() + .and_then(|n| n.to_str()) + .is_some_and(|n| n != "host.out") + { + dcx.emit_err(crate::errors::OffloadWrongFileName); + } else if !device_pathbuf.exists() { + dcx.emit_err(crate::errors::OffloadNonexistingPath); + } + let host_path = cgcx.output_filenames.path(OutputType::Object); + let host_dir = host_path.parent().unwrap(); + let out_obj = host_dir.join("host.o"); + let host_out_c = path_to_c_string(device_pathbuf.as_path()); + + // 2) Finalize host: lib.bc + host.out -> host.o (host TM) + // We create a full clone of our LLVM host module, since we will embed the device IR + // into it, and this might break caching or incremental compilation otherwise. + let llmod2 = llvm::LLVMCloneModule(module.module_llvm.llmod()); + let ok = + unsafe { llvm::LLVMRustOffloadEmbedBufferInModule(llmod2, host_out_c.as_ptr()) }; + if !ok { + dcx.emit_err(crate::errors::OffloadEmbedFailed); + } + write_output_file( + dcx, + module.module_llvm.tm.raw(), + config.no_builtins, + llmod2, + &out_obj, + None, + llvm::FileType::ObjectFile, + prof, + true, + ); + // We ignore cgcx.save_temps here and unconditionally always keep our `host.out` artifact. + // Otherwise, recompiling the host code would fail since we deleted that device artifact + // in the previous host compilation, which would be confusing at best. + } + } result.into_result().unwrap_or_else(|()| llvm_err(dcx, LlvmError::RunLlvmPasses)) } // Unsafe due to LLVM calls. pub(crate) fn optimize( - cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ) { - let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &*module.name); + let _timer = prof.generic_activity_with_arg("LLVM_module_optimize", &*module.name); + + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); let llcx = &*module.module_llvm.llcx; - let _handlers = DiagnosticHandlers::new(cgcx, dcx, llcx, module, CodegenDiagnosticsStage::Opt); + let _handlers = + DiagnosticHandlers::new(cgcx, shared_emitter, llcx, module, CodegenDiagnosticsStage::Opt); if config.emit_no_opt_bc { let out = cgcx.output_filenames.temp_path_ext_for_cgu( @@ -809,14 +921,13 @@ pub(crate) fn optimize( let opt_stage = match cgcx.lto { Lto::Fat => llvm::OptStage::PreLinkFatLTO, Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO, - _ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO, + _ if cgcx.use_linker_plugin_lto => llvm::OptStage::PreLinkThinLTO, _ => llvm::OptStage::PreLinkNoLTO, }; // If we know that we will later run AD, then we disable vectorization and loop unrolling. // Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD). - let consider_ad = - cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable); + let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable); let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; // The embedded bitcode is used to run LTO/ThinLTO. // The bitcode obtained during the `codegen` phase is no longer suitable for performing LTO. @@ -833,6 +944,7 @@ pub(crate) fn optimize( unsafe { llvm_optimize( cgcx, + prof, dcx, module, thin_lto_buffer.as_mut(), @@ -854,12 +966,12 @@ pub(crate) fn optimize( && let Some(thin_link_bitcode_filename) = bc_summary_out.file_name() { let summary_data = thin_lto_buffer.thin_link_data(); - cgcx.prof.artifact_size( + prof.artifact_size( "llvm_bitcode_summary", thin_link_bitcode_filename.to_string_lossy(), summary_data.len() as u64, ); - let _timer = cgcx.prof.generic_activity_with_arg( + let _timer = prof.generic_activity_with_arg( "LLVM_module_codegen_emit_bitcode_summary", &*module.name, ); @@ -872,20 +984,28 @@ pub(crate) fn optimize( } pub(crate) fn codegen( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - let dcx = cgcx.create_dcx(); + let _timer = prof.generic_activity_with_arg("LLVM_module_codegen", &*module.name); + + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); - let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_codegen", &*module.name); { let llmod = module.module_llvm.llmod(); let llcx = &*module.module_llvm.llcx; let tm = &*module.module_llvm.tm; - let _handlers = - DiagnosticHandlers::new(cgcx, dcx, llcx, &module, CodegenDiagnosticsStage::Codegen); + let _handlers = DiagnosticHandlers::new( + cgcx, + shared_emitter, + llcx, + &module, + CodegenDiagnosticsStage::Codegen, + ); if cgcx.msvc_imps_needed { create_msvc_imps(cgcx, llcx, llmod); @@ -909,18 +1029,17 @@ pub(crate) fn codegen( if config.bitcode_needed() { if config.emit_bc || config.emit_obj == EmitObj::Bitcode { let thin = { - let _timer = cgcx.prof.generic_activity_with_arg( + let _timer = prof.generic_activity_with_arg( "LLVM_module_codegen_make_bitcode", &*module.name, ); ThinBuffer::new(llmod, config.emit_thin_lto) }; let data = thin.data(); - let _timer = cgcx - .prof + let _timer = prof .generic_activity_with_arg("LLVM_module_codegen_emit_bitcode", &*module.name); if let Some(bitcode_filename) = bc_out.file_name() { - cgcx.prof.artifact_size( + prof.artifact_size( "llvm_bitcode", bitcode_filename.to_string_lossy(), data.len() as u64, @@ -932,8 +1051,7 @@ pub(crate) fn codegen( } if config.embed_bitcode() && module.kind == ModuleKind::Regular { - let _timer = cgcx - .prof + let _timer = prof .generic_activity_with_arg("LLVM_module_codegen_embed_bitcode", &*module.name); let thin_bc = module.thin_lto_buffer.as_deref().expect("cannot find embedded bitcode"); @@ -943,7 +1061,7 @@ pub(crate) fn codegen( if config.emit_ir { let _timer = - cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &*module.name); + prof.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &*module.name); let out = cgcx.output_filenames.temp_path_for_cgu( OutputType::LlvmAssembly, &module.name, @@ -981,7 +1099,7 @@ pub(crate) fn codegen( unsafe { llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback) }; if result == llvm::LLVMRustResult::Success { - record_artifact_size(&cgcx.prof, "llvm_ir", &out); + record_artifact_size(prof, "llvm_ir", &out); } result @@ -991,7 +1109,7 @@ pub(crate) fn codegen( if config.emit_asm { let _timer = - cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &*module.name); + prof.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &*module.name); let path = cgcx.output_filenames.temp_path_for_cgu( OutputType::Assembly, &module.name, @@ -1015,16 +1133,15 @@ pub(crate) fn codegen( &path, None, llvm::FileType::AssemblyFile, - &cgcx.prof, + prof, config.verify_llvm_ir, ); } match config.emit_obj { EmitObj::ObjectCode(_) => { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name); + let _timer = + prof.generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name); let dwo_out = cgcx .output_filenames @@ -1051,7 +1168,7 @@ pub(crate) fn codegen( &obj_out, dwo_out, llvm::FileType::ObjectFile, - &cgcx.prof, + prof, config.verify_llvm_ir, ); } @@ -1071,7 +1188,7 @@ pub(crate) fn codegen( EmitObj::None => {} } - record_llvm_cgu_instructions_stats(&cgcx.prof, llmod); + record_llvm_cgu_instructions_stats(prof, &module.name, llmod); } // `.dwo` files are only emitted if: @@ -1120,7 +1237,7 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data: asm } -pub(crate) fn bitcode_section_name(cgcx: &CodegenContext) -> &'static CStr { +pub(crate) fn bitcode_section_name(cgcx: &CodegenContext) -> &'static CStr { if cgcx.target_is_like_darwin { c"__LLVM,__bitcode" } else if cgcx.target_is_like_aix { @@ -1132,7 +1249,7 @@ pub(crate) fn bitcode_section_name(cgcx: &CodegenContext) -> /// Embed the bitcode of an LLVM module for LTO in the LLVM module itself. fn embed_bitcode( - cgcx: &CodegenContext, + cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::Module, bitcode: &[u8], @@ -1216,11 +1333,7 @@ fn embed_bitcode( // when using MSVC linker. We do this only for data, as linker can fix up // code references on its own. // See #26591, #27438 -fn create_msvc_imps( - cgcx: &CodegenContext, - llcx: &llvm::Context, - llmod: &llvm::Module, -) { +fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::Module) { if !cgcx.msvc_imps_needed { return; } @@ -1278,22 +1391,11 @@ fn record_artifact_size( } } -fn record_llvm_cgu_instructions_stats(prof: &SelfProfilerRef, llmod: &llvm::Module) { +fn record_llvm_cgu_instructions_stats(prof: &SelfProfilerRef, name: &str, llmod: &llvm::Module) { if !prof.enabled() { return; } - let raw_stats = - llvm::build_string(|s| unsafe { llvm::LLVMRustModuleInstructionStats(llmod, s) }) - .expect("cannot get module instruction stats"); - - #[derive(serde::Deserialize)] - struct InstructionsStats { - module: String, - total: u64, - } - - let InstructionsStats { module, total } = - serde_json::from_str(&raw_stats).expect("cannot parse llvm cgu instructions stats"); - prof.artifact_size("cgu_instructions", module, total); + let total = unsafe { llvm::LLVMRustModuleInstructionStats(llmod) }; + prof.artifact_size("cgu_instructions", name, total); } diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 6cbddfec4631..d00e70638b45 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -23,13 +23,14 @@ use rustc_middle::dep_graph; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, SanitizerFnAttrs}; use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; -use rustc_session::config::DebugInfo; +use rustc_session::config::{DebugInfo, Offload}; use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; use super::ModuleLlvm; use crate::attributes; use crate::builder::Builder; +use crate::builder::gpu_offload::OffloadGlobals; use crate::context::CodegenCx; use crate::llvm::{self, Value}; @@ -85,6 +86,24 @@ pub(crate) fn compile_codegen_unit( let llvm_module = ModuleLlvm::new(tcx, cgu_name.as_str()); { let mut cx = CodegenCx::new(tcx, cgu, &llvm_module); + + // Declare and store globals shared by all offload kernels + // + // These globals are left in the LLVM-IR host module so all kernels can access them. + // They are necessary for correct offload execution. We do this here to simplify the + // `offload` intrinsic, avoiding the need for tracking whether it's the first + // intrinsic call or not. + let has_host_offload = cx + .sess() + .opts + .unstable_opts + .offload + .iter() + .any(|o| matches!(o, Offload::Host(_) | Offload::Test)); + if has_host_offload && !cx.sess().target.is_like_gpu { + cx.offload_globals.replace(Some(OffloadGlobals::declare(&cx))); + } + let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx); for &(mono_item, data) in &mono_items { mono_item.predefine::>( diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 3442abece2f7..4ffc836f5559 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -97,6 +97,21 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { GenericBuilder { llbuilder, cx: scx } } + pub(crate) fn append_block( + cx: &'a GenericCx<'ll, CX>, + llfn: &'ll Value, + name: &str, + ) -> &'ll BasicBlock { + unsafe { + let name = SmallCStr::new(name); + llvm::LLVMAppendBasicBlockInContext(cx.llcx(), llfn, name.as_ptr()) + } + } + + pub(crate) fn trunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { + unsafe { llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED) } + } + pub(crate) fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED) } } @@ -173,19 +188,6 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { load } } - - fn memset(&mut self, ptr: &'ll Value, fill_byte: &'ll Value, size: &'ll Value, align: Align) { - unsafe { - llvm::LLVMRustBuildMemSet( - self.llbuilder, - ptr, - align.bytes() as c_uint, - fill_byte, - size, - false, - ); - } - } } /// Empty string, to be used where LLVM expects an instruction name, indicating @@ -613,6 +615,25 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } + fn scalable_alloca(&mut self, elt: u64, align: Align, element_ty: Ty<'_>) -> Self::Value { + let mut bx = Builder::with_cx(self.cx); + bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); + let llvm_ty = match element_ty.kind() { + ty::Bool => bx.type_i1(), + ty::Int(int_ty) => self.cx.type_int_from_ty(*int_ty), + ty::Uint(uint_ty) => self.cx.type_uint_from_ty(*uint_ty), + ty::Float(float_ty) => self.cx.type_float_from_ty(*float_ty), + _ => unreachable!("scalable vectors can only contain a bool, int, uint or float"), + }; + + unsafe { + let ty = llvm::LLVMScalableVectorType(llvm_ty, elt.try_into().unwrap()); + let alloca = llvm::LLVMBuildAlloca(&bx.llbuilder, ty, UNNAMED); + llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); + alloca + } + } + fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value { unsafe { let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED); @@ -1363,12 +1384,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn call( &mut self, llty: &'ll Type, - fn_call_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, args: &[&'ll Value], funclet: Option<&Funclet<'ll>>, - instance: Option>, + callee_instance: Option>, ) -> &'ll Value { debug!("call {:?} with args ({:?})", llfn, args); @@ -1380,10 +1401,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } // Emit CFI pointer type membership test - self.cfi_type_test(fn_call_attrs, fn_abi, instance, llfn); + self.cfi_type_test(caller_attrs, fn_abi, callee_instance, llfn); // Emit KCFI operand bundle - let kcfi_bundle = self.kcfi_operand_bundle(fn_call_attrs, fn_abi, instance, llfn); + let kcfi_bundle = self.kcfi_operand_bundle(caller_attrs, fn_abi, callee_instance, llfn); if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.as_ref()) { bundles.push(kcfi_bundle); } @@ -1401,17 +1422,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { ) }; - if let Some(instance) = instance { + if let Some(callee_instance) = callee_instance { // Attributes on the function definition being called - let fn_defn_attrs = self.cx.tcx.codegen_fn_attrs(instance.def_id()); - if let Some(fn_call_attrs) = fn_call_attrs + let callee_attrs = self.cx.tcx.codegen_fn_attrs(callee_instance.def_id()); + if let Some(caller_attrs) = caller_attrs // If there is an inline attribute and a target feature that matches // we will add the attribute to the callsite otherwise we'll omit // this and not add the attribute to prevent soundness issues. - && let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, instance) + && let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, callee_instance) && self.cx.tcx.is_target_feature_call_safe( - &fn_defn_attrs.target_features, - &fn_call_attrs.target_features.iter().cloned().chain( + &callee_attrs.target_features, + &caller_attrs.target_features.iter().cloned().chain( self.cx.tcx.sess.target_features.iter().map(|feat| TargetFeature { name: *feat, kind: TargetFeatureKind::Implied, @@ -1436,14 +1457,15 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn tail_call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ) { - let call = self.call(llty, fn_attrs, Some(fn_abi), llfn, args, funclet, instance); + let call = + self.call(llty, caller_attrs, Some(fn_abi), llfn, args, funclet, callee_instance); llvm::LLVMSetTailCallKind(call, llvm::TailCallKind::MustTail); match &fn_abi.ret.mode { @@ -1686,7 +1708,7 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { ret.expect("LLVM does not have support for catchret") } - fn check_call<'b>( + pub(crate) fn check_call<'b>( &mut self, typ: &str, fn_ty: &'ll Type, @@ -1754,6 +1776,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { } if crate::llvm_util::get_version() >= (22, 0, 0) { + // LLVM 22 requires the lifetime intrinsic to act directly on the alloca, + // there can't be an addrspacecast in between. + let ptr = unsafe { llvm::LLVMRustStripPointerCasts(ptr) }; self.call_intrinsic(intrinsic, &[self.val_ty(ptr)], &[ptr]); } else { self.call_intrinsic(intrinsic, &[self.val_ty(ptr)], &[self.cx.const_u64(size), ptr]); diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 5d1ddd057d88..a60e2d1f0ab0 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -1,18 +1,189 @@ use std::ffi::CString; +use bitflags::Flags; use llvm::Linkage::*; use rustc_abi::Align; -use rustc_codegen_ssa::traits::BaseTypeCodegenMethods; -use rustc_middle::ty::offload_meta::OffloadMetadata; +use rustc_codegen_ssa::common::TypeKind; +use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; +use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; +use rustc_middle::bug; +use rustc_middle::ty::offload_meta::{MappingFlags, OffloadMetadata}; -use crate::builder::SBuilder; +use crate::builder::Builder; +use crate::common::CodegenCx; use crate::llvm::AttributePlace::Function; -use crate::llvm::{self, BasicBlock, Linkage, Type, Value}; +use crate::llvm::{self, Linkage, Type, Value}; use crate::{SimpleCx, attributes}; +// LLVM kernel-independent globals required for offloading +pub(crate) struct OffloadGlobals<'ll> { + pub launcher_fn: &'ll llvm::Value, + pub launcher_ty: &'ll llvm::Type, + + pub kernel_args_ty: &'ll llvm::Type, + + pub offload_entry_ty: &'ll llvm::Type, + + pub begin_mapper: &'ll llvm::Value, + pub end_mapper: &'ll llvm::Value, + pub mapper_fn_ty: &'ll llvm::Type, + + pub ident_t_global: &'ll llvm::Value, +} + +impl<'ll> OffloadGlobals<'ll> { + pub(crate) fn declare(cx: &CodegenCx<'ll, '_>) -> Self { + let (launcher_fn, launcher_ty) = generate_launcher(cx); + let kernel_args_ty = KernelArgsTy::new_decl(cx); + let offload_entry_ty = TgtOffloadEntry::new_decl(cx); + let (begin_mapper, _, end_mapper, mapper_fn_ty) = gen_tgt_data_mappers(cx); + let ident_t_global = generate_at_one(cx); + + // We want LLVM's openmp-opt pass to pick up and optimize this module, since it covers both + // openmp and offload optimizations. + llvm::add_module_flag_u32(cx.llmod(), llvm::ModuleFlagMergeBehavior::Max, "openmp", 51); + + OffloadGlobals { + launcher_fn, + launcher_ty, + kernel_args_ty, + offload_entry_ty, + begin_mapper, + end_mapper, + mapper_fn_ty, + ident_t_global, + } + } +} + +// We need to register offload before using it. We also should unregister it once we are done, for +// good measures. Previously we have done so before and after each individual offload intrinsic +// call, but that comes at a performance cost. The repeated (un)register calls might also confuse +// the LLVM ompOpt pass, which tries to move operations to a better location. The easiest solution, +// which we copy from clang, is to just have those two calls once, in the global ctor/dtor section +// of the final binary. +pub(crate) fn register_offload<'ll>(cx: &CodegenCx<'ll, '_>) { + // First we check quickly whether we already have done our setup, in which case we return early. + // Shouldn't be needed for correctness. + let register_lib_name = "__tgt_register_lib"; + if cx.get_function(register_lib_name).is_some() { + return; + } + + let reg_lib_decl = cx.type_func(&[cx.type_ptr()], cx.type_void()); + let register_lib = declare_offload_fn(&cx, register_lib_name, reg_lib_decl); + let unregister_lib = declare_offload_fn(&cx, "__tgt_unregister_lib", reg_lib_decl); + + let ptr_null = cx.const_null(cx.type_ptr()); + let const_struct = cx.const_struct(&[cx.get_const_i32(0), ptr_null, ptr_null, ptr_null], false); + let omp_descriptor = + add_global(cx, ".omp_offloading.descriptor", const_struct, InternalLinkage); + // @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries } + // @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 0, ptr null, ptr null, ptr null } + + let atexit = cx.type_func(&[cx.type_ptr()], cx.type_i32()); + let atexit_fn = declare_offload_fn(cx, "atexit", atexit); + + // FIXME(offload): Drop this, once we fully automated our offload compilation pipeline, since + // LLVM will initialize them for us if it sees gpu kernels being registered. + let init_ty = cx.type_func(&[], cx.type_void()); + let init_rtls = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); + + let desc_ty = cx.type_func(&[], cx.type_void()); + let reg_name = ".omp_offloading.descriptor_reg"; + let unreg_name = ".omp_offloading.descriptor_unreg"; + let desc_reg_fn = declare_offload_fn(cx, reg_name, desc_ty); + let desc_unreg_fn = declare_offload_fn(cx, unreg_name, desc_ty); + llvm::set_linkage(desc_reg_fn, InternalLinkage); + llvm::set_linkage(desc_unreg_fn, InternalLinkage); + llvm::set_section(desc_reg_fn, c".text.startup"); + llvm::set_section(desc_unreg_fn, c".text.startup"); + + // define internal void @.omp_offloading.descriptor_reg() section ".text.startup" { + // entry: + // call void @__tgt_register_lib(ptr @.omp_offloading.descriptor) + // call void @__tgt_init_all_rtls() + // %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg) + // ret void + // } + let bb = Builder::append_block(cx, desc_reg_fn, "entry"); + let mut a = Builder::build(cx, bb); + a.call(reg_lib_decl, None, None, register_lib, &[omp_descriptor], None, None); + a.call(init_ty, None, None, init_rtls, &[], None, None); + a.call(atexit, None, None, atexit_fn, &[desc_unreg_fn], None, None); + a.ret_void(); + + // define internal void @.omp_offloading.descriptor_unreg() section ".text.startup" { + // entry: + // call void @__tgt_unregister_lib(ptr @.omp_offloading.descriptor) + // ret void + // } + let bb = Builder::append_block(cx, desc_unreg_fn, "entry"); + let mut a = Builder::build(cx, bb); + a.call(reg_lib_decl, None, None, unregister_lib, &[omp_descriptor], None, None); + a.ret_void(); + + // @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }] + let args = vec![cx.get_const_i32(101), desc_reg_fn, ptr_null]; + let const_struct = cx.const_struct(&args, false); + let arr = cx.const_array(cx.val_ty(const_struct), &[const_struct]); + add_global(cx, "llvm.global_ctors", arr, AppendingLinkage); +} + +pub(crate) struct OffloadKernelDims<'ll> { + num_workgroups: &'ll Value, + threads_per_block: &'ll Value, + workgroup_dims: &'ll Value, + thread_dims: &'ll Value, +} + +impl<'ll> OffloadKernelDims<'ll> { + pub(crate) fn from_operands<'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, + workgroup_op: &OperandRef<'tcx, &'ll llvm::Value>, + thread_op: &OperandRef<'tcx, &'ll llvm::Value>, + ) -> Self { + let cx = builder.cx; + let arr_ty = cx.type_array(cx.type_i32(), 3); + let four = Align::from_bytes(4).unwrap(); + + let OperandValue::Ref(place) = workgroup_op.val else { + bug!("expected array operand by reference"); + }; + let workgroup_val = builder.load(arr_ty, place.llval, four); + + let OperandValue::Ref(place) = thread_op.val else { + bug!("expected array operand by reference"); + }; + let thread_val = builder.load(arr_ty, place.llval, four); + + fn mul_dim3<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, + arr: &'ll Value, + ) -> &'ll Value { + let x = builder.extract_value(arr, 0); + let y = builder.extract_value(arr, 1); + let z = builder.extract_value(arr, 2); + + let xy = builder.mul(x, y); + builder.mul(xy, z) + } + + let num_workgroups = mul_dim3(builder, workgroup_val); + let threads_per_block = mul_dim3(builder, thread_val); + + OffloadKernelDims { + workgroup_dims: workgroup_val, + thread_dims: thread_val, + num_workgroups, + threads_per_block, + } + } +} + // ; Function Attrs: nounwind // declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) #2 -fn generate_launcher<'ll>(cx: &'ll SimpleCx<'_>) -> (&'ll llvm::Value, &'ll llvm::Type) { +fn generate_launcher<'ll>(cx: &CodegenCx<'ll, '_>) -> (&'ll llvm::Value, &'ll llvm::Type) { let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); let ti32 = cx.type_i32(); @@ -30,7 +201,7 @@ fn generate_launcher<'ll>(cx: &'ll SimpleCx<'_>) -> (&'ll llvm::Value, &'ll llvm // @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8 // FIXME(offload): @0 should include the file name (e.g. lib.rs) in which the function to be // offloaded was defined. -fn generate_at_one<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Value { +pub(crate) fn generate_at_one<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll llvm::Value { let unknown_txt = ";unknown;unknown;0;0;;"; let c_entry_name = CString::new(unknown_txt).unwrap(); let c_val = c_entry_name.as_bytes_with_nul(); @@ -68,7 +239,7 @@ pub(crate) struct TgtOffloadEntry { } impl TgtOffloadEntry { - pub(crate) fn new_decl<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Type { + pub(crate) fn new_decl<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll llvm::Type { let offload_entry_ty = cx.type_named_struct("struct.__tgt_offload_entry"); let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); @@ -82,7 +253,7 @@ impl TgtOffloadEntry { } fn new<'ll>( - cx: &'ll SimpleCx<'_>, + cx: &CodegenCx<'ll, '_>, region_id: &'ll Value, llglobal: &'ll Value, ) -> [&'ll Value; 9] { @@ -126,7 +297,7 @@ impl KernelArgsTy { const OFFLOAD_VERSION: u64 = 3; const FLAGS: u64 = 0; const TRIPCOUNT: u64 = 0; - fn new_decl<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll Type { + fn new_decl<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Type { let kernel_arguments_ty = cx.type_named_struct("struct.__tgt_kernel_arguments"); let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); @@ -140,17 +311,17 @@ impl KernelArgsTy { kernel_arguments_ty } - fn new<'ll>( - cx: &'ll SimpleCx<'_>, + fn new<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, num_args: u64, memtransfer_types: &'ll Value, geps: [&'ll Value; 3], + workgroup_dims: &'ll Value, + thread_dims: &'ll Value, ) -> [(Align, &'ll Value); 13] { let four = Align::from_bytes(4).expect("4 Byte alignment should work"); let eight = Align::EIGHT; - let ti32 = cx.type_i32(); - let ci32_0 = cx.get_const_i32(0); [ (four, cx.get_const_i32(KernelArgsTy::OFFLOAD_VERSION)), (four, cx.get_const_i32(num_args)), @@ -163,23 +334,25 @@ impl KernelArgsTy { (eight, cx.const_null(cx.type_ptr())), // dbg (eight, cx.get_const_i64(KernelArgsTy::TRIPCOUNT)), (eight, cx.get_const_i64(KernelArgsTy::FLAGS)), - (four, cx.const_array(ti32, &[cx.get_const_i32(2097152), ci32_0, ci32_0])), - (four, cx.const_array(ti32, &[cx.get_const_i32(256), ci32_0, ci32_0])), + (four, workgroup_dims), + (four, thread_dims), (four, cx.get_const_i32(0)), ] } } // Contains LLVM values needed to manage offloading for a single kernel. -pub(crate) struct OffloadKernelData<'ll> { +#[derive(Copy, Clone)] +pub(crate) struct OffloadKernelGlobals<'ll> { pub offload_sizes: &'ll llvm::Value, - pub memtransfer_types: &'ll llvm::Value, + pub memtransfer_begin: &'ll llvm::Value, + pub memtransfer_kernel: &'ll llvm::Value, + pub memtransfer_end: &'ll llvm::Value, pub region_id: &'ll llvm::Value, - pub offload_entry: &'ll llvm::Value, } fn gen_tgt_data_mappers<'ll>( - cx: &'ll SimpleCx<'_>, + cx: &CodegenCx<'ll, '_>, ) -> (&'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Type) { let tptr = cx.type_ptr(); let ti64 = cx.type_i64(); @@ -241,40 +414,58 @@ pub(crate) fn add_global<'ll>( // mapped to/from the gpu. It also returns a region_id with the name of this kernel, to be // concatenated into the list of region_ids. pub(crate) fn gen_define_handling<'ll>( - cx: &SimpleCx<'ll>, - offload_entry_ty: &'ll llvm::Type, + cx: &CodegenCx<'ll, '_>, metadata: &[OffloadMetadata], - types: &[&Type], - symbol: &str, -) -> OffloadKernelData<'ll> { - // It seems like non-pointer values are automatically mapped. So here, we focus on pointer (or - // reference) types. - let ptr_meta = types.iter().zip(metadata).filter_map(|(&x, meta)| match cx.type_kind(x) { - rustc_codegen_ssa::common::TypeKind::Pointer => Some(meta), - _ => None, - }); + symbol: String, + offload_globals: &OffloadGlobals<'ll>, +) -> OffloadKernelGlobals<'ll> { + if let Some(entry) = cx.offload_kernel_cache.borrow().get(&symbol) { + return *entry; + } - // FIXME(Sa4dUs): add `OMP_MAP_TARGET_PARAM = 0x20` only if necessary - let (ptr_sizes, ptr_transfer): (Vec<_>, Vec<_>) = - ptr_meta.map(|m| (m.payload_size, m.mode.bits() | 0x20)).unzip(); + let offload_entry_ty = offload_globals.offload_entry_ty; - let offload_sizes = add_priv_unnamed_arr(&cx, &format!(".offload_sizes.{symbol}"), &ptr_sizes); - // Here we figure out whether something needs to be copied to the gpu (=1), from the gpu (=2), - // or both to and from the gpu (=3). Other values shouldn't affect us for now. - // A non-mutable reference or pointer will be 1, an array that's not read, but fully overwritten - // will be 2. For now, everything is 3, until we have our frontend set up. - // 1+2+32: 1 (MapTo), 2 (MapFrom), 32 (Add one extra input ptr per function, to be used later). - let memtransfer_types = - add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}"), &ptr_transfer); + let (sizes, transfer): (Vec<_>, Vec<_>) = + metadata.iter().map(|m| (m.payload_size, m.mode)).unzip(); + // Our begin mapper should only see simplified information about which args have to be + // transferred to the device, the end mapper only about which args should be transferred back. + // Any information beyond that makes it harder for LLVM's opt pass to evaluate whether it can + // safely move (=optimize) the LLVM-IR location of this data transfer. Only the mapping types + // mentioned below are handled, so make sure that we don't generate any other ones. + let handled_mappings = MappingFlags::TO + | MappingFlags::FROM + | MappingFlags::TARGET_PARAM + | MappingFlags::LITERAL + | MappingFlags::IMPLICIT; + for arg in &transfer { + debug_assert!(!arg.contains_unknown_bits()); + debug_assert!(handled_mappings.contains(*arg)); + } + + let valid_begin_mappings = MappingFlags::TO | MappingFlags::LITERAL | MappingFlags::IMPLICIT; + let transfer_to: Vec = + transfer.iter().map(|m| m.intersection(valid_begin_mappings).bits()).collect(); + let transfer_from: Vec = + transfer.iter().map(|m| m.intersection(MappingFlags::FROM).bits()).collect(); + // FIXME(offload): add `OMP_MAP_TARGET_PARAM = 0x20` only if necessary + let transfer_kernel = vec![MappingFlags::TARGET_PARAM.bits(); transfer_to.len()]; + + let offload_sizes = add_priv_unnamed_arr(&cx, &format!(".offload_sizes.{symbol}"), &sizes); + let memtransfer_begin = + add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}.begin"), &transfer_to); + let memtransfer_kernel = + add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}.kernel"), &transfer_kernel); + let memtransfer_end = + add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{symbol}.end"), &transfer_from); // Next: For each function, generate these three entries. A weak constant, // the llvm.rodata entry name, and the llvm_offload_entries value let name = format!(".{symbol}.region_id"); let initializer = cx.get_const_i8(0); - let region_id = add_unnamed_global(&cx, &name, initializer, WeakAnyLinkage); + let region_id = add_global(&cx, &name, initializer, WeakAnyLinkage); - let c_entry_name = CString::new(symbol).unwrap(); + let c_entry_name = CString::new(symbol.clone()).unwrap(); let c_val = c_entry_name.as_bytes_with_nul(); let offload_entry_name = format!(".offloading.entry_name.{symbol}"); @@ -298,11 +489,26 @@ pub(crate) fn gen_define_handling<'ll>( let c_section_name = CString::new("llvm_offload_entries").unwrap(); llvm::set_section(offload_entry, &c_section_name); - OffloadKernelData { offload_sizes, memtransfer_types, region_id, offload_entry } + cx.add_compiler_used_global(offload_entry); + + let result = OffloadKernelGlobals { + offload_sizes, + memtransfer_begin, + memtransfer_kernel, + memtransfer_end, + region_id, + }; + + // FIXME(Sa4dUs): use this global for constant offload sizes + cx.add_compiler_used_global(result.offload_sizes); + + cx.offload_kernel_cache.borrow_mut().insert(symbol, result); + + result } fn declare_offload_fn<'ll>( - cx: &'ll SimpleCx<'_>, + cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll llvm::Type, ) -> &'ll llvm::Value { @@ -316,13 +522,25 @@ fn declare_offload_fn<'ll>( ) } +pub(crate) fn scalar_width<'ll>(cx: &'ll SimpleCx<'_>, ty: &'ll Type) -> u64 { + match cx.type_kind(ty) { + TypeKind::Half + | TypeKind::Float + | TypeKind::Double + | TypeKind::X86_FP80 + | TypeKind::FP128 + | TypeKind::PPC_FP128 => cx.float_width(ty) as u64, + TypeKind::Integer => cx.int_width(ty), + other => bug!("scalar_width was called on a non scalar type {other:?}"), + } +} + // For each kernel *call*, we now use some of our previous declared globals to move data to and from // the gpu. For now, we only handle the data transfer part of it. // If two consecutive kernels use the same memory, we still move it to the host and back to the gpu. // Since in our frontend users (by default) don't have to specify data transfer, this is something -// we should optimize in the future! We also assume that everything should be copied back and forth, -// but sometimes we can directly zero-allocate on the device and only move back, or if something is -// immutable, we might only copy it to the device, but not back. +// we should optimize in the future! In some cases we can directly zero-allocate on the device and +// only move data back, or if something is immutable, we might only copy it to the device. // // Current steps: // 0. Alloca some variables for the following steps @@ -335,54 +553,41 @@ fn declare_offload_fn<'ll>( // 4. set insert point after kernel call. // 5. generate all the GEPS and stores, to be used in 6) // 6. generate __tgt_target_data_end calls to move data from the GPU -pub(crate) fn gen_call_handling<'ll>( - cx: &SimpleCx<'ll>, - bb: &BasicBlock, - offload_data: &OffloadKernelData<'ll>, +pub(crate) fn gen_call_handling<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, + offload_data: &OffloadKernelGlobals<'ll>, args: &[&'ll Value], types: &[&Type], metadata: &[OffloadMetadata], + offload_globals: &OffloadGlobals<'ll>, + offload_dims: &OffloadKernelDims<'ll>, ) { - let OffloadKernelData { offload_sizes, offload_entry, memtransfer_types, region_id } = - offload_data; - let (tgt_decl, tgt_target_kernel_ty) = generate_launcher(&cx); - // %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } - let tptr = cx.type_ptr(); - let ti32 = cx.type_i32(); - let tgt_bin_desc_ty = vec![ti32, tptr, tptr, tptr]; - let tgt_bin_desc = cx.type_named_struct("struct.__tgt_bin_desc"); - cx.set_struct_body(tgt_bin_desc, &tgt_bin_desc_ty, false); + let cx = builder.cx; + let OffloadKernelGlobals { + memtransfer_begin, + memtransfer_kernel, + memtransfer_end, + region_id, + .. + } = offload_data; + let OffloadKernelDims { num_workgroups, threads_per_block, workgroup_dims, thread_dims } = + offload_dims; - let tgt_kernel_decl = KernelArgsTy::new_decl(&cx); - let (begin_mapper_decl, _, end_mapper_decl, fn_ty) = gen_tgt_data_mappers(&cx); + let tgt_decl = offload_globals.launcher_fn; + let tgt_target_kernel_ty = offload_globals.launcher_ty; - let mut builder = SBuilder::build(cx, bb); + let tgt_kernel_decl = offload_globals.kernel_args_ty; + let begin_mapper_decl = offload_globals.begin_mapper; + let end_mapper_decl = offload_globals.end_mapper; + let fn_ty = offload_globals.mapper_fn_ty; let num_args = types.len() as u64; - let ip = unsafe { llvm::LLVMRustGetInsertPoint(&builder.llbuilder) }; - - // FIXME(Sa4dUs): dummy loads are a temp workaround, we should find a proper way to prevent these - // variables from being optimized away - for val in [offload_sizes, offload_entry] { - unsafe { - let dummy = llvm::LLVMBuildLoad2( - &builder.llbuilder, - llvm::LLVMTypeOf(val), - val, - b"dummy\0".as_ptr() as *const _, - ); - llvm::LLVMSetVolatile(dummy, llvm::TRUE); - } - } + let bb = builder.llbb(); // Step 0) - // %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } - // %6 = alloca %struct.__tgt_bin_desc, align 8 - let llfn = unsafe { llvm::LLVMGetBasicBlockParent(bb) }; unsafe { - llvm::LLVMRustPositionBuilderPastAllocas(&builder.llbuilder, llfn); + llvm::LLVMRustPositionBuilderPastAllocas(&builder.llbuilder, builder.llfn()); } - let tgt_bin_desc_alloca = builder.direct_alloca(tgt_bin_desc, Align::EIGHT, "EmptyDesc"); let ty = cx.type_array(cx.type_ptr(), num_args); // Baseptr are just the input pointer to the kernel, stored in a local alloca @@ -398,32 +603,45 @@ pub(crate) fn gen_call_handling<'ll>( // Step 1) unsafe { - llvm::LLVMRustRestoreInsertPoint(&builder.llbuilder, ip); + llvm::LLVMPositionBuilderAtEnd(&builder.llbuilder, bb); } - builder.memset(tgt_bin_desc_alloca, cx.get_const_i8(0), cx.get_const_i64(32), Align::EIGHT); // Now we allocate once per function param, a copy to be passed to one of our maps. let mut vals = vec![]; let mut geps = vec![]; let i32_0 = cx.get_const_i32(0); for &v in args { - let gep = builder.inbounds_gep(cx.type_f32(), v, &[i32_0]); - vals.push(v); + let ty = cx.val_ty(v); + let ty_kind = cx.type_kind(ty); + let (base_val, gep_base) = match ty_kind { + TypeKind::Pointer => (v, v), + TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::Integer => { + // FIXME(Sa4dUs): check for `f128` support, latest NVIDIA cards support it + let num_bits = scalar_width(cx, ty); + + let bb = builder.llbb(); + unsafe { + llvm::LLVMRustPositionBuilderPastAllocas(builder.llbuilder, builder.llfn()); + } + let addr = builder.direct_alloca(cx.type_i64(), Align::EIGHT, "addr"); + unsafe { + llvm::LLVMPositionBuilderAtEnd(builder.llbuilder, bb); + } + + let cast = builder.bitcast(v, cx.type_ix(num_bits)); + let value = builder.zext(cast, cx.type_i64()); + builder.store(value, addr, Align::EIGHT); + (value, addr) + } + other => bug!("offload does not support {other:?}"), + }; + + let gep = builder.inbounds_gep(cx.type_f32(), gep_base, &[i32_0]); + + vals.push(base_val); geps.push(gep); } - let mapper_fn_ty = cx.type_func(&[cx.type_ptr()], cx.type_void()); - let register_lib_decl = declare_offload_fn(&cx, "__tgt_register_lib", mapper_fn_ty); - let unregister_lib_decl = declare_offload_fn(&cx, "__tgt_unregister_lib", mapper_fn_ty); - let init_ty = cx.type_func(&[], cx.type_void()); - let init_rtls_decl = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); - - // FIXME(offload): Later we want to add them to the wrapper code, rather than our main function. - // call void @__tgt_register_lib(ptr noundef %6) - builder.call(mapper_fn_ty, register_lib_decl, &[tgt_bin_desc_alloca], None); - // call void @__tgt_init_all_rtls() - builder.call(init_ty, init_rtls_decl, &[], None); - for i in 0..num_args { let idx = cx.get_const_i32(i); let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, idx]); @@ -437,15 +655,15 @@ pub(crate) fn gen_call_handling<'ll>( // For now we have a very simplistic indexing scheme into our // offload_{baseptrs,ptrs,sizes}. We will probably improve this along with our gpu frontend pr. - fn get_geps<'a, 'll>( - builder: &mut SBuilder<'a, 'll>, - cx: &'ll SimpleCx<'ll>, + fn get_geps<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, ty: &'ll Type, ty2: &'ll Type, a1: &'ll Value, a2: &'ll Value, a4: &'ll Value, ) -> [&'ll Value; 3] { + let cx = builder.cx; let i32_0 = cx.get_const_i32(0); let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, i32_0]); @@ -454,9 +672,8 @@ pub(crate) fn gen_call_handling<'ll>( [gep1, gep2, gep3] } - fn generate_mapper_call<'a, 'll>( - builder: &mut SBuilder<'a, 'll>, - cx: &'ll SimpleCx<'ll>, + fn generate_mapper_call<'ll, 'tcx>( + builder: &mut Builder<'_, 'll, 'tcx>, geps: [&'ll Value; 3], o_type: &'ll Value, fn_to_call: &'ll Value, @@ -464,28 +681,29 @@ pub(crate) fn gen_call_handling<'ll>( num_args: u64, s_ident_t: &'ll Value, ) { + let cx = builder.cx; let nullptr = cx.const_null(cx.type_ptr()); let i64_max = cx.get_const_i64(u64::MAX); let num_args = cx.get_const_i32(num_args); let args = vec![s_ident_t, i64_max, num_args, geps[0], geps[1], geps[2], o_type, nullptr, nullptr]; - builder.call(fn_ty, fn_to_call, &args, None); + builder.call(fn_ty, None, None, fn_to_call, &args, None, None); } // Step 2) - let s_ident_t = generate_at_one(&cx); - let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4); + let s_ident_t = offload_globals.ident_t_global; + let geps = get_geps(builder, ty, ty2, a1, a2, a4); generate_mapper_call( - &mut builder, - &cx, + builder, geps, - memtransfer_types, + memtransfer_begin, begin_mapper_decl, fn_ty, num_args, s_ident_t, ); - let values = KernelArgsTy::new(&cx, num_args, memtransfer_types, geps); + let values = + KernelArgsTy::new(&cx, num_args, memtransfer_kernel, geps, workgroup_dims, thread_dims); // Step 3) // Here we fill the KernelArgsTy, see the documentation above @@ -498,29 +716,23 @@ pub(crate) fn gen_call_handling<'ll>( s_ident_t, // FIXME(offload) give users a way to select which GPU to use. cx.get_const_i64(u64::MAX), // MAX == -1. - // FIXME(offload): Don't hardcode the numbers of threads in the future. - cx.get_const_i32(2097152), - cx.get_const_i32(256), + num_workgroups, + threads_per_block, region_id, a5, ]; - builder.call(tgt_target_kernel_ty, tgt_decl, &args, None); + builder.call(tgt_target_kernel_ty, None, None, tgt_decl, &args, None, None); // %41 = call i32 @__tgt_target_kernel(ptr @1, i64 -1, i32 2097152, i32 256, ptr @.kernel_1.region_id, ptr %kernel_args) // Step 4) - let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4); + let geps = get_geps(builder, ty, ty2, a1, a2, a4); generate_mapper_call( - &mut builder, - &cx, + builder, geps, - memtransfer_types, + memtransfer_end, end_mapper_decl, fn_ty, num_args, s_ident_t, ); - - builder.call(mapper_fn_ty, unregister_lib_decl, &[tgt_bin_desc_alloca], None); - - drop(builder); } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index b0cf9925019d..f2261ab79340 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -124,6 +124,10 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn const_null(&self, t: &'ll Type) -> &'ll Value { unsafe { llvm::LLVMConstNull(t) } } + + pub(crate) fn const_struct(&self, elts: &[&'ll Value], packed: bool) -> &'ll Value { + struct_in_context(self.llcx(), elts, packed) + } } impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> { diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 08c53179bc14..2b04f81c267f 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -187,6 +187,10 @@ fn check_and_apply_linkage<'ll, 'tcx>( }; llvm::set_linkage(g1, base::linkage_to_llvm(linkage)); + // Normally this is done in `get_static_inner`, but when as we generate an internal global, + // it will apply the dso_local to the internal global instead, so do it here, too. + cx.assume_dso_local(g1, true); + // Declare an internal global `extern_with_linkage_foo` which // is initialized with the address of `foo`. If `foo` is // discarded during linking (for example, if `foo` has weak diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 6caf60e3cc41..2760683dad9d 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -35,6 +35,7 @@ use smallvec::SmallVec; use crate::abi::to_llvm_calling_convention; use crate::back::write::to_llvm_code_model; +use crate::builder::gpu_offload::{OffloadGlobals, OffloadKernelGlobals}; use crate::callee::get_fn; use crate::debuginfo::metadata::apply_vcall_visibility_metadata; use crate::llvm::{self, Metadata, MetadataKindId, Module, Type, Value}; @@ -100,6 +101,8 @@ pub(crate) struct FullCx<'ll, 'tcx> { /// Cache instances of monomorphic and polymorphic items pub instances: RefCell, &'ll Value>>, + /// Cache instances of intrinsics + pub intrinsic_instances: RefCell, &'ll Value>>, /// Cache generated vtables pub vtables: RefCell, Option>), &'ll Value>>, /// Cache of constant strings, @@ -156,6 +159,12 @@ pub(crate) struct FullCx<'ll, 'tcx> { /// Cache of Objective-C selector references pub objc_selrefs: RefCell>, + + /// Globals shared by the offloading runtime + pub offload_globals: RefCell>>, + + /// Cache of kernel-specific globals + pub offload_kernel_cache: RefCell>>, } fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode { @@ -202,6 +211,21 @@ pub(crate) unsafe fn create_module<'ll>( // LLVM 22 updated the NVPTX layout to indicate 256-bit vector load/store: https://github.com/llvm/llvm-project/pull/155198 target_data_layout = target_data_layout.replace("-i256:256", ""); } + if sess.target.arch == Arch::PowerPC64 { + // LLVM 22 updated the ABI alignment for double on AIX: https://github.com/llvm/llvm-project/pull/144673 + target_data_layout = target_data_layout.replace("-f64:32:64", ""); + } + if sess.target.arch == Arch::AmdGpu { + // LLVM 22 specified ELF mangling in the amdgpu data layout: + // https://github.com/llvm/llvm-project/pull/163011 + target_data_layout = target_data_layout.replace("-m:e", ""); + } + } + if llvm_version < (23, 0, 0) { + if sess.target.arch == Arch::S390x { + // LLVM 23 updated the s390x layout to specify the stack alignment: https://github.com/llvm/llvm-project/pull/176041 + target_data_layout = target_data_layout.replace("-S64", ""); + } } // Ensure the data-layout values hardcoded remain the defaults. @@ -620,6 +644,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { tls_model, codegen_unit, instances: Default::default(), + intrinsic_instances: Default::default(), vtables: Default::default(), const_str_cache: Default::default(), const_globals: Default::default(), @@ -639,6 +664,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { objc_class_t: Cell::new(None), objc_classrefs: Default::default(), objc_selrefs: Default::default(), + offload_globals: Default::default(), + offload_kernel_cache: Default::default(), }, PhantomData, ) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index b3a11f8b12bf..b27b1a88f133 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -1,15 +1,13 @@ -use std::assert_matches::assert_matches; use std::sync::Arc; use itertools::Itertools; use rustc_abi::Align; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; use rustc_middle::ty::TyCtxt; -use rustc_session::RemapFileNameExt; -use rustc_session::config::RemapPathScopeComponents; -use rustc_span::{SourceFile, StableSourceFileId}; +use rustc_span::{FileName, RemapPathScopeComponents, SourceFile, StableSourceFileId}; use tracing::debug; use crate::common::CodegenCx; @@ -127,10 +125,19 @@ impl GlobalFileTable { for file in all_files { raw_file_table.entry(file.stable_id).or_insert_with(|| { - file.name - .for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE) - .to_string_lossy() - .into_owned() + // Prefer using the embeddable filename as this filename is going to + // end-up in the coverage artifacts (see rust-lang/rust#150020). + if let FileName::Real(real) = &file.name { + let (_work_dir, abs_name) = + real.embeddable_name(RemapPathScopeComponents::COVERAGE); + + abs_name.to_string_lossy().into_owned() + } else { + file.name + .display(RemapPathScopeComponents::COVERAGE) + .to_string_lossy() + .into_owned() + } }); } @@ -145,9 +152,10 @@ impl GlobalFileTable { // resolve any other entries that are stored as relative paths. let base_dir = tcx .sess - .opts - .working_dir - .for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE) + .psess + .source_map() + .working_dir() + .path(RemapPathScopeComponents::COVERAGE) .to_string_lossy(); table.push(base_dir.as_ref()); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs index 5d874631ca1a..0b5ef6c68740 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs @@ -1,8 +1,37 @@ +use std::ptr; + use libc::c_uint; use rustc_abi::Align; use crate::llvm::debuginfo::DIBuilder; -use crate::llvm::{self, ToLlvmBool}; +use crate::llvm::{self, Module, ToLlvmBool}; + +/// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder +/// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder` +/// needed for debuginfo FFI calls. +pub(crate) struct DIBuilderBox<'ll> { + raw: ptr::NonNull>, +} + +impl<'ll> DIBuilderBox<'ll> { + pub(crate) fn new(llmod: &'ll Module) -> Self { + let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) }; + let raw = ptr::NonNull::new(raw).unwrap(); + Self { raw } + } + + pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> { + // SAFETY: This is an owning pointer, so `&DIBuilder` is valid + // for as long as `&self` is. + unsafe { self.raw.as_ref() } + } +} + +impl<'ll> Drop for DIBuilderBox<'ll> { + fn drop(&mut self) { + unsafe { llvm::LLVMDisposeDIBuilder(self.raw) }; + } +} /// Extension trait for defining safe wrappers and helper methods on /// `&DIBuilder<'ll>`, without requiring it to be defined in the same crate. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/doc.md b/compiler/rustc_codegen_llvm/src/debuginfo/doc.md index aaec4e68c174..f5ea5ea77c4b 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/doc.md +++ b/compiler/rustc_codegen_llvm/src/debuginfo/doc.md @@ -16,7 +16,7 @@ module to generate correct metadata and insert it into the LLVM IR. As the exact format of metadata trees may change between different LLVM versions, we now use LLVM [DIBuilder](https://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) -to create metadata where possible. This will hopefully ease the adaption of +to create metadata where possible. This will hopefully ease the adaptation of this module to future LLVM versions. The public API of the module is a set of functions that will insert the @@ -87,19 +87,19 @@ describe the type anew. This behavior is encapsulated in the ## Source Locations and Line Information In addition to data type descriptions the debugging information must also -allow to map machine code locations back to source code locations in order +allow mapping machine code locations back to source code locations in order to be useful. This functionality is also handled in this module. The -following functions allow to control source mappings: +following functions allow controlling source mappings: + `set_source_location()` + `clear_source_location()` + `start_emitting_source_locations()` -`set_source_location()` allows to set the current source location. All IR +`set_source_location()` allows setting the current source location. All IR instructions created after a call to this function will be linked to the given source location, until another location is specified with `set_source_location()` or the source location is cleared with -`clear_source_location()`. In the later case, subsequent IR instruction +`clear_source_location()`. In the latter case, subsequent IR instructions will not be linked to any source location. As you can see, this is a stateful API (mimicking the one in LLVM), so be careful with source locations set by previous calls. It's probably best to not rely on any diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 3a750b6b53eb..f88f0c2fb099 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -92,7 +92,7 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { CrateType::Executable | CrateType::Dylib | CrateType::Cdylib - | CrateType::Staticlib + | CrateType::StaticLib | CrateType::Sdylib => { // These are crate types for which we will embed pretty printers since they // are treated as leaf crates. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 5535ebe65859..c759d46b7d2f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::sync::Arc; use std::{iter, ptr}; @@ -19,9 +19,7 @@ use rustc_middle::ty::{ self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility, }; use rustc_session::config::{self, DebugInfo, Lto}; -use rustc_span::{ - DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Span, Symbol, hygiene, -}; +use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene}; use rustc_symbol_mangling::typeid_for_trait_ref; use rustc_target::spec::DebuginfoKind; use smallvec::smallvec; @@ -481,7 +479,18 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>( AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span), }, ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id), - _ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t), + ty::Pat(base, _) => return type_di_node(cx, base), + // FIXME(unsafe_binders): impl debug info + ty::UnsafeBinder(_) => unimplemented!(), + ty::Alias(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Infer(_) + | ty::Placeholder(_) + | ty::CoroutineWitness(..) + | ty::Error(_) => { + bug!("debuginfo: unexpected type in type_di_node(): {:?}", t) + } }; { @@ -555,79 +564,38 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi ) -> &'ll DIFile { debug!(?source_file.name); - let filename_display_preference = - cx.sess().filename_display_preference(RemapPathScopeComponents::DEBUGINFO); - - use rustc_session::config::RemapPathScopeComponents; let (directory, file_name) = match &source_file.name { FileName::Real(filename) => { - let working_directory = &cx.sess().opts.working_dir; - debug!(?working_directory); + let (working_directory, embeddable_name) = + filename.embeddable_name(RemapPathScopeComponents::DEBUGINFO); - if filename_display_preference == FileNameDisplayPreference::Remapped { - let filename = cx - .sess() - .source_map() - .path_mapping() - .to_embeddable_absolute_path(filename.clone(), working_directory); + debug!(?working_directory, ?embeddable_name); - // Construct the absolute path of the file - let abs_path = filename.remapped_path_if_available(); - debug!(?abs_path); - - if let Ok(rel_path) = - abs_path.strip_prefix(working_directory.remapped_path_if_available()) - { - // If the compiler's working directory (which also is the DW_AT_comp_dir of - // the compilation unit) is a prefix of the path we are about to emit, then - // only emit the part relative to the working directory. Because of path - // remapping we sometimes see strange things here: `abs_path` might - // actually look like a relative path (e.g. - // `/src/lib.rs`), so if we emit it without taking - // the working directory into account, downstream tooling will interpret it - // as `//src/lib.rs`, which - // makes no sense. Usually in such cases the working directory will also be - // remapped to `` or some other prefix of the path - // we are remapping, so we end up with - // `//src/lib.rs`. - // By moving the working directory portion into the `directory` part of the - // DIFile, we allow LLVM to emit just the relative path for DWARF, while - // still emitting the correct absolute path for CodeView. - ( - working_directory.to_string_lossy(FileNameDisplayPreference::Remapped), - rel_path.to_string_lossy().into_owned(), - ) - } else { - ("".into(), abs_path.to_string_lossy().into_owned()) - } + if let Ok(rel_path) = embeddable_name.strip_prefix(working_directory) { + // If the compiler's working directory (which also is the DW_AT_comp_dir of + // the compilation unit) is a prefix of the path we are about to emit, then + // only emit the part relative to the working directory. Because of path + // remapping we sometimes see strange things here: `abs_path` might + // actually look like a relative path (e.g. + // `/src/lib.rs`), so if we emit it without taking + // the working directory into account, downstream tooling will interpret it + // as `//src/lib.rs`, which + // makes no sense. Usually in such cases the working directory will also be + // remapped to `` or some other prefix of the path + // we are remapping, so we end up with + // `//src/lib.rs`. + // + // By moving the working directory portion into the `directory` part of the + // DIFile, we allow LLVM to emit just the relative path for DWARF, while + // still emitting the correct absolute path for CodeView. + (working_directory.to_string_lossy(), rel_path.to_string_lossy().into_owned()) } else { - let working_directory = working_directory.local_path_if_available(); - let filename = filename.local_path_if_available(); - - debug!(?working_directory, ?filename); - - let abs_path: Cow<'_, Path> = if filename.is_absolute() { - filename.into() - } else { - let mut p = PathBuf::new(); - p.push(working_directory); - p.push(filename); - p.into() - }; - - if let Ok(rel_path) = abs_path.strip_prefix(working_directory) { - ( - working_directory.to_string_lossy(), - rel_path.to_string_lossy().into_owned(), - ) - } else { - ("".into(), abs_path.to_string_lossy().into_owned()) - } + ("".into(), embeddable_name.to_string_lossy().into_owned()) } } other => { debug!(?other); - ("".into(), other.display(filename_display_preference).to_string()) + ("".into(), other.display(RemapPathScopeComponents::DEBUGINFO).to_string()) } }; @@ -708,8 +676,8 @@ impl MsvcBasicName for ty::UintTy { impl MsvcBasicName for ty::FloatTy { fn msvc_basic_name(self) -> &'static str { - // FIXME(f16_f128): `f16` and `f128` have no MSVC representation. We could improve the - // debuginfo. See: + // FIXME(f128): `f128` has no MSVC representation. We could improve the debuginfo. + // See: match self { ty::FloatTy::F16 => { bug!("`f16` should have been handled in `build_basic_type_di_node`") @@ -889,12 +857,10 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( codegen_unit_name: &str, debug_context: &CodegenUnitDebugContext<'ll, 'tcx>, ) -> &'ll DIDescriptor { - use rustc_session::RemapFileNameExt; - use rustc_session::config::RemapPathScopeComponents; let mut name_in_debuginfo = tcx .sess .local_crate_source_file() - .map(|src| src.for_scope(&tcx.sess, RemapPathScopeComponents::DEBUGINFO).to_path_buf()) + .map(|src| src.path(RemapPathScopeComponents::DEBUGINFO).to_path_buf()) .unwrap_or_else(|| PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str())); // To avoid breaking split DWARF, we need to ensure that each codegen unit @@ -923,12 +889,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( let producer = format!("clang LLVM ({rustc_producer})"); let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); - let work_dir = tcx - .sess - .opts - .working_dir - .for_scope(tcx.sess, RemapPathScopeComponents::DEBUGINFO) - .to_string_lossy(); + let work_dir = tcx.sess.psess.source_map().working_dir(); let output_filenames = tcx.output_filenames(()); let split_name = if tcx.sess.target_can_use_split_dwarf() && let Some(f) = output_filenames.split_dwarf_path( @@ -938,14 +899,15 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( tcx.sess.invocation_temp.as_deref(), ) { // We get a path relative to the working directory from split_dwarf_path - Some(tcx.sess.source_map().path_mapping().to_real_filename(f)) + Some(tcx.sess.source_map().path_mapping().to_real_filename(work_dir, f)) } else { None }; let split_name = split_name .as_ref() - .map(|f| f.for_scope(tcx.sess, RemapPathScopeComponents::DEBUGINFO).to_string_lossy()) + .map(|f| f.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy()) .unwrap_or_default(); + let work_dir = work_dir.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy(); let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo); let dwarf_version = tcx.sess.dwarf_version(); @@ -1569,7 +1531,6 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( // Unwrap potential addrspacecast let vtable = find_vtable_behind_cast(vtable); let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty); - let trait_ref_self = cx.tcx.erase_and_anonymize_regions(trait_ref_self); let trait_def_id = trait_ref_self.def_id; let trait_vis = cx.tcx.visibility(trait_def_id); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index c2c55ee2b64f..c3fa86f8a2ad 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -38,8 +38,9 @@ use self::namespace::mangled_name_of_instance; use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; +use crate::debuginfo::di_builder::DIBuilderBox; use crate::llvm::debuginfo::{ - DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, + DIArray, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DITemplateTypeParameter, DIType, DIVariable, }; use crate::llvm::{self, Value}; @@ -455,7 +456,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let generics = tcx.generics_of(enclosing_fn_def_id); let args = instance.args.truncate_to(tcx, generics); - type_names::push_generic_params( + type_names::push_generic_args( tcx, tcx.normalize_erasing_regions(self.typing_env(), args), &mut name, diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index dd9fde0b08c6..af154a1aea80 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -2,14 +2,12 @@ use std::ffi::CString; use std::path::Path; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level}; +use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, msg}; use rustc_macros::Diagnostic; use rustc_span::Span; -use crate::fluent_generated as fluent; - #[derive(Diagnostic)] -#[diag(codegen_llvm_symbol_already_defined)] +#[diag("symbol `{$symbol_name}` is already defined")] pub(crate) struct SymbolAlreadyDefined<'a> { #[primary_span] pub span: Span, @@ -17,7 +15,7 @@ pub(crate) struct SymbolAlreadyDefined<'a> { } #[derive(Diagnostic)] -#[diag(codegen_llvm_sanitizer_memtag_requires_mte)] +#[diag("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`")] pub(crate) struct SanitizerMemtagRequiresMte; pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>); @@ -27,57 +25,94 @@ impl Diagnostic<'_, G> for ParseTargetMachineConfig<'_> { let diag: Diag<'_, G> = self.0.into_diag(dcx, level); let (message, _) = diag.messages.first().expect("`LlvmError` with no message"); let message = dcx.eagerly_translate_to_string(message.clone(), diag.args.iter()); - Diag::new(dcx, level, fluent::codegen_llvm_parse_target_machine_config) - .with_arg("error", message) + Diag::new( + dcx, + level, + msg!("failed to parse target machine config to target machine: {$error}"), + ) + .with_arg("error", message) } } #[derive(Diagnostic)] -#[diag(codegen_llvm_autodiff_without_lto)] +#[diag("failed to load our autodiff backend: {$err}")] +pub(crate) struct AutoDiffComponentUnavailable { + pub err: String, +} + +#[derive(Diagnostic)] +#[diag("autodiff backend not found in the sysroot: {$err}")] +#[note("it will be distributed via rustup in the future")] +pub(crate) struct AutoDiffComponentMissing { + pub err: String, +} + +#[derive(Diagnostic)] +#[diag("using the autodiff feature requires setting `lto=\"fat\"` in your Cargo.toml")] pub(crate) struct AutoDiffWithoutLto; #[derive(Diagnostic)] -#[diag(codegen_llvm_autodiff_without_enable)] +#[diag("using the autodiff feature requires -Z autodiff=Enable")] pub(crate) struct AutoDiffWithoutEnable; #[derive(Diagnostic)] -#[diag(codegen_llvm_offload_without_enable)] +#[diag("using the offload feature requires -Z offload=")] pub(crate) struct OffloadWithoutEnable; #[derive(Diagnostic)] -#[diag(codegen_llvm_offload_without_fat_lto)] +#[diag("using the offload feature requires -C lto=fat")] pub(crate) struct OffloadWithoutFatLTO; #[derive(Diagnostic)] -#[diag(codegen_llvm_lto_bitcode_from_rlib)] +#[diag("using the `-Z offload=Host=/absolute/path/to/host.out` flag requires an absolute path")] +pub(crate) struct OffloadWithoutAbsPath; + +#[derive(Diagnostic)] +#[diag( + "using the `-Z offload=Host=/absolute/path/to/host.out` flag must point to a `host.out` file" +)] +pub(crate) struct OffloadWrongFileName; + +#[derive(Diagnostic)] +#[diag( + "the given path/file to `host.out` does not exist. Did you forget to run the device compilation first?" +)] +pub(crate) struct OffloadNonexistingPath; + +#[derive(Diagnostic)] +#[diag("call to BundleImages failed, `host.out` was not created")] +pub(crate) struct OffloadBundleImagesFailed; + +#[derive(Diagnostic)] +#[diag("call to EmbedBufferInModule failed, `host.o` was not created")] +pub(crate) struct OffloadEmbedFailed; + +#[derive(Diagnostic)] +#[diag("failed to get bitcode from object file for LTO ({$err})")] pub(crate) struct LtoBitcodeFromRlib { pub err: String, } #[derive(Diagnostic)] -pub enum LlvmError<'a> { - #[diag(codegen_llvm_write_output)] +pub(crate) enum LlvmError<'a> { + #[diag("could not write output to {$path}")] WriteOutput { path: &'a Path }, - #[diag(codegen_llvm_target_machine)] + #[diag("could not create LLVM TargetMachine for triple: {$triple}")] CreateTargetMachine { triple: SmallCStr }, - #[diag(codegen_llvm_run_passes)] + #[diag("failed to run LLVM passes")] RunLlvmPasses, - #[diag(codegen_llvm_serialize_module)] - SerializeModule { name: &'a str }, - #[diag(codegen_llvm_write_ir)] + #[diag("failed to write LLVM IR to {$path}")] WriteIr { path: &'a Path }, - #[diag(codegen_llvm_prepare_thin_lto_context)] + #[diag("failed to prepare thin LTO context")] PrepareThinLtoContext, - #[diag(codegen_llvm_load_bitcode)] + #[diag("failed to load bitcode of module \"{$name}\"")] LoadBitcode { name: CString }, - #[diag(codegen_llvm_write_thinlto_key)] + #[diag("error while writing ThinLTO key data: {$err}")] WriteThinLtoKey { err: std::io::Error }, - #[diag(codegen_llvm_prepare_thin_lto_module)] + #[diag("failed to prepare thin LTO module")] PrepareThinLtoModule, - #[diag(codegen_llvm_parse_bitcode)] + #[diag("failed to parse bitcode for LTO module")] ParseBitcode, - #[diag(codegen_llvm_prepare_autodiff)] - PrepareAutoDiff { src: String, target: String, error: String }, } pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String); @@ -86,17 +121,25 @@ impl Diagnostic<'_, G> for WithLlvmError<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { use LlvmError::*; let msg_with_llvm_err = match &self.0 { - WriteOutput { .. } => fluent::codegen_llvm_write_output_with_llvm_err, - CreateTargetMachine { .. } => fluent::codegen_llvm_target_machine_with_llvm_err, - RunLlvmPasses => fluent::codegen_llvm_run_passes_with_llvm_err, - SerializeModule { .. } => fluent::codegen_llvm_serialize_module_with_llvm_err, - WriteIr { .. } => fluent::codegen_llvm_write_ir_with_llvm_err, - PrepareThinLtoContext => fluent::codegen_llvm_prepare_thin_lto_context_with_llvm_err, - LoadBitcode { .. } => fluent::codegen_llvm_load_bitcode_with_llvm_err, - WriteThinLtoKey { .. } => fluent::codegen_llvm_write_thinlto_key_with_llvm_err, - PrepareThinLtoModule => fluent::codegen_llvm_prepare_thin_lto_module_with_llvm_err, - ParseBitcode => fluent::codegen_llvm_parse_bitcode_with_llvm_err, - PrepareAutoDiff { .. } => fluent::codegen_llvm_prepare_autodiff_with_llvm_err, + WriteOutput { .. } => msg!("could not write output to {$path}: {$llvm_err}"), + CreateTargetMachine { .. } => { + msg!("could not create LLVM TargetMachine for triple: {$triple}: {$llvm_err}") + } + RunLlvmPasses => msg!("failed to run LLVM passes: {$llvm_err}"), + WriteIr { .. } => msg!("failed to write LLVM IR to {$path}: {$llvm_err}"), + PrepareThinLtoContext => { + msg!("failed to prepare thin LTO context: {$llvm_err}") + } + LoadBitcode { .. } => { + msg!("failed to load bitcode of module \"{$name}\": {$llvm_err}") + } + WriteThinLtoKey { .. } => { + msg!("error while writing ThinLTO key data: {$err}: {$llvm_err}") + } + PrepareThinLtoModule => { + msg!("failed to prepare thin LTO module: {$llvm_err}") + } + ParseBitcode => msg!("failed to parse bitcode for LTO module: {$llvm_err}"), }; self.0 .into_diag(dcx, level) @@ -106,7 +149,7 @@ impl Diagnostic<'_, G> for WithLlvmError<'_> { } #[derive(Diagnostic)] -#[diag(codegen_llvm_from_llvm_optimization_diag)] +#[diag("{$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message}")] pub(crate) struct FromLlvmOptimizationDiag<'a> { pub filename: &'a str, pub line: std::ffi::c_uint, @@ -117,32 +160,36 @@ pub(crate) struct FromLlvmOptimizationDiag<'a> { } #[derive(Diagnostic)] -#[diag(codegen_llvm_from_llvm_diag)] +#[diag("{$message}")] pub(crate) struct FromLlvmDiag { pub message: String, } #[derive(Diagnostic)] -#[diag(codegen_llvm_write_bytecode)] +#[diag("failed to write bytecode to {$path}: {$err}")] pub(crate) struct WriteBytecode<'a> { pub path: &'a Path, pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_llvm_copy_bitcode)] +#[diag("failed to copy bitcode to object file: {$err}")] pub(crate) struct CopyBitcode { pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_llvm_unknown_debuginfo_compression)] +#[diag( + "unknown debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo" +)] pub(crate) struct UnknownCompression { pub algorithm: &'static str, } #[derive(Diagnostic)] -#[diag(codegen_llvm_mismatch_data_layout)] +#[diag( + "data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}`" +)] pub(crate) struct MismatchedDataLayout<'a> { pub rustc_target: &'a str, pub rustc_layout: &'a str, @@ -151,11 +198,11 @@ pub(crate) struct MismatchedDataLayout<'a> { } #[derive(Diagnostic)] -#[diag(codegen_llvm_fixed_x18_invalid_arch)] +#[diag("the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture")] pub(crate) struct FixedX18InvalidArch<'a> { pub arch: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_llvm_sanitizer_kcfi_arity_requires_llvm_21_0_0)] +#[diag("`-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later")] pub(crate) struct SanitizerKcfiArityRequiresLLVM2100; diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 33541f7b695f..6bcc8135f35e 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1,7 +1,10 @@ -use std::assert_matches::assert_matches; use std::cmp::Ordering; +use std::ffi::c_uint; +use std::ptr; -use rustc_abi::{Align, BackendRepr, ExternAbi, Float, HasDataLayout, Primitive, Size}; +use rustc_abi::{ + Align, BackendRepr, ExternAbi, Float, HasDataLayout, Primitive, Size, WrappingRange, +}; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::codegen_attrs::autodiff_attrs; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; @@ -9,6 +12,7 @@ use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphizati use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue}; use rustc_codegen_ssa::traits::*; +use rustc_data_structures::assert_matches; use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::{self as hir}; use rustc_middle::mir::BinOp; @@ -26,8 +30,11 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::builder::Builder; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; -use crate::builder::gpu_offload::TgtOffloadEntry; +use crate::builder::gpu_offload::{ + OffloadKernelDims, gen_call_handling, gen_define_handling, register_offload, +}; use crate::context::CodegenCx; +use crate::declare::declare_raw_fn; use crate::errors::{ AutoDiffWithoutEnable, AutoDiffWithoutLto, OffloadWithoutEnable, OffloadWithoutFatLTO, }; @@ -202,13 +209,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { return Ok(()); } sym::offload => { - if !tcx - .sess - .opts - .unstable_opts - .offload - .contains(&rustc_session::config::Offload::Enable) - { + if tcx.sess.opts.unstable_opts.offload.is_empty() { let _ = tcx.dcx().emit_almost_fatal(OffloadWithoutEnable); } @@ -270,14 +271,6 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { return Ok(()); } sym::breakpoint => self.call_intrinsic("llvm.debugtrap", &[], &[]), - sym::va_copy => { - let dest = args[0].immediate(); - self.call_intrinsic( - "llvm.va_copy", - &[self.val_ty(dest)], - &[dest, args[1].immediate()], - ) - } sym::va_arg => { match result.layout.backend_repr { BackendRepr::Scalar(scalar) => { @@ -351,7 +344,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { _ => bug!(), }; let ptr = args[0].immediate(); - let locality = fn_args.const_at(1).to_value().valtree.unwrap_leaf().to_i32(); + let locality = fn_args.const_at(1).to_leaf().to_i32(); self.call_intrinsic( "llvm.prefetch", &[self.val_ty(ptr)], @@ -394,6 +387,27 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let pair = self.insert_value(pair, high, 1); pair } + + // FIXME move into the branch below when LLVM 22 is the lowest version we support. + sym::carryless_mul if crate::llvm_util::get_version() >= (22, 0, 0) => { + let ty = args[0].layout.ty; + if !ty.is_integral() { + tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType { + span, + name, + ty, + }); + return Ok(()); + } + let (size, _) = ty.int_size_and_signed(self.tcx); + let width = size.bits(); + let llty = self.type_ix(width); + + let lhs = args[0].immediate(); + let rhs = args[1].immediate(); + self.call_intrinsic("llvm.clmul", &[llty], &[lhs, rhs]) + } + sym::ctlz | sym::ctlz_nonzero | sym::cttz @@ -480,6 +494,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, SimdVector { .. } => false, + ScalableVector { .. } => { + tcx.dcx().emit_err(InvalidMonomorphization::NonScalableType { + span, + name: sym::raw_eq, + ty: tp_ty, + }); + return Ok(()); + } Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), @@ -553,6 +575,12 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { return Ok(()); } + sym::amdgpu_dispatch_ptr => { + let val = self.call_intrinsic("llvm.amdgcn.dispatch.ptr", &[], &[]); + // Relying on `LLVMBuildPointerCast` to produce an addrspacecast + self.pointercast(val, self.type_ptr()) + } + _ if name.as_str().starts_with("simd_") => { // Unpack non-power-of-2 #[repr(packed, simd)] arguments. // This gives them the expected layout of a regular #[repr(simd)] vector. @@ -631,6 +659,120 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { Ok(()) } + fn codegen_llvm_intrinsic_call( + &mut self, + instance: ty::Instance<'tcx>, + args: &[OperandRef<'tcx, Self::Value>], + is_cleanup: bool, + ) -> Self::Value { + let tcx = self.tcx(); + + let fn_ty = instance.ty(tcx, self.typing_env()); + let fn_sig = match *fn_ty.kind() { + ty::FnDef(def_id, args) => { + tcx.instantiate_bound_regions_with_erased(tcx.fn_sig(def_id).instantiate(tcx, args)) + } + _ => unreachable!(), + }; + assert!(!fn_sig.c_variadic); + + let ret_layout = self.layout_of(fn_sig.output()); + let llreturn_ty = if ret_layout.is_zst() { + self.type_void() + } else { + ret_layout.immediate_llvm_type(self) + }; + + let mut llargument_tys = Vec::with_capacity(fn_sig.inputs().len()); + for &arg in fn_sig.inputs() { + let arg_layout = self.layout_of(arg); + if arg_layout.is_zst() { + continue; + } + llargument_tys.push(arg_layout.immediate_llvm_type(self)); + } + + let fn_ty = self.type_func(&llargument_tys, llreturn_ty); + + let fn_ptr = if let Some(&llfn) = self.intrinsic_instances.borrow().get(&instance) { + llfn + } else { + let sym = tcx.symbol_name(instance).name; + + // FIXME use get_intrinsic + let llfn = if let Some(llfn) = self.get_declared_value(sym) { + llfn + } else { + // Function addresses in Rust are never significant, allowing functions to + // be merged. + let llfn = declare_raw_fn( + self, + sym, + llvm::CCallConv, + llvm::UnnamedAddr::Global, + llvm::Visibility::Default, + fn_ty, + ); + + llfn + }; + + self.intrinsic_instances.borrow_mut().insert(instance, llfn); + + llfn + }; + + let mut llargs = vec![]; + + for arg in args { + match arg.val { + OperandValue::ZeroSized => {} + OperandValue::Immediate(_) => llargs.push(arg.immediate()), + OperandValue::Pair(a, b) => { + llargs.push(a); + llargs.push(b); + } + OperandValue::Ref(op_place_val) => { + let mut llval = op_place_val.llval; + // We can't use `PlaceRef::load` here because the argument + // may have a type we don't treat as immediate, but the ABI + // used for this call is passing it by-value. In that case, + // the load would just produce `OperandValue::Ref` instead + // of the `OperandValue::Immediate` we need for the call. + llval = self.load(self.backend_type(arg.layout), llval, op_place_val.align); + if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr { + if scalar.is_bool() { + self.range_metadata(llval, WrappingRange { start: 0, end: 1 }); + } + // We store bools as `i8` so we need to truncate to `i1`. + llval = self.to_immediate_scalar(llval, scalar); + } + llargs.push(llval); + } + } + } + + debug!("call intrinsic {:?} with args ({:?})", instance, llargs); + let args = self.check_call("call", fn_ty, fn_ptr, &llargs); + let llret = unsafe { + llvm::LLVMBuildCallWithOperandBundles( + self.llbuilder, + fn_ty, + fn_ptr, + args.as_ptr() as *const &llvm::Value, + args.len() as c_uint, + ptr::dangling(), + 0, + c"".as_ptr(), + ) + }; + if is_cleanup { + self.apply_attrs_to_cleanup_callsite(llret); + } + + llret + } + fn abort(&mut self) { self.call_intrinsic("llvm.trap", &[], &[]); } @@ -1284,29 +1426,29 @@ fn codegen_offload<'ll, 'tcx>( } }; - let args = get_args_from_tuple(bx, args[1], fn_target); + let offload_dims = OffloadKernelDims::from_operands(bx, &args[1], &args[2]); + let args = get_args_from_tuple(bx, args[3], fn_target); let target_symbol = symbol_name_for_instance_in_crate(tcx, fn_target, LOCAL_CRATE); - let offload_entry_ty = TgtOffloadEntry::new_decl(&cx); - - let sig = tcx.fn_sig(fn_target.def_id()).skip_binder().skip_binder(); + let sig = tcx.fn_sig(fn_target.def_id()).skip_binder(); + let sig = tcx.instantiate_bound_regions_with_erased(sig); let inputs = sig.inputs(); let metadata = inputs.iter().map(|ty| OffloadMetadata::from_ty(tcx, *ty)).collect::>(); let types = inputs.iter().map(|ty| cx.layout_of(*ty).llvm_type(cx)).collect::>(); - let offload_data = crate::builder::gpu_offload::gen_define_handling( - cx, - offload_entry_ty, - &metadata, - &types, - &target_symbol, - ); - - // FIXME(Sa4dUs): pass the original builder once we separate kernel launch logic from globals - let bb = unsafe { llvm::LLVMGetInsertBlock(bx.llbuilder) }; - crate::builder::gpu_offload::gen_call_handling(cx, bb, &offload_data, &args, &types, &metadata); + let offload_globals_ref = cx.offload_globals.borrow(); + let offload_globals = match offload_globals_ref.as_ref() { + Some(globals) => globals, + None => { + // Offload is not initialized, cannot continue + return; + } + }; + register_offload(cx); + let offload_data = gen_define_handling(&cx, &metadata, target_symbol, offload_globals); + gen_call_handling(bx, &offload_data, &args, &types, &metadata, offload_globals, &offload_dims); } fn get_args_from_tuple<'ll, 'tcx>( @@ -1484,6 +1626,31 @@ fn generic_simd_intrinsic<'ll, 'tcx>( return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } + if name == sym::simd_splat { + let (_out_len, out_ty) = require_simd!(ret_ty, SimdReturn); + + require!( + args[0].layout.ty == out_ty, + InvalidMonomorphization::ExpectedVectorElementType { + span, + name, + expected_element: out_ty, + vector_type: ret_ty, + } + ); + + // `insertelement poison, elem %x, i32 0` + let poison_vec = bx.const_poison(llret_ty); + let idx0 = bx.const_i32(0); + let v0 = bx.insert_element(poison_vec, args[0].immediate(), idx0); + + // `shufflevector v0, poison, zeroinitializer` + // The masks is all zeros, so this splats lane 0 (which has our element in it). + let splat = bx.shuffle_vector(v0, poison_vec, bx.const_null(llret_ty)); + + return Ok(splat); + } + // every intrinsic below takes a SIMD vector as its first argument let (in_len, in_elem) = require_simd!(args[0].layout.ty, SimdInput); let in_ty = args[0].layout.ty; @@ -1528,7 +1695,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( } if name == sym::simd_shuffle_const_generic { - let idx = fn_args[2].expect_const().to_value().valtree.unwrap_branch(); + let idx = fn_args[2].expect_const().to_branch(); let n = idx.len() as u64; let (out_len, out_ty) = require_simd!(ret_ty, SimdReturn); @@ -1547,7 +1714,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( .iter() .enumerate() .map(|(arg_idx, val)| { - let idx = val.unwrap_leaf().to_i32(); + let idx = val.to_leaf().to_i32(); if idx >= i32::try_from(total_len).unwrap() { bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds { span, @@ -1679,11 +1846,27 @@ fn generic_simd_intrinsic<'ll, 'tcx>( m_len == v_len, InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len } ); - let in_elem_bitwidth = require_int_or_uint_ty!( - m_elem_ty.kind(), - InvalidMonomorphization::MaskWrongElementType { span, name, ty: m_elem_ty } - ); - let m_i1s = vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len); + + let m_i1s = if args[1].layout.ty.is_scalable_vector() { + match m_elem_ty.kind() { + ty::Bool => {} + _ => return_error!(InvalidMonomorphization::MaskWrongElementType { + span, + name, + ty: m_elem_ty + }), + }; + let i1 = bx.type_i1(); + let i1xn = bx.type_scalable_vector(i1, m_len as u64); + bx.trunc(args[0].immediate(), i1xn) + } else { + let in_elem_bitwidth = require_int_or_uint_ty!( + m_elem_ty.kind(), + InvalidMonomorphization::MaskWrongElementType { span, name, ty: m_elem_ty } + ); + vector_mask_to_bitmask(bx, args[0].immediate(), in_elem_bitwidth, m_len) + }; + return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } @@ -1756,11 +1939,10 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }}; } - let elem_ty = if let ty::Float(f) = in_elem.kind() { - bx.cx.type_float_from_ty(*f) - } else { + let ty::Float(f) = in_elem.kind() else { return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty }); }; + let elem_ty = bx.cx.type_float_from_ty(*f); let vec_ty = bx.type_vector(elem_ty, in_len); @@ -1944,9 +2126,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // those lanes whose `mask` bit is enabled. // The memory addresses corresponding to the “off†lanes are not accessed. - let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = fn_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); // The element type of the "mask" argument must be a signed integer type of any width let mask_ty = in_ty; @@ -2039,9 +2219,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // those lanes whose `mask` bit is enabled. // The memory addresses corresponding to the “off†lanes are not accessed. - let alignment = fn_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(); + let alignment = fn_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(); // The element type of the "mask" argument must be a signed integer type of any width let mask_ty = in_ty; @@ -2627,6 +2805,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( | sym::simd_ctlz | sym::simd_ctpop | sym::simd_cttz + | sym::simd_carryless_mul | sym::simd_funnel_shl | sym::simd_funnel_shr ) { @@ -2651,6 +2830,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( sym::simd_cttz => "llvm.cttz", sym::simd_funnel_shl => "llvm.fshl", sym::simd_funnel_shr => "llvm.fshr", + sym::simd_carryless_mul => "llvm.clmul", _ => unreachable!(), }; let int_size = in_elem.int_size_and_signed(bx.tcx()).0.bits(); @@ -2676,6 +2856,17 @@ fn generic_simd_intrinsic<'ll, 'tcx>( &[vec_ty], &[args[0].immediate(), args[1].immediate(), args[2].immediate()], )), + sym::simd_carryless_mul => { + if crate::llvm_util::get_version() >= (22, 0, 0) { + Ok(bx.call_intrinsic( + llvm_intrinsic, + &[vec_ty], + &[args[0].immediate(), args[1].immediate()], + )) + } else { + span_bug!(span, "`simd_carryless_mul` needs LLVM 22 or higher"); + } + } _ => unreachable!(), }; } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8c0c0afcc1dd..3310fe4f43f8 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -5,14 +5,14 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![cfg_attr(bootstrap, feature(slice_as_array))] -#![feature(assert_matches)] +#![cfg_attr(bootstrap, feature(assert_matches))] #![feature(extern_types)] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(macro_derive)] +#![feature(once_cell_try)] #![feature(trim_prefix_suffix)] #![feature(try_blocks)] // tidy-alphabetical-end @@ -25,24 +25,25 @@ use std::path::PathBuf; use back::owned_target_machine::OwnedTargetMachine; use back::write::{create_informational_target_machine, create_target_machine}; use context::SimpleCx; -use errors::ParseTargetMachineConfig; use llvm_util::target_config; use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ - CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, + CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryConfig, + TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::DiagCtxtHandle; +use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest}; -use rustc_span::Symbol; +use rustc_span::{Symbol, sym}; use rustc_target::spec::{RelocModel, TlsModel}; use crate::llvm::ToLlvmBool; @@ -73,8 +74,6 @@ mod typetree; mod va_arg; mod value; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub(crate) use macros::TryFromU32; #[derive(Clone)] @@ -153,7 +152,6 @@ impl WriteBackendMethods for LlvmCodegenBackend { type Module = ModuleLlvm; type ModuleBuffer = back::lto::ModuleBuffer; type TargetMachine = OwnedTargetMachine; - type TargetMachineError = crate::errors::LlvmError<'static>; type ThinData = back::lto::ThinData; type ThinBuffer = back::lto::ThinBuffer; fn print_pass_timings(&self) { @@ -165,22 +163,34 @@ impl WriteBackendMethods for LlvmCodegenBackend { print!("{stats}"); } fn run_and_optimize_fat_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, + tm_factory: TargetMachineFactoryFn, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, ) -> ModuleCodegen { - let mut module = - back::lto::run_fat(cgcx, exported_symbols_for_lto, each_linked_rlib_for_lto, modules); + let mut module = back::lto::run_fat( + cgcx, + prof, + shared_emitter, + tm_factory, + exported_symbols_for_lto, + each_linked_rlib_for_lto, + modules, + ); - let dcx = cgcx.create_dcx(); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); let dcx = dcx.handle(); - back::lto::run_pass_manager(cgcx, dcx, &mut module, false); + back::lto::run_pass_manager(cgcx, prof, dcx, &mut module, false); module } fn run_thin_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, Self::ThinBuffer)>, @@ -188,6 +198,8 @@ impl WriteBackendMethods for LlvmCodegenBackend { ) -> (Vec>, Vec) { back::lto::run_thin( cgcx, + prof, + dcx, exported_symbols_for_lto, each_linked_rlib_for_lto, modules, @@ -195,25 +207,31 @@ impl WriteBackendMethods for LlvmCodegenBackend { ) } fn optimize( - cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ) { - back::write::optimize(cgcx, dcx, module, config) + back::write::optimize(cgcx, prof, shared_emitter, module, config) } fn optimize_thin( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, + tm_factory: TargetMachineFactoryFn, thin: ThinModule, ) -> ModuleCodegen { - back::lto::optimize_thin_module(thin, cgcx) + back::lto::optimize_thin_module(cgcx, prof, shared_emitter, tm_factory, thin) } fn codegen( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule { - back::write::codegen(cgcx, module, config) + back::write::codegen(cgcx, prof, shared_emitter, module, config) } fn prepare_thin(module: ModuleCodegen) -> (String, Self::ThinBuffer) { back::lto::prepare_thin(module) @@ -230,20 +248,37 @@ impl LlvmCodegenBackend { } impl CodegenBackend for LlvmCodegenBackend { - fn locale_resource(&self) -> &'static str { - crate::DEFAULT_LOCALE_RESOURCE - } - fn name(&self) -> &'static str { "llvm" } fn init(&self, sess: &Session) { llvm_util::init(sess); // Make sure llvm is inited + + // autodiff is based on Enzyme, a library which we might not have available, when it was + // neither build, nor downloaded via rustup. If autodiff is used, but not available we emit + // an early error here and abort compilation. + { + use rustc_session::config::AutoDiff; + + use crate::back::lto::enable_autodiff_settings; + if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) { + match llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) { + Ok(_) => {} + Err(llvm::EnzymeLibraryError::NotFound { err }) => { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentMissing { err }); + } + Err(llvm::EnzymeLibraryError::LoadFailed { err }) => { + sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable { err }); + } + } + enable_autodiff_settings(&sess.opts.unstable_opts.autodiff); + } + } } fn provide(&self, providers: &mut Providers) { - providers.global_backend_features = + providers.queries.global_backend_features = |tcx, ()| llvm_util::global_llvm_features(tcx.sess, false) } @@ -257,10 +292,6 @@ impl CodegenBackend for LlvmCodegenBackend { } writeln!(out).unwrap(); } - PrintKind::BackendHasZstd => { - let has_zstd = llvm::LLVMRustLLVMHasZstdCompression(); - writeln!(out, "{has_zstd}").unwrap(); - } PrintKind::CodeModels => { writeln!(out, "Available code models:").unwrap(); for name in &["tiny", "small", "kernel", "medium", "large"] { @@ -314,10 +345,25 @@ impl CodegenBackend for LlvmCodegenBackend { llvm_util::print_version(); } + fn has_zstd(&self) -> bool { + llvm::LLVMRustLLVMHasZstdCompression() + } + fn target_config(&self, sess: &Session) -> TargetConfig { target_config(sess) } + fn replaced_intrinsics(&self) -> Vec { + let mut will_not_use_fallback = + vec![sym::unchecked_funnel_shl, sym::unchecked_funnel_shr, sym::carrying_mul_add]; + + if llvm_util::get_version() >= (22, 0, 0) { + will_not_use_fallback.push(sym::carryless_mul); + } + + will_not_use_fallback + } + fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box { Box::new(rustc_codegen_ssa::base::codegen_crate( LlvmCodegenBackend(()), @@ -410,22 +456,9 @@ impl ModuleLlvm { } } - fn tm_from_cgcx( - cgcx: &CodegenContext, - name: &str, - dcx: DiagCtxtHandle<'_>, - ) -> OwnedTargetMachine { - let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, name); - match (cgcx.tm_factory)(tm_factory_config) { - Ok(m) => m, - Err(e) => { - dcx.emit_fatal(ParseTargetMachineConfig(e)); - } - } - } - fn parse( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + tm_factory: TargetMachineFactoryFn, name: &CStr, buffer: &[u8], dcx: DiagCtxtHandle<'_>, @@ -434,7 +467,7 @@ impl ModuleLlvm { let llcx = llvm::LLVMContextCreate(); llvm::LLVMContextSetDiscardValueNames(llcx, cgcx.fewer_names.to_llvm_bool()); let llmod_raw = back::lto::parse_module(llcx, name, buffer, dcx); - let tm = ModuleLlvm::tm_from_cgcx(cgcx, name.to_str().unwrap(), dcx); + let tm = tm_factory(dcx, TargetMachineFactoryConfig::new(cgcx, name.to_str().unwrap())); ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/conversions.rs b/compiler/rustc_codegen_llvm/src/llvm/conversions.rs index 9e9f9339ade8..3bc790ca7cff 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/conversions.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/conversions.rs @@ -1,6 +1,6 @@ //! Conversions from backend-independent data types to/from LLVM FFI types. -use rustc_codegen_ssa::common::{AtomicRmwBinOp, IntPredicate, RealPredicate}; +use rustc_codegen_ssa::common::{AtomicRmwBinOp, IntPredicate, RealPredicate, TypeKind}; use rustc_middle::ty::AtomicOrdering; use rustc_session::config::DebugInfo; use rustc_target::spec::SymbolVisibility; @@ -9,10 +9,22 @@ use crate::llvm; /// Helper trait for converting backend-independent types to LLVM-specific /// types, for FFI purposes. +/// +/// FIXME(#147327): These trait/method names were chosen to avoid churn in +/// existing code, but are not great and could probably be made clearer. pub(crate) trait FromGeneric { fn from_generic(other: T) -> Self; } +/// Helper trait for converting LLVM-specific types to backend-independent +/// types, for FFI purposes. +/// +/// FIXME(#147327): These trait/method names were chosen to avoid churn in +/// existing code, but are not great and could probably be made clearer. +pub(crate) trait ToGeneric { + fn to_generic(&self) -> T; +} + impl FromGeneric for llvm::Visibility { fn from_generic(visibility: SymbolVisibility) -> Self { match visibility { @@ -113,3 +125,29 @@ impl FromGeneric for llvm::debuginfo::DebugEmissionKind { } } } + +impl ToGeneric for llvm::TypeKind { + fn to_generic(&self) -> TypeKind { + match self { + Self::Void => TypeKind::Void, + Self::Half => TypeKind::Half, + Self::Float => TypeKind::Float, + Self::Double => TypeKind::Double, + Self::X86_FP80 => TypeKind::X86_FP80, + Self::FP128 => TypeKind::FP128, + Self::PPC_FP128 => TypeKind::PPC_FP128, + Self::Label => TypeKind::Label, + Self::Integer => TypeKind::Integer, + Self::Function => TypeKind::Function, + Self::Struct => TypeKind::Struct, + Self::Array => TypeKind::Array, + Self::Pointer => TypeKind::Pointer, + Self::Vector => TypeKind::Vector, + Self::Metadata => TypeKind::Metadata, + Self::Token => TypeKind::Token, + Self::ScalableVector => TypeKind::ScalableVector, + Self::BFloat => TypeKind::BFloat, + Self::X86_AMX => TypeKind::X86_AMX, + } + } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index e63043b21227..67fbc0f53adc 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -86,223 +86,400 @@ pub(crate) enum LLVMRustVerifierFailureAction { LLVMReturnStatusAction = 2, } -#[cfg(feature = "llvm_enzyme")] pub(crate) use self::Enzyme_AD::*; -#[cfg(feature = "llvm_enzyme")] pub(crate) mod Enzyme_AD { - use std::ffi::{CString, c_char}; + use std::ffi::{c_char, c_void}; + use std::sync::{Mutex, MutexGuard, OnceLock}; - use libc::c_void; + use rustc_middle::bug; + use rustc_session::config::{Sysroot, host_tuple}; + use rustc_session::filesearch; use super::{CConcreteType, CTypeTreeRef, Context}; + use crate::llvm::{EnzymeTypeTree, LLVMRustVersionMajor}; - unsafe extern "C" { - pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8); - pub(crate) fn EnzymeSetCLString(arg1: *mut ::std::os::raw::c_void, arg2: *const c_char); + type EnzymeSetCLBoolFn = unsafe extern "C" fn(*mut c_void, u8); + type EnzymeSetCLStringFn = unsafe extern "C" fn(*mut c_void, *const c_char); + + type EnzymeNewTypeTreeFn = unsafe extern "C" fn() -> CTypeTreeRef; + type EnzymeNewTypeTreeCTFn = unsafe extern "C" fn(CConcreteType, &Context) -> CTypeTreeRef; + type EnzymeNewTypeTreeTRFn = unsafe extern "C" fn(CTypeTreeRef) -> CTypeTreeRef; + type EnzymeFreeTypeTreeFn = unsafe extern "C" fn(CTypeTreeRef); + type EnzymeMergeTypeTreeFn = unsafe extern "C" fn(CTypeTreeRef, CTypeTreeRef) -> bool; + type EnzymeTypeTreeOnlyEqFn = unsafe extern "C" fn(CTypeTreeRef, i64); + type EnzymeTypeTreeData0EqFn = unsafe extern "C" fn(CTypeTreeRef); + type EnzymeTypeTreeShiftIndiciesEqFn = + unsafe extern "C" fn(CTypeTreeRef, *const c_char, i64, i64, u64); + type EnzymeTypeTreeInsertEqFn = + unsafe extern "C" fn(CTypeTreeRef, *const i64, usize, CConcreteType, &Context); + type EnzymeTypeTreeToStringFn = unsafe extern "C" fn(CTypeTreeRef) -> *const c_char; + type EnzymeTypeTreeToStringFreeFn = unsafe extern "C" fn(*const c_char); + + #[allow(non_snake_case)] + pub(crate) struct EnzymeWrapper { + EnzymeNewTypeTree: EnzymeNewTypeTreeFn, + EnzymeNewTypeTreeCT: EnzymeNewTypeTreeCTFn, + EnzymeNewTypeTreeTR: EnzymeNewTypeTreeTRFn, + EnzymeFreeTypeTree: EnzymeFreeTypeTreeFn, + EnzymeMergeTypeTree: EnzymeMergeTypeTreeFn, + EnzymeTypeTreeOnlyEq: EnzymeTypeTreeOnlyEqFn, + EnzymeTypeTreeData0Eq: EnzymeTypeTreeData0EqFn, + EnzymeTypeTreeShiftIndiciesEq: EnzymeTypeTreeShiftIndiciesEqFn, + EnzymeTypeTreeInsertEq: EnzymeTypeTreeInsertEqFn, + EnzymeTypeTreeToString: EnzymeTypeTreeToStringFn, + EnzymeTypeTreeToStringFree: EnzymeTypeTreeToStringFreeFn, + + EnzymePrintPerf: *mut c_void, + EnzymePrintActivity: *mut c_void, + EnzymePrintType: *mut c_void, + EnzymeFunctionToAnalyze: *mut c_void, + EnzymePrint: *mut c_void, + EnzymeStrictAliasing: *mut c_void, + EnzymeInline: *mut c_void, + EnzymeMaxTypeDepth: *mut c_void, + RustTypeRules: *mut c_void, + looseTypeAnalysis: *mut c_void, + + EnzymeSetCLBool: EnzymeSetCLBoolFn, + EnzymeSetCLString: EnzymeSetCLStringFn, + pub registerEnzymeAndPassPipeline: *const c_void, + lib: libloading::Library, } - // TypeTree functions - unsafe extern "C" { - pub(crate) fn EnzymeNewTypeTree() -> CTypeTreeRef; - pub(crate) fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef; - pub(crate) fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef; - pub(crate) fn EnzymeFreeTypeTree(CTT: CTypeTreeRef); - pub(crate) fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool; - pub(crate) fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64); - pub(crate) fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef); - pub(crate) fn EnzymeTypeTreeShiftIndiciesEq( - arg1: CTypeTreeRef, + unsafe impl Sync for EnzymeWrapper {} + unsafe impl Send for EnzymeWrapper {} + + fn load_ptr_by_symbol_mut_void( + lib: &libloading::Library, + bytes: &[u8], + ) -> Result<*mut c_void, libloading::Error> { + unsafe { + let s: libloading::Symbol<'_, *mut c_void> = lib.get(bytes)?; + // libloading = 0.9.0: try_as_raw_ptr always succeeds and returns Some + let s = s.try_as_raw_ptr().unwrap(); + Ok(s) + } + } + + // e.g. + // load_ptrs_by_symbols_mut_void(ABC, XYZ); + // => + // let ABC = load_ptr_mut_void(&lib, b"ABC")?; + // let XYZ = load_ptr_mut_void(&lib, b"XYZ")?; + macro_rules! load_ptrs_by_symbols_mut_void { + ($lib:expr, $($name:ident),* $(,)?) => { + $( + #[allow(non_snake_case)] + let $name = load_ptr_by_symbol_mut_void(&$lib, stringify!($name).as_bytes())?; + )* + }; + } + + // e.g. + // load_ptrs_by_symbols_fn(ABC: ABCFn, XYZ: XYZFn); + // => + // let ABC: libloading::Symbol<'_, ABCFn> = unsafe { lib.get(b"ABC")? }; + // let XYZ: libloading::Symbol<'_, XYZFn> = unsafe { lib.get(b"XYZ")? }; + macro_rules! load_ptrs_by_symbols_fn { + ($lib:expr, $($name:ident : $ty:ty),* $(,)?) => { + $( + #[allow(non_snake_case)] + let $name: $ty = *unsafe { $lib.get::<$ty>(stringify!($name).as_bytes())? }; + )* + }; + } + + static ENZYME_INSTANCE: OnceLock> = OnceLock::new(); + + #[derive(Debug)] + pub(crate) enum EnzymeLibraryError { + NotFound { err: String }, + LoadFailed { err: String }, + } + + impl From for EnzymeLibraryError { + fn from(err: libloading::Error) -> Self { + Self::LoadFailed { err: format!("{err:?}") } + } + } + + impl EnzymeWrapper { + /// Initialize EnzymeWrapper with the given sysroot if not already initialized. + /// Safe to call multiple times - subsequent calls are no-ops due to OnceLock. + pub(crate) fn get_or_init( + sysroot: &rustc_session::config::Sysroot, + ) -> Result, EnzymeLibraryError> { + let mtx: &'static Mutex = ENZYME_INSTANCE.get_or_try_init(|| { + let w = Self::call_dynamic(sysroot)?; + Ok::<_, EnzymeLibraryError>(Mutex::new(w)) + })?; + + Ok(mtx.lock().unwrap()) + } + + /// Get the EnzymeWrapper instance. Panics if not initialized. + pub(crate) fn get_instance() -> MutexGuard<'static, Self> { + ENZYME_INSTANCE + .get() + .expect("EnzymeWrapper not initialized. Call get_or_init with sysroot first.") + .lock() + .unwrap() + } + + pub(crate) fn new_type_tree(&self) -> CTypeTreeRef { + unsafe { (self.EnzymeNewTypeTree)() } + } + + pub(crate) fn new_type_tree_ct( + &self, + t: CConcreteType, + ctx: &Context, + ) -> *mut EnzymeTypeTree { + unsafe { (self.EnzymeNewTypeTreeCT)(t, ctx) } + } + + pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef { + unsafe { (self.EnzymeNewTypeTreeTR)(tree) } + } + + pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) { + unsafe { (self.EnzymeFreeTypeTree)(tree) } + } + + pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool { + unsafe { (self.EnzymeMergeTypeTree)(tree1, tree2) } + } + + pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) { + unsafe { (self.EnzymeTypeTreeOnlyEq)(tree, num) } + } + + pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) { + unsafe { (self.EnzymeTypeTreeData0Eq)(tree) } + } + + pub(crate) fn shift_indicies_eq( + &self, + tree: CTypeTreeRef, data_layout: *const c_char, offset: i64, max_size: i64, add_offset: u64, - ); - pub(crate) fn EnzymeTypeTreeInsertEq( - CTT: CTypeTreeRef, + ) { + unsafe { + (self.EnzymeTypeTreeShiftIndiciesEq)( + tree, + data_layout, + offset, + max_size, + add_offset, + ) + } + } + + pub(crate) fn tree_insert_eq( + &self, + tree: CTypeTreeRef, indices: *const i64, len: usize, ct: CConcreteType, ctx: &Context, - ); - pub(crate) fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char; - pub(crate) fn EnzymeTypeTreeToStringFree(arg1: *const c_char); - } + ) { + unsafe { (self.EnzymeTypeTreeInsertEq)(tree, indices, len, ct, ctx) } + } - unsafe extern "C" { - static mut EnzymePrintPerf: c_void; - static mut EnzymePrintActivity: c_void; - static mut EnzymePrintType: c_void; - static mut EnzymeFunctionToAnalyze: c_void; - static mut EnzymePrint: c_void; - static mut EnzymeStrictAliasing: c_void; - static mut looseTypeAnalysis: c_void; - static mut EnzymeInline: c_void; - static mut RustTypeRules: c_void; - } - pub(crate) fn set_print_perf(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8); + pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char { + unsafe { (self.EnzymeTypeTreeToString)(tree) } } - } - pub(crate) fn set_print_activity(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8); + + pub(crate) fn tree_to_string_free(&self, ch: *const c_char) { + unsafe { (self.EnzymeTypeTreeToStringFree)(ch) } } - } - pub(crate) fn set_print_type(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8); + + pub(crate) fn get_max_type_depth(&self) -> usize { + unsafe { std::ptr::read::(self.EnzymeMaxTypeDepth as *const u32) as usize } } - } - pub(crate) fn set_print_type_fun(fun_name: &str) { - let c_fun_name = CString::new(fun_name).unwrap(); - unsafe { - EnzymeSetCLString( - std::ptr::addr_of_mut!(EnzymeFunctionToAnalyze), - c_fun_name.as_ptr() as *const c_char, + + pub(crate) fn set_print_perf(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrintPerf, print as u8); + } + } + + pub(crate) fn set_print_activity(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrintActivity, print as u8); + } + } + + pub(crate) fn set_print_type(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrintType, print as u8); + } + } + + pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) { + let c_fun_name = std::ffi::CString::new(fun_name) + .unwrap_or_else(|err| bug!("failed to set_print_type_fun: {err}")); + unsafe { + (self.EnzymeSetCLString)( + self.EnzymeFunctionToAnalyze, + c_fun_name.as_ptr() as *const c_char, + ); + } + } + + pub(crate) fn set_print(&mut self, print: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymePrint, print as u8); + } + } + + pub(crate) fn set_strict_aliasing(&mut self, strict: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymeStrictAliasing, strict as u8); + } + } + + pub(crate) fn set_loose_types(&mut self, loose: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.looseTypeAnalysis, loose as u8); + } + } + + pub(crate) fn set_inline(&mut self, val: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.EnzymeInline, val as u8); + } + } + + pub(crate) fn set_rust_rules(&mut self, val: bool) { + unsafe { + (self.EnzymeSetCLBool)(self.RustTypeRules, val as u8); + } + } + + #[allow(non_snake_case)] + fn call_dynamic( + sysroot: &rustc_session::config::Sysroot, + ) -> Result { + let enzyme_path = Self::get_enzyme_path(sysroot)?; + let lib = unsafe { libloading::Library::new(enzyme_path)? }; + + load_ptrs_by_symbols_fn!( + lib, + EnzymeNewTypeTree: EnzymeNewTypeTreeFn, + EnzymeNewTypeTreeCT: EnzymeNewTypeTreeCTFn, + EnzymeNewTypeTreeTR: EnzymeNewTypeTreeTRFn, + EnzymeFreeTypeTree: EnzymeFreeTypeTreeFn, + EnzymeMergeTypeTree: EnzymeMergeTypeTreeFn, + EnzymeTypeTreeOnlyEq: EnzymeTypeTreeOnlyEqFn, + EnzymeTypeTreeData0Eq: EnzymeTypeTreeData0EqFn, + EnzymeTypeTreeShiftIndiciesEq: EnzymeTypeTreeShiftIndiciesEqFn, + EnzymeTypeTreeInsertEq: EnzymeTypeTreeInsertEqFn, + EnzymeTypeTreeToString: EnzymeTypeTreeToStringFn, + EnzymeTypeTreeToStringFree: EnzymeTypeTreeToStringFreeFn, + EnzymeSetCLBool: EnzymeSetCLBoolFn, + EnzymeSetCLString: EnzymeSetCLStringFn, ); + + load_ptrs_by_symbols_mut_void!( + lib, + registerEnzymeAndPassPipeline, + EnzymePrintPerf, + EnzymePrintActivity, + EnzymePrintType, + EnzymeFunctionToAnalyze, + EnzymePrint, + EnzymeStrictAliasing, + EnzymeInline, + EnzymeMaxTypeDepth, + RustTypeRules, + looseTypeAnalysis, + ); + + Ok(Self { + EnzymeNewTypeTree, + EnzymeNewTypeTreeCT, + EnzymeNewTypeTreeTR, + EnzymeFreeTypeTree, + EnzymeMergeTypeTree, + EnzymeTypeTreeOnlyEq, + EnzymeTypeTreeData0Eq, + EnzymeTypeTreeShiftIndiciesEq, + EnzymeTypeTreeInsertEq, + EnzymeTypeTreeToString, + EnzymeTypeTreeToStringFree, + EnzymePrintPerf, + EnzymePrintActivity, + EnzymePrintType, + EnzymeFunctionToAnalyze, + EnzymePrint, + EnzymeStrictAliasing, + EnzymeInline, + EnzymeMaxTypeDepth, + RustTypeRules, + looseTypeAnalysis, + EnzymeSetCLBool, + EnzymeSetCLString, + registerEnzymeAndPassPipeline, + lib, + }) } - } - pub(crate) fn set_print(print: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8); + + fn get_enzyme_path(sysroot: &Sysroot) -> Result { + let llvm_version_major = unsafe { LLVMRustVersionMajor() }; + + let path_buf = sysroot + .all_paths() + .map(|sysroot_path| { + filesearch::make_target_lib_path(sysroot_path, host_tuple()) + .join("lib") + .with_file_name(format!("libEnzyme-{llvm_version_major}")) + .with_extension(std::env::consts::DLL_EXTENSION) + }) + .find(|f| f.exists()) + .ok_or_else(|| { + let candidates = sysroot + .all_paths() + .map(|p| p.join("lib").display().to_string()) + .collect::>() + .join("\n* "); + EnzymeLibraryError::NotFound { + err: format!( + "failed to find a `libEnzyme-{llvm_version_major}` folder \ + in the sysroot candidates:\n* {candidates}" + ), + } + })?; + + Ok(path_buf + .to_str() + .ok_or_else(|| EnzymeLibraryError::LoadFailed { + err: format!("invalid UTF-8 in path: {}", path_buf.display()), + })? + .to_string()) } } - pub(crate) fn set_strict_aliasing(strict: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8); - } - } - pub(crate) fn set_loose_types(loose: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8); - } - } - pub(crate) fn set_inline(val: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8); - } - } - pub(crate) fn set_rust_rules(val: bool) { - unsafe { - EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8); - } - } -} - -#[cfg(not(feature = "llvm_enzyme"))] -pub(crate) use self::Fallback_AD::*; - -#[cfg(not(feature = "llvm_enzyme"))] -pub(crate) mod Fallback_AD { - #![allow(unused_variables)] - - use libc::c_char; - - use super::{CConcreteType, CTypeTreeRef, Context}; - - // TypeTree function fallbacks - pub(crate) unsafe fn EnzymeNewTypeTree() -> CTypeTreeRef { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeFreeTypeTree(CTT: CTypeTreeRef) { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64) { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef) { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeTypeTreeShiftIndiciesEq( - arg1: CTypeTreeRef, - data_layout: *const c_char, - offset: i64, - max_size: i64, - add_offset: u64, - ) { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeTypeTreeInsertEq( - CTT: CTypeTreeRef, - indices: *const i64, - len: usize, - ct: CConcreteType, - ctx: &Context, - ) { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char { - unimplemented!() - } - - pub(crate) unsafe fn EnzymeTypeTreeToStringFree(arg1: *const c_char) { - unimplemented!() - } - - pub(crate) fn set_inline(val: bool) { - unimplemented!() - } - pub(crate) fn set_print_perf(print: bool) { - unimplemented!() - } - pub(crate) fn set_print_activity(print: bool) { - unimplemented!() - } - pub(crate) fn set_print_type(print: bool) { - unimplemented!() - } - pub(crate) fn set_print_type_fun(fun_name: &str) { - unimplemented!() - } - pub(crate) fn set_print(print: bool) { - unimplemented!() - } - pub(crate) fn set_strict_aliasing(strict: bool) { - unimplemented!() - } - pub(crate) fn set_loose_types(loose: bool) { - unimplemented!() - } - pub(crate) fn set_rust_rules(val: bool) { - unimplemented!() - } } impl TypeTree { pub(crate) fn new() -> TypeTree { - let inner = unsafe { EnzymeNewTypeTree() }; + let wrapper = EnzymeWrapper::get_instance(); + let inner = wrapper.new_type_tree(); TypeTree { inner } } pub(crate) fn from_type(t: CConcreteType, ctx: &Context) -> TypeTree { - let inner = unsafe { EnzymeNewTypeTreeCT(t, ctx) }; + let wrapper = EnzymeWrapper::get_instance(); + let inner = wrapper.new_type_tree_ct(t, ctx); TypeTree { inner } } pub(crate) fn merge(self, other: Self) -> Self { - unsafe { - EnzymeMergeTypeTree(self.inner, other.inner); - } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.merge_type_tree(self.inner, other.inner); drop(other); self } @@ -316,37 +493,36 @@ impl TypeTree { add_offset: usize, ) -> Self { let layout = std::ffi::CString::new(layout).unwrap(); - - unsafe { - EnzymeTypeTreeShiftIndiciesEq( - self.inner, - layout.as_ptr(), - offset as i64, - max_size as i64, - add_offset as u64, - ); - } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.shift_indicies_eq( + self.inner, + layout.as_ptr(), + offset as i64, + max_size as i64, + add_offset as u64, + ); self } pub(crate) fn insert(&mut self, indices: &[i64], ct: CConcreteType, ctx: &Context) { - unsafe { - EnzymeTypeTreeInsertEq(self.inner, indices.as_ptr(), indices.len(), ct, ctx); - } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.tree_insert_eq(self.inner, indices.as_ptr(), indices.len(), ct, ctx); } } impl Clone for TypeTree { fn clone(&self) -> Self { - let inner = unsafe { EnzymeNewTypeTreeTR(self.inner) }; + let wrapper = EnzymeWrapper::get_instance(); + let inner = wrapper.new_type_tree_tr(self.inner); TypeTree { inner } } } impl std::fmt::Display for TypeTree { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let ptr = unsafe { EnzymeTypeTreeToString(self.inner) }; + let wrapper = EnzymeWrapper::get_instance(); + let ptr = wrapper.tree_to_string(self.inner); let cstr = unsafe { std::ffi::CStr::from_ptr(ptr) }; match cstr.to_str() { Ok(x) => write!(f, "{}", x)?, @@ -354,9 +530,7 @@ impl std::fmt::Display for TypeTree { } // delete C string pointer - unsafe { - EnzymeTypeTreeToStringFree(ptr); - } + wrapper.tree_to_string_free(ptr); Ok(()) } @@ -370,6 +544,7 @@ impl std::fmt::Debug for TypeTree { impl Drop for TypeTree { fn drop(&mut self) { - unsafe { EnzymeFreeTypeTree(self.inner) } + let wrapper = EnzymeWrapper::get_instance(); + wrapper.free_type_tree(self.inner) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index c5cbc92ae772..4956549f2ed3 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -167,6 +167,7 @@ pub(crate) enum CallConv { PreserveMost = 14, PreserveAll = 15, Tail = 18, + PreserveNone = 21, X86StdcallCallConv = 64, X86FastcallCallConv = 65, ArmAapcsCallConv = 67, @@ -363,33 +364,6 @@ pub(crate) enum TypeKind { X86_AMX = 19, } -impl TypeKind { - pub(crate) fn to_generic(self) -> rustc_codegen_ssa::common::TypeKind { - use rustc_codegen_ssa::common::TypeKind as Common; - match self { - Self::Void => Common::Void, - Self::Half => Common::Half, - Self::Float => Common::Float, - Self::Double => Common::Double, - Self::X86_FP80 => Common::X86_FP80, - Self::FP128 => Common::FP128, - Self::PPC_FP128 => Common::PPC_FP128, - Self::Label => Common::Label, - Self::Integer => Common::Integer, - Self::Function => Common::Function, - Self::Struct => Common::Struct, - Self::Array => Common::Array, - Self::Pointer => Common::Pointer, - Self::Vector => Common::Vector, - Self::Metadata => Common::Metadata, - Self::Token => Common::Token, - Self::ScalableVector => Common::ScalableVector, - Self::BFloat => Common::BFloat, - Self::X86_AMX => Common::X86_AMX, - } - } -} - /// LLVMAtomicRmwBinOp #[derive(Copy, Clone)] #[repr(C)] @@ -738,12 +712,9 @@ unsafe extern "C" { pub(crate) type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void); pub(crate) mod debuginfo { - use std::ptr; - use bitflags::bitflags; use super::{InvariantOpaque, Metadata}; - use crate::llvm::{self, Module}; /// Opaque target type for references to an LLVM debuginfo builder. /// @@ -756,33 +727,6 @@ pub(crate) mod debuginfo { #[repr(C)] pub(crate) struct DIBuilder<'ll>(InvariantOpaque<'ll>); - /// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder - /// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder` - /// needed for debuginfo FFI calls. - pub(crate) struct DIBuilderBox<'ll> { - raw: ptr::NonNull>, - } - - impl<'ll> DIBuilderBox<'ll> { - pub(crate) fn new(llmod: &'ll Module) -> Self { - let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) }; - let raw = ptr::NonNull::new(raw).unwrap(); - Self { raw } - } - - pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> { - // SAFETY: This is an owning pointer, so `&DIBuilder` is valid - // for as long as `&self` is. - unsafe { self.raw.as_ref() } - } - } - - impl<'ll> Drop for DIBuilderBox<'ll> { - fn drop(&mut self) { - unsafe { llvm::LLVMDisposeDIBuilder(self.raw) }; - } - } - pub(crate) type DIDescriptor = Metadata; pub(crate) type DILocation = Metadata; pub(crate) type DIScope = DIDescriptor; @@ -998,6 +942,7 @@ unsafe extern "C" { // Operations on array, pointer, and vector types (sequence types) pub(crate) safe fn LLVMPointerTypeInContext(C: &Context, AddressSpace: c_uint) -> &Type; pub(crate) fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type; + pub(crate) fn LLVMScalableVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type; pub(crate) fn LLVMGetElementType(Ty: &Type) -> &Type; pub(crate) fn LLVMGetVectorSize(VectorTy: &Type) -> c_uint; @@ -1722,8 +1667,20 @@ mod Offload { use super::*; unsafe extern "C" { /// Processes the module and writes it in an offload compatible way into a "host.out" file. - pub(crate) fn LLVMRustBundleImages<'a>(M: &'a Module, TM: &'a TargetMachine) -> bool; - pub(crate) fn LLVMRustOffloadMapper<'a>(OldFn: &'a Value, NewFn: &'a Value); + pub(crate) fn LLVMRustBundleImages<'a>( + M: &'a Module, + TM: &'a TargetMachine, + host_out: *const c_char, + ) -> bool; + pub(crate) unsafe fn LLVMRustOffloadEmbedBufferInModule<'a>( + _M: &'a Module, + _host_out: *const c_char, + ) -> bool; + pub(crate) fn LLVMRustOffloadMapper<'a>( + OldFn: &'a Value, + NewFn: &'a Value, + RebuiltArgs: *const &Value, + ); } } @@ -1736,11 +1693,25 @@ mod Offload_fallback { /// Processes the module and writes it in an offload compatible way into a "host.out" file. /// Marked as unsafe to match the real offload wrapper which is unsafe due to FFI. #[allow(unused_unsafe)] - pub(crate) unsafe fn LLVMRustBundleImages<'a>(_M: &'a Module, _TM: &'a TargetMachine) -> bool { + pub(crate) unsafe fn LLVMRustBundleImages<'a>( + _M: &'a Module, + _TM: &'a TargetMachine, + _host_out: *const c_char, + ) -> bool { + unimplemented!("This rustc version was not built with LLVM Offload support!"); + } + pub(crate) unsafe fn LLVMRustOffloadEmbedBufferInModule<'a>( + _M: &'a Module, + _host_out: *const c_char, + ) -> bool { unimplemented!("This rustc version was not built with LLVM Offload support!"); } #[allow(unused_unsafe)] - pub(crate) unsafe fn LLVMRustOffloadMapper<'a>(_OldFn: &'a Value, _NewFn: &'a Value) { + pub(crate) unsafe fn LLVMRustOffloadMapper<'a>( + _OldFn: &'a Value, + _NewFn: &'a Value, + _RebuiltArgs: *const &Value, + ) { unimplemented!("This rustc version was not built with LLVM Offload support!"); } } @@ -1997,6 +1968,7 @@ unsafe extern "C" { Metadata: &'a Metadata, ); pub(crate) fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool; + pub(crate) fn LLVMRustStripPointerCasts<'a>(Val: &'a Value) -> &'a Value; // Operations on scalar constants pub(crate) fn LLVMRustConstIntGetZExtValue(ConstantVal: &ConstantInt, Value: &mut u64) -> bool; @@ -2376,6 +2348,7 @@ unsafe extern "C" { DebugInfoCompression: CompressionKind, UseEmulatedTls: bool, UseWasmEH: bool, + LargeDataThreshold: u64, ) -> *mut TargetMachine; pub(crate) fn LLVMRustAddLibraryInfo<'a>( @@ -2411,7 +2384,7 @@ unsafe extern "C" { LoopVectorize: bool, DisableSimplifyLibCalls: bool, EmitLifetimeMarkers: bool, - RunEnzyme: bool, + RunEnzyme: *const c_void, PrintBeforeEnzyme: bool, PrintAfterEnzyme: bool, PrintPasses: bool, @@ -2481,8 +2454,6 @@ unsafe extern "C" { pub(crate) fn LLVMRustPositionBuilderPastAllocas<'a>(B: &Builder<'a>, Fn: &'a Value); pub(crate) fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock); - pub(crate) fn LLVMRustGetInsertPoint<'a>(B: &Builder<'a>) -> &'a Value; - pub(crate) fn LLVMRustRestoreInsertPoint<'a>(B: &Builder<'a>, IP: &'a Value); pub(crate) fn LLVMRustSetModulePICLevel(M: &Module); pub(crate) fn LLVMRustSetModulePIELevel(M: &Module); @@ -2492,7 +2463,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize; pub(crate) fn LLVMRustModuleBufferFree(p: &'static mut ModuleBuffer); pub(crate) fn LLVMRustModuleCost(M: &Module) -> u64; - pub(crate) fn LLVMRustModuleInstructionStats(M: &Module, Str: &RustString); + pub(crate) fn LLVMRustModuleInstructionStats(M: &Module) -> u64; pub(crate) fn LLVMRustThinLTOBufferCreate( M: &Module, @@ -2583,4 +2554,12 @@ unsafe extern "C" { pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value); pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value); + + pub(crate) fn LLVMAddAlias2<'ll>( + M: &'ll Module, + ValueTy: &Type, + AddressSpace: c_uint, + Aliasee: &Value, + Name: *const c_char, + ) -> &'ll Value; } diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index 55a4b415a4e2..621004e756ec 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -6,7 +6,7 @@ use std::ptr; use std::string::FromUtf8Error; use libc::c_uint; -use rustc_abi::{Align, Size, WrappingRange}; +use rustc_abi::{AddressSpace, Align, Size, WrappingRange}; use rustc_llvm::RustString; pub(crate) use self::CallConv::*; @@ -452,3 +452,14 @@ pub(crate) fn append_module_inline_asm<'ll>(llmod: &'ll Module, asm: &[u8]) { LLVMAppendModuleInlineAsm(llmod, asm.as_ptr(), asm.len()); } } + +/// Safe wrapper for `LLVMAddAlias2` +pub(crate) fn add_alias<'ll>( + module: &'ll Module, + ty: &Type, + address_space: AddressSpace, + aliasee: &Value, + name: &CStr, +) -> &'ll Value { + unsafe { LLVMAddAlias2(module, ty, address_space.0, aliasee, name.as_ptr()) } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 682484595a89..fbb582fe8601 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -262,10 +262,19 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("crypto")), s => Some(LLVMFeature::new(s)), }, + Arch::RiscV32 | Arch::RiscV64 => match s { + // Filter out Rust-specific *virtual* target feature + "zkne_or_zknd" => None, + s => Some(LLVMFeature::new(s)), + }, Arch::Sparc | Arch::Sparc64 => match s { "leoncasa" => Some(LLVMFeature::new("hasleoncasa")), s => Some(LLVMFeature::new(s)), }, + Arch::Wasm32 | Arch::Wasm64 => match s { + "gc" if major < 22 => None, + s => Some(LLVMFeature::new(s)), + }, Arch::X86 | Arch::X86_64 => { match s { "sse4.2" => Some(LLVMFeature::with_dependencies( @@ -278,12 +287,12 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("cx16")), "lahfsahf" => Some(LLVMFeature::new("sahf")), // Enable the evex512 target feature if an avx512 target feature is enabled. - s if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies( + s if s.starts_with("avx512") && major < 22 => Some(LLVMFeature::with_dependencies( s, smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")], )), - "avx10.1" => Some(LLVMFeature::new("avx10.1-512")), - "avx10.2" => Some(LLVMFeature::new("avx10.2-512")), + "avx10.1" if major < 22 => Some(LLVMFeature::new("avx10.1-512")), + "avx10.2" if major < 22 => Some(LLVMFeature::new("avx10.2-512")), "apxf" => Some(LLVMFeature::with_dependencies( "egpr", smallvec![ @@ -360,28 +369,29 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { let target_abi = &sess.target.options.abi; let target_pointer_width = sess.target.pointer_width; let version = get_version(); - let lt_20_1_1 = version < (20, 1, 1); - let lt_21_0_0 = version < (21, 0, 0); + let (major, _, _) = version; cfg.has_reliable_f16 = match (target_arch, target_os) { - // LLVM crash without neon (fixed in llvm20) + // LLVM crash without neon (fixed in LLVM 20.1.1) (Arch::AArch64, _) - if !cfg.target_features.iter().any(|f| f.as_str() == "neon") && lt_20_1_1 => + if !cfg.target_features.iter().any(|f| f.as_str() == "neon") + && version < (20, 1, 1) => { false } - // Unsupported - (Arch::Arm64EC, _) => false, + // Unsupported (fixed in llvm22) + (Arch::Arm64EC, _) if major < 22 => false, // Selection failure (fixed in llvm21) - (Arch::S390x, _) if lt_21_0_0 => false, + (Arch::S390x, _) if major < 21 => false, // MinGW ABI bugs (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // Infinite recursion - (Arch::CSky, _) => false, - (Arch::Hexagon, _) if lt_21_0_0 => false, // (fixed in llvm21) - (Arch::PowerPC | Arch::PowerPC64, _) => false, - (Arch::Sparc | Arch::Sparc64, _) => false, - (Arch::Wasm32 | Arch::Wasm64, _) => false, + (Arch::CSky, _) if major < 22 => false, // (fixed in llvm22) + (Arch::Hexagon, _) if major < 21 => false, // (fixed in llvm21) + (Arch::LoongArch32 | Arch::LoongArch64, _) if major < 21 => false, // (fixed in llvm21) + (Arch::PowerPC | Arch::PowerPC64, _) if major < 22 => false, // (fixed in llvm22) + (Arch::Sparc | Arch::Sparc64, _) if major < 22 => false, // (fixed in llvm22) + (Arch::Wasm32 | Arch::Wasm64, _) if major < 22 => false, // (fixed in llvm22) // `f16` support only requires that symbols converting to and from `f32` are available. We // provide these in `compiler-builtins`, so `f16` should be available on all platforms that // do not have other ABI issues or LLVM crashes. @@ -389,15 +399,15 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { }; cfg.has_reliable_f128 = match (target_arch, target_os) { + // Unsupported https://github.com/llvm/llvm-project/issues/121122 + (Arch::AmdGpu, _) => false, // Unsupported (Arch::Arm64EC, _) => false, - // Selection bug (fixed in llvm20) - (Arch::Mips64 | Arch::Mips64r6, _) if lt_20_1_1 => false, + // Selection bug (fixed in LLVM 20.1.0) + (Arch::Mips64 | Arch::Mips64r6, _) if version < (20, 1, 0) => false, // Selection bug . This issue is closed // but basic math still does not work. (Arch::Nvptx64, _) => false, - // Unsupported https://github.com/llvm/llvm-project/issues/121122 - (Arch::AmdGpu, _) => false, // ABI bugs et al. (full // list at ) (Arch::PowerPC | Arch::PowerPC64, _) => false, @@ -405,7 +415,7 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) { (Arch::Sparc, _) => false, // Stack alignment bug . NB: tests may // not fail if our compiler-builtins is linked. (fixed in llvm21) - (Arch::X86, _) if lt_21_0_0 => false, + (Arch::X86, _) if major < 21 => false, // MinGW ABI bugs (Arch::X86_64, Os::Windows) if *target_env == Env::Gnu && *target_abi != Abi::Llvm => false, // There are no known problems on other platforms, so the only requirement is that symbols diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 4184ced74962..1a8fbf67f0bc 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -1,3 +1,6 @@ +use std::ffi::CString; + +use rustc_abi::AddressSpace; use rustc_codegen_ssa::traits::*; use rustc_hir::attrs::Linkage; use rustc_hir::def::DefKind; @@ -38,9 +41,13 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { }); llvm::set_linkage(g, base::linkage_to_llvm(linkage)); - llvm::set_visibility(g, base::visibility_to_llvm(visibility)); + self.set_visibility(g, linkage, visibility); + self.assume_dso_local(g, false); + let attrs = self.tcx.codegen_instance_attrs(instance.def); + self.add_aliases(g, &attrs.foreign_item_symbol_aliases); + self.instances.borrow_mut().insert(instance, g); } @@ -63,27 +70,40 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { { llvm::SetUniqueComdat(self.llmod, lldecl); } - - // If we're compiling the compiler-builtins crate, e.g., the equivalent of - // compiler-rt, then we want to implicitly compile everything with hidden - // visibility as we're going to link this object all over the place but - // don't want the symbols to get exported. - if linkage != Linkage::Internal && self.tcx.is_compiler_builtins(LOCAL_CRATE) { - llvm::set_visibility(lldecl, llvm::Visibility::Hidden); - } else { - llvm::set_visibility(lldecl, base::visibility_to_llvm(visibility)); - } + self.set_visibility(lldecl, linkage, visibility); debug!("predefine_fn: instance = {:?}", instance); self.assume_dso_local(lldecl, false); + self.add_aliases(lldecl, &attrs.foreign_item_symbol_aliases); + self.instances.borrow_mut().insert(instance, lldecl); } } impl CodegenCx<'_, '_> { - /// Whether a definition or declaration can be assumed to be local to a group of + fn add_aliases(&self, aliasee: &llvm::Value, aliases: &[(DefId, Linkage, Visibility)]) { + let ty = self.get_type_of_global(aliasee); + + for (alias, linkage, visibility) in aliases { + let symbol_name = self.tcx.symbol_name(Instance::mono(self.tcx, *alias)); + + tracing::debug!("ALIAS: {alias:?} {linkage:?} {visibility:?}"); + let lldecl = llvm::add_alias( + self.llmod, + ty, + AddressSpace::ZERO, + aliasee, + &CString::new(symbol_name.name).unwrap(), + ); + + llvm::set_visibility(lldecl, base::visibility_to_llvm(*visibility)); + llvm::set_linkage(lldecl, base::linkage_to_llvm(*linkage)); + } + } + + /// A definition or declaration can be assumed to be local to a group of /// libraries that form a single DSO or executable. /// Marks the local as DSO if so. pub(crate) fn assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool { @@ -94,6 +114,18 @@ impl CodegenCx<'_, '_> { assume } + fn set_visibility(&self, lldecl: &llvm::Value, linkage: Linkage, visibility: Visibility) { + // If we're compiling the compiler-builtins crate, i.e., the equivalent of + // compiler-rt, then we want to implicitly compile everything with hidden + // visibility as we're going to link this object all over the place but + // don't want the symbols to get exported. + if linkage != Linkage::Internal && self.tcx.is_compiler_builtins(LOCAL_CRATE) { + llvm::set_visibility(lldecl, llvm::Visibility::Hidden); + } else { + llvm::set_visibility(lldecl, base::visibility_to_llvm(visibility)); + } + } + fn should_assume_dso_local(&self, llval: &llvm::Value, is_declaration: bool) -> bool { let linkage = llvm::get_linkage(llval); let visibility = llvm::get_visibility(llval); @@ -116,7 +148,7 @@ impl CodegenCx<'_, '_> { } // PowerPC64 prefers TOC indirection to avoid copy relocations. - if matches!(self.tcx.sess.target.arch, Arch::PowerPC64 | Arch::PowerPC64LE) { + if self.tcx.sess.target.arch == Arch::PowerPC64 { return false; } @@ -125,7 +157,7 @@ impl CodegenCx<'_, '_> { return false; } - // With pie relocation model calls of functions defined in the translation + // With pie relocation model, calls of functions defined in the translation // unit can use copy relocations. if self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration { return true; diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 55f053f4fad3..d8b77369a34f 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -15,7 +15,7 @@ use rustc_target::callconv::{CastTarget, FnAbi}; use crate::abi::{FnAbiLlvmExt, LlvmType}; use crate::common; use crate::context::{CodegenCx, GenericCx, SCx}; -use crate::llvm::{self, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value}; +use crate::llvm::{self, FALSE, Metadata, TRUE, ToGeneric, ToLlvmBool, Type, Value}; use crate::type_of::LayoutLlvmExt; impl PartialEq for Type { @@ -68,6 +68,10 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { unsafe { llvm::LLVMVectorType(ty, len as c_uint) } } + pub(crate) fn type_scalable_vector(&self, ty: &'ll Type, count: u64) -> &'ll Type { + unsafe { llvm::LLVMScalableVectorType(ty, count as c_uint) } + } + pub(crate) fn add_func(&self, name: &str, ty: &'ll Type) -> &'ll Value { let name = SmallCStr::new(name); unsafe { llvm::LLVMAddFunction(self.llmod(), name.as_ptr(), ty) } diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 2b2ac1c6eb29..1ed06fbd2821 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -24,6 +24,15 @@ fn uncached_llvm_type<'a, 'tcx>( let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } + BackendRepr::ScalableVector { ref element, count } => { + let element = if element.is_bool() { + cx.type_i1() + } else { + layout.scalar_llvm_type_at(cx, *element) + }; + + return cx.type_scalable_vector(element, count); + } BackendRepr::Memory { .. } | BackendRepr::ScalarPair(..) => {} } @@ -176,7 +185,9 @@ pub(crate) trait LayoutLlvmExt<'tcx> { impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn is_llvm_immediate(&self) -> bool { match self.backend_repr { - BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, + BackendRepr::Scalar(_) + | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } => true, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -186,6 +197,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { BackendRepr::ScalarPair(..) => true, BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_llvm/src/typetree.rs b/compiler/rustc_codegen_llvm/src/typetree.rs index 7e2635037008..4f433f273c8c 100644 --- a/compiler/rustc_codegen_llvm/src/typetree.rs +++ b/compiler/rustc_codegen_llvm/src/typetree.rs @@ -1,14 +1,10 @@ -use rustc_ast::expand::typetree::FncTree; -#[cfg(feature = "llvm_enzyme")] -use { - crate::attributes, - rustc_ast::expand::typetree::TypeTree as RustTypeTree, - std::ffi::{CString, c_char, c_uint}, -}; +use std::ffi::{CString, c_char, c_uint}; -use crate::llvm::{self, Value}; +use rustc_ast::expand::typetree::{FncTree, TypeTree as RustTypeTree}; + +use crate::attributes; +use crate::llvm::{self, EnzymeWrapper, Value}; -#[cfg(feature = "llvm_enzyme")] fn to_enzyme_typetree( rust_typetree: RustTypeTree, _data_layout: &str, @@ -18,7 +14,6 @@ fn to_enzyme_typetree( process_typetree_recursive(&mut enzyme_tt, &rust_typetree, &[], llcx); enzyme_tt } -#[cfg(feature = "llvm_enzyme")] fn process_typetree_recursive( enzyme_tt: &mut llvm::TypeTree, rust_typetree: &RustTypeTree, @@ -56,13 +51,21 @@ fn process_typetree_recursive( } } -#[cfg(feature = "llvm_enzyme")] +#[cfg_attr(not(feature = "llvm_enzyme"), allow(unused))] pub(crate) fn add_tt<'ll>( llmod: &'ll llvm::Module, llcx: &'ll llvm::Context, fn_def: &'ll Value, tt: FncTree, ) { + // TypeTree processing uses functions from Enzyme, which we might not have available if we did + // not build this compiler with `llvm_enzyme`. This feature is not strictly necessary, but + // skipping this function increases the chance that Enzyme fails to compile some code. + // FIXME(autodiff): In the future we should conditionally run this function even without the + // `llvm_enzyme` feature, in case that libEnzyme was provided via rustup. + #[cfg(not(feature = "llvm_enzyme"))] + return; + let inputs = tt.args; let ret_tt: RustTypeTree = tt.ret; @@ -77,7 +80,8 @@ pub(crate) fn add_tt<'ll>( for (i, input) in inputs.iter().enumerate() { unsafe { let enzyme_tt = to_enzyme_typetree(input.clone(), llvm_data_layout, llcx); - let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner); + let enzyme_wrapper = EnzymeWrapper::get_instance(); + let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner); let c_str = std::ffi::CStr::from_ptr(c_str); let attr = llvm::LLVMCreateStringAttribute( @@ -89,13 +93,14 @@ pub(crate) fn add_tt<'ll>( ); attributes::apply_to_llfn(fn_def, llvm::AttributePlace::Argument(i as u32), &[attr]); - llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr()); + enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); } } unsafe { let enzyme_tt = to_enzyme_typetree(ret_tt, llvm_data_layout, llcx); - let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner); + let enzyme_wrapper = EnzymeWrapper::get_instance(); + let c_str = enzyme_wrapper.tree_to_string(enzyme_tt.inner); let c_str = std::ffi::CStr::from_ptr(c_str); let ret_attr = llvm::LLVMCreateStringAttribute( @@ -107,16 +112,6 @@ pub(crate) fn add_tt<'ll>( ); attributes::apply_to_llfn(fn_def, llvm::AttributePlace::ReturnValue, &[ret_attr]); - llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr()); + enzyme_wrapper.tree_to_string_free(c_str.as_ptr()); } } - -#[cfg(not(feature = "llvm_enzyme"))] -pub(crate) fn add_tt<'ll>( - _llmod: &'ll llvm::Module, - _llcx: &'ll llvm::Context, - _fn_def: &'ll Value, - _tt: FncTree, -) { - unimplemented!() -} diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index add25da025b2..460f4afea963 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -1,13 +1,14 @@ -use rustc_abi::{Align, BackendRepr, Endian, HasDataLayout, Primitive, Size, TyAndLayout}; +use rustc_abi::{Align, BackendRepr, Endian, HasDataLayout, Primitive, Size}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, LayoutTypeCodegenMethods, }; +use rustc_middle::bug; use rustc_middle::ty::Ty; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; -use rustc_target::spec::{Abi, Arch}; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; +use rustc_target::spec::{Abi, Arch, Env}; use crate::builder::Builder; use crate::llvm::{Type, Value}; @@ -82,6 +83,7 @@ enum PassMode { enum SlotSize { Bytes8 = 8, Bytes4 = 4, + Bytes1 = 1, } enum AllowHigherAlign { @@ -129,7 +131,7 @@ fn emit_ptr_va_arg<'ll, 'tcx>( ); if indirect { let tmp_ret = bx.load(llty, addr, addr_align); - bx.load(bx.cx.layout_of(target_ty).llvm_type(bx.cx), tmp_ret, align.abi) + bx.load(layout.llvm_type(bx.cx), tmp_ret, align.abi) } else { bx.load(llty, addr, addr_align) } @@ -549,7 +551,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( registers_for_primitive(scalar1.primitive()); registers_for_primitive(scalar2.primitive()); } - BackendRepr::SimdVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { // Because no instance of VaArgSafe uses a non-scalar `BackendRepr`. unreachable!( "No x86-64 SysV va_arg implementation for {:?}", @@ -689,7 +691,9 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( } } // The Previous match on `BackendRepr` means control flow already escaped. - BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } => unreachable!(), + BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } + | BackendRepr::Memory { .. } => unreachable!(), }; // AMD64-ABI 3.5.7p5: Step 5. Set: @@ -726,7 +730,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( fn copy_to_temporary_if_more_aligned<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, reg_addr: &'ll Value, - layout: TyAndLayout<'tcx, Ty<'tcx>>, + layout: TyAndLayout<'tcx>, src_align: Align, ) -> &'ll Value { if layout.layout.align.abi > src_align { @@ -749,7 +753,7 @@ fn copy_to_temporary_if_more_aligned<'ll, 'tcx>( fn x86_64_sysv64_va_arg_from_memory<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, va_list_addr: &'ll Value, - layout: TyAndLayout<'tcx, Ty<'tcx>>, + layout: TyAndLayout<'tcx>, ) -> &'ll Value { let dl = bx.cx.data_layout(); let ptr_align_abi = dl.data_layout().pointer_align().abi; @@ -780,6 +784,129 @@ fn x86_64_sysv64_va_arg_from_memory<'ll, 'tcx>( mem_addr } +fn emit_hexagon_va_arg_musl<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + list: OperandRef<'tcx, &'ll Value>, + target_ty: Ty<'tcx>, +) -> &'ll Value { + // Implementation of va_arg for Hexagon musl target. + // Based on LLVM's HexagonBuiltinVaList implementation. + // + // struct __va_list_tag { + // void *__current_saved_reg_area_pointer; + // void *__saved_reg_area_end_pointer; + // void *__overflow_area_pointer; + // }; + // + // All variadic arguments are passed on the stack, but the musl implementation + // uses a register save area for compatibility. + let va_list_addr = list.immediate(); + let layout = bx.cx.layout_of(target_ty); + let ptr_align_abi = bx.tcx().data_layout.pointer_align().abi; + let ptr_size = bx.tcx().data_layout.pointer_size().bytes(); + + // Check if argument fits in register save area + let maybe_reg = bx.append_sibling_block("va_arg.maybe_reg"); + let from_overflow = bx.append_sibling_block("va_arg.from_overflow"); + let end = bx.append_sibling_block("va_arg.end"); + + // Load the three pointers from va_list + let current_ptr_addr = va_list_addr; + let end_ptr_addr = bx.inbounds_ptradd(va_list_addr, bx.const_usize(ptr_size)); + let overflow_ptr_addr = bx.inbounds_ptradd(va_list_addr, bx.const_usize(2 * ptr_size)); + + let current_ptr = bx.load(bx.type_ptr(), current_ptr_addr, ptr_align_abi); + let end_ptr = bx.load(bx.type_ptr(), end_ptr_addr, ptr_align_abi); + let overflow_ptr = bx.load(bx.type_ptr(), overflow_ptr_addr, ptr_align_abi); + + // Align current pointer based on argument type size (following LLVM's implementation) + // Arguments <= 32 bits (4 bytes) use 4-byte alignment, > 32 bits use 8-byte alignment + let type_size_bits = bx.cx.size_of(target_ty).bits(); + let arg_align = if type_size_bits > 32 { + Align::from_bytes(8).unwrap() + } else { + Align::from_bytes(4).unwrap() + }; + let aligned_current = round_pointer_up_to_alignment(bx, current_ptr, arg_align, bx.type_ptr()); + + // Calculate next pointer position (following LLVM's logic) + // Arguments <= 32 bits take 4 bytes, > 32 bits take 8 bytes + let arg_size = if type_size_bits > 32 { 8 } else { 4 }; + let next_ptr = bx.inbounds_ptradd(aligned_current, bx.const_usize(arg_size)); + + // Check if argument fits in register save area + let fits_in_regs = bx.icmp(IntPredicate::IntULE, next_ptr, end_ptr); + bx.cond_br(fits_in_regs, maybe_reg, from_overflow); + + // Load from register save area + bx.switch_to_block(maybe_reg); + let reg_value_addr = aligned_current; + // Update current pointer + bx.store(next_ptr, current_ptr_addr, ptr_align_abi); + bx.br(end); + + // Load from overflow area (stack) + bx.switch_to_block(from_overflow); + + // Align overflow pointer using the same alignment rules + let aligned_overflow = + round_pointer_up_to_alignment(bx, overflow_ptr, arg_align, bx.type_ptr()); + + let overflow_value_addr = aligned_overflow; + // Update overflow pointer - use the same size calculation + let next_overflow = bx.inbounds_ptradd(aligned_overflow, bx.const_usize(arg_size)); + bx.store(next_overflow, overflow_ptr_addr, ptr_align_abi); + + // IMPORTANT: Also update the current saved register area pointer to match + // This synchronizes the pointers when switching to overflow area + bx.store(next_overflow, current_ptr_addr, ptr_align_abi); + bx.br(end); + + // Return the value + bx.switch_to_block(end); + let value_addr = + bx.phi(bx.type_ptr(), &[reg_value_addr, overflow_value_addr], &[maybe_reg, from_overflow]); + bx.load(layout.llvm_type(bx), value_addr, layout.align.abi) +} + +fn emit_hexagon_va_arg_bare_metal<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + list: OperandRef<'tcx, &'ll Value>, + target_ty: Ty<'tcx>, +) -> &'ll Value { + // Implementation of va_arg for Hexagon bare-metal (non-musl) targets. + // Based on LLVM's EmitVAArgForHexagon implementation. + // + // va_list is a simple pointer (char *) + let va_list_addr = list.immediate(); + let layout = bx.cx.layout_of(target_ty); + let ptr_align_abi = bx.tcx().data_layout.pointer_align().abi; + + // Load current pointer from va_list + let current_ptr = bx.load(bx.type_ptr(), va_list_addr, ptr_align_abi); + + // Handle address alignment for types with alignment > 4 bytes + let ty_align = layout.align.abi; + let aligned_ptr = if ty_align.bytes() > 4 { + // Ensure alignment is a power of 2 + debug_assert!(ty_align.bytes().is_power_of_two(), "Alignment is not power of 2!"); + round_pointer_up_to_alignment(bx, current_ptr, ty_align, bx.type_ptr()) + } else { + current_ptr + }; + + // Calculate offset: round up type size to 4-byte boundary (minimum stack slot size) + let type_size = layout.size.bytes(); + let offset = type_size.next_multiple_of(4); // align to 4 bytes + + // Update va_list to point to next argument + let next_ptr = bx.inbounds_ptradd(aligned_ptr, bx.const_usize(offset)); + bx.store(next_ptr, va_list_addr, ptr_align_abi); + + // Load and return the argument value + bx.load(layout.llvm_type(bx), aligned_ptr, layout.align.abi) +} + fn emit_xtensa_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, list: OperandRef<'tcx, &'ll Value>, @@ -878,15 +1005,23 @@ fn emit_xtensa_va_arg<'ll, 'tcx>( return bx.load(layout.llvm_type(bx), value_ptr, layout.align.abi); } +/// Determine the va_arg implementation to use. The LLVM va_arg instruction +/// is lacking in some instances, so we should only use it as a fallback. +/// +/// pub(super) fn emit_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, addr: OperandRef<'tcx, &'ll Value>, target_ty: Ty<'tcx>, ) -> &'ll Value { - // Determine the va_arg implementation to use. The LLVM va_arg instruction - // is lacking in some instances, so we should only use it as a fallback. - let target = &bx.cx.tcx.sess.target; + let layout = bx.cx.layout_of(target_ty); + let target_ty_size = layout.layout.size().bytes(); + // Some ABIs have special behavior for zero-sized types. currently `VaArgSafe` is not + // implemented for any zero-sized types, so this assert should always hold. + assert!(!bx.layout_of(target_ty).is_zst()); + + let target = &bx.cx.tcx.sess.target; match target.arch { Arch::X86 => emit_ptr_va_arg( bx, @@ -897,17 +1032,24 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, ForceRightAdjust::No, ), - Arch::AArch64 | Arch::Arm64EC if target.is_like_windows || target.is_like_darwin => { - emit_ptr_va_arg( - bx, - addr, - target_ty, - PassMode::Direct, - SlotSize::Bytes8, - if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, - ForceRightAdjust::No, - ) - } + Arch::Arm64EC => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes8, + if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, + ForceRightAdjust::No, + ), + Arch::AArch64 if target.is_like_windows || target.is_like_darwin => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes8, + if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes }, + ForceRightAdjust::No, + ), Arch::AArch64 => emit_aapcs_va_arg(bx, addr, target_ty), Arch::Arm => { // Types wider than 16 bytes are not currently supported. Clang has special logic for @@ -935,38 +1077,118 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( AllowHigherAlign::Yes, ForceRightAdjust::Yes, ), - Arch::PowerPC64LE => emit_ptr_va_arg( + Arch::RiscV32 if target.abi == Abi::Ilp32e => { + // FIXME: clang manually adjusts the alignment for this ABI. It notes: + // + // > To be compatible with GCC's behaviors, we force arguments with + // > 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`, + // > `unsigned long long` and `double` to have 4-byte alignment. This + // > behavior may be changed when RV32E/ILP32E is ratified. + bug!("c-variadic calls with ilp32e use a custom ABI and are not currently implemented"); + } + Arch::RiscV32 | Arch::LoongArch32 => emit_ptr_va_arg( bx, addr, target_ty, - PassMode::Direct, + if target_ty_size > 2 * 4 { PassMode::Indirect } else { PassMode::Direct }, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + Arch::RiscV64 | Arch::LoongArch64 => emit_ptr_va_arg( + bx, + addr, + target_ty, + if target_ty_size > 2 * 8 { PassMode::Indirect } else { PassMode::Direct }, SlotSize::Bytes8, AllowHigherAlign::Yes, ForceRightAdjust::No, ), + Arch::AmdGpu => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes4, + AllowHigherAlign::No, + ForceRightAdjust::No, + ), + Arch::Nvptx64 => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes1, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + Arch::Wasm32 | Arch::Wasm64 => emit_ptr_va_arg( + bx, + addr, + target_ty, + if layout.is_aggregate() || layout.is_zst() || layout.is_1zst() { + PassMode::Indirect + } else { + PassMode::Direct + }, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + Arch::CSky => emit_ptr_va_arg( + bx, + addr, + target_ty, + PassMode::Direct, + SlotSize::Bytes4, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), // Windows x86_64 - Arch::X86_64 if target.is_like_windows => { - let target_ty_size = bx.cx.size_of(target_ty).bytes(); - emit_ptr_va_arg( - bx, - addr, - target_ty, - if target_ty_size > 8 || !target_ty_size.is_power_of_two() { - PassMode::Indirect - } else { - PassMode::Direct - }, - SlotSize::Bytes8, - AllowHigherAlign::No, - ForceRightAdjust::No, - ) - } + Arch::X86_64 if target.is_like_windows => emit_ptr_va_arg( + bx, + addr, + target_ty, + if target_ty_size > 8 || !target_ty_size.is_power_of_two() { + PassMode::Indirect + } else { + PassMode::Direct + }, + SlotSize::Bytes8, + AllowHigherAlign::No, + ForceRightAdjust::No, + ), // This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64. Arch::X86_64 => emit_x86_64_sysv64_va_arg(bx, addr, target_ty), Arch::Xtensa => emit_xtensa_va_arg(bx, addr, target_ty), - // For all other architecture/OS combinations fall back to using - // the LLVM va_arg instruction. - // https://llvm.org/docs/LangRef.html#va-arg-instruction - _ => bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)), + Arch::Hexagon => match target.env { + Env::Musl => emit_hexagon_va_arg_musl(bx, addr, target_ty), + _ => emit_hexagon_va_arg_bare_metal(bx, addr, target_ty), + }, + Arch::Sparc64 => emit_ptr_va_arg( + bx, + addr, + target_ty, + if target_ty_size > 2 * 8 { PassMode::Indirect } else { PassMode::Direct }, + SlotSize::Bytes8, + AllowHigherAlign::Yes, + ForceRightAdjust::No, + ), + + Arch::Bpf => bug!("bpf does not support c-variadic functions"), + Arch::SpirV => bug!("spirv does not support c-variadic functions"), + + Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => { + // FIXME: port MipsTargetLowering::lowerVAARG. + bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + } + Arch::Sparc | Arch::Avr | Arch::M68k | Arch::Msp430 => { + // Clang uses the LLVM implementation for these architectures. + bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + } + Arch::Other(_) => { + // For custom targets, use the LLVM va_arg instruction as a fallback. + bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)) + } } } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 9c5a3d839ceb..c7d7b7429f34 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -18,7 +18,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } @@ -28,7 +27,6 @@ rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } -rustc_query_system = { path = "../rustc_query_system" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } @@ -38,7 +36,6 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } serde_json = "1.0.59" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tempfile = "3.2" -thin-vec = "0.2.12" thorin-dwp = "0.9" tracing = "0.1" wasm-encoder = "0.219" diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl deleted file mode 100644 index fc6e4fb12574..000000000000 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ /dev/null @@ -1,413 +0,0 @@ -codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender - -codegen_ssa_aarch64_softfloat_neon = enabling the `neon` target feature on the current target is unsound due to ABI issues - -codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} - -codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work - -codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error} - -codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument - -codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty - -codegen_ssa_cgu_not_recorded = - CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded - -codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option. - -codegen_ssa_compiler_builtins_cannot_call = - `compiler_builtins` cannot call functions through upstream monomorphizations; encountered invalid call from `{$caller}` to `{$callee}` - -codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error} - -codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error} - -codegen_ssa_cpu_required = target requires explicitly specifying a cpu with `-C target-cpu` - -codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} - -codegen_ssa_dlltool_fail_import_library = - dlltool could not create import library with {$dlltool_path} {$dlltool_args}: - {$stdout} - {$stderr} - -codegen_ssa_dynamic_linking_with_lto = - cannot prefer dynamic linking when performing LTO - .note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO - -codegen_ssa_error_calling_dlltool = - error calling dlltool '{$dlltool_path}': {$error} - -codegen_ssa_error_creating_import_library = - error creating import library for {$lib_name}: {$error} - -codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error} - -codegen_ssa_error_writing_def_file = - error writing .DEF file: {$error} - -codegen_ssa_expected_name_value_pair = expected name value pair - -codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified - -codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_open_file = failed to open file '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error} -codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error} - -codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err} - -codegen_ssa_failed_to_write = failed to write {$path}: {$error} - -codegen_ssa_feature_not_valid = the feature named `{$feature}` is not valid for this target - .label = `{$feature}` is not valid for this target - .help = consider removing the leading `+` in the feature name - -codegen_ssa_field_associated_value_expected = associated value expected for `{$name}` - -codegen_ssa_forbidden_ctarget_feature = - target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason} - .note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -codegen_ssa_forbidden_ctarget_feature_issue = for more information, see issue #116344 - -codegen_ssa_forbidden_target_feature_attr = - target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason} - -codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced - -codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced - -codegen_ssa_incorrect_cgu_reuse_type = - CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least -> - [one] {"at least "} - *[other] {""} - }`{$expected_reuse}` - -codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. - -codegen_ssa_invalid_instruction_set = invalid instruction set specified - -codegen_ssa_invalid_literal_value = invalid literal value - .label = value must be an integer between `0` and `255` - -codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_basic_integer_or_ptr_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer or pointer type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` - -codegen_ssa_invalid_monomorphization_cast_wide_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast wide pointer `{$ty}` - -codegen_ssa_invalid_monomorphization_expected_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}` - -codegen_ssa_invalid_monomorphization_expected_pointer = invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}` - -codegen_ssa_invalid_monomorphization_expected_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}` - -codegen_ssa_invalid_monomorphization_expected_usize = invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}` - -codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type - -codegen_ssa_invalid_monomorphization_float_to_int_unchecked = invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}` - -codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type - -codegen_ssa_invalid_monomorphization_floating_point_vector = invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}` - -codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}` - -codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` - -codegen_ssa_invalid_monomorphization_mask_wrong_element_type = invalid monomorphization of `{$name}` intrinsic: expected mask element type to be an integer, found `{$ty}` - -codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}` - -codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}` - -codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}` - -codegen_ssa_invalid_monomorphization_return_length = invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_return_length_input_type = invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` - -codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: SIMD index #{$arg_idx} is out of bounds (limit {$total_len}) - -codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `{$ty}` - -codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}` - -codegen_ssa_invalid_monomorphization_third_argument_length = invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len} - -codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}` - -codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}` - -codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}` - -codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` - -codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}` - -codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64 - -codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error} - -codegen_ssa_link_exe_status_stack_buffer_overrun = 0xc0000409 is `STATUS_STACK_BUFFER_OVERRUN` - .abort_note = this may have been caused by a program abort and not a stack buffer overrun - .event_log_note = consider checking the Application Event Log for Windows Error Reporting events to see the fail fast error code - -codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error - -codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker - -codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error} - -codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker - -codegen_ssa_linker_not_found = linker `{$linker_path}` not found - .note = {$error} - -codegen_ssa_linker_output = {$inner} - -codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker - -codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status} - -codegen_ssa_lto_disallowed = lto can only be run for executables, cdylibs and static library outputs - -codegen_ssa_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdylib-lto` - -codegen_ssa_lto_proc_macro = lto cannot be used for `proc-macro` crate type without `-Zdylib-lto` - -codegen_ssa_malformed_cgu_name = - found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case). - -codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload - -codegen_ssa_missing_features = add the missing features in a `target_feature` attribute - -codegen_ssa_missing_query_depgraph = - found CGU-reuse attribute but `-Zquery-dep-graph` was not specified - -codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found - -codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions - -codegen_ssa_multiple_instruction_set = cannot specify more than one instruction set - -codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times - .help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point - -codegen_ssa_no_field = no field `{$name}` - -codegen_ssa_no_module_named = - no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names} - -codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} - -codegen_ssa_no_saved_object_file = cached cgu {$cgu_name} should have an object file, but doesn't - -codegen_ssa_out_of_range_integer = integer value out of range - .label = value must be between `0` and `255` - -codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} - .note = {$output} - -codegen_ssa_read_file = failed to read file: {$message} - -codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer - -codegen_ssa_requires_rust_abi = `#[track_caller]` requires Rust ABI - -codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib at `{$path}`: {$error} - -codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`) - -codegen_ssa_rlib_missing_format = could not find formats for rlibs - -codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}` - -codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, found rmeta (metadata) file - -codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected - -codegen_ssa_self_contained_linker_missing = the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot - -codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time - -codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link - -codegen_ssa_static_library_native_artifacts = link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. - -codegen_ssa_static_library_native_artifacts_to_file = native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms. - -codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status} - .note = {$output} - -codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error} - -codegen_ssa_target_feature_disable_or_enable = - the target features {$features} must all be either enabled or disabled together - -codegen_ssa_target_feature_safe_trait = `#[target_feature(..)]` cannot be applied to safe trait method - .label = cannot be applied to safe trait method - .label_def = not an `unsafe` function - -codegen_ssa_thorin_decompress_data = failed to decompress compressed section - -codegen_ssa_thorin_duplicate_unit = duplicate split compilation unit ({$unit}) - -codegen_ssa_thorin_empty_unit = unit {$unit} in input DWARF object with no data - -codegen_ssa_thorin_gimli_read = {$error} -codegen_ssa_thorin_gimli_write = {$error} - -codegen_ssa_thorin_incompatible_index_version = incompatible `{$section}` index version: found version {$actual}, expected version {$format} - -codegen_ssa_thorin_invalid_input_kind = input is not an archive or elf object - -codegen_ssa_thorin_io = {$error} -codegen_ssa_thorin_missing_dwo_name = missing path attribute to DWARF object ({$id}) - -codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executable was not found - -codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}` - -codegen_ssa_thorin_mixed_input_encodings = input objects have mixed encodings - -codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections - -codegen_ssa_thorin_multiple_debug_types_section = multiple `.debug_types.dwo` sections in a package - -codegen_ssa_thorin_multiple_relocations = multiple relocations for section `{$section}` at offset {$offset} - -codegen_ssa_thorin_no_compilation_units = input object has no compilation units - -codegen_ssa_thorin_no_die = no top-level debugging information entry in compilation/type unit - -codegen_ssa_thorin_not_output_object_created = no output object was created from inputs - -codegen_ssa_thorin_not_split_unit = regular compilation unit in object (missing dwo identifier) - -codegen_ssa_thorin_object_read = {$error} -codegen_ssa_thorin_object_write = {$error} -codegen_ssa_thorin_offset_at_index = read offset at index {$index} of `.debug_str_offsets.dwo` section - -codegen_ssa_thorin_parse_archive_member = failed to parse archive member - -codegen_ssa_thorin_parse_index = failed to parse `{$section}` index section - -codegen_ssa_thorin_parse_input_archive_file = failed to parse input archive file - -codegen_ssa_thorin_parse_input_file_kind = failed to parse input file kind - -codegen_ssa_thorin_parse_input_object_file = failed to parse input object file - -codegen_ssa_thorin_parse_unit = failed to parse unit - -codegen_ssa_thorin_parse_unit_abbreviations = failed to parse unit abbreviations - -codegen_ssa_thorin_parse_unit_attribute = failed to parse unit attribute - -codegen_ssa_thorin_parse_unit_header = failed to parse unit header - -codegen_ssa_thorin_read_input_failure = failed to read input file - -codegen_ssa_thorin_relocation_with_invalid_symbol = relocation with invalid symbol for section `{$section}` at offset {$offset} - -codegen_ssa_thorin_row_not_in_index = row {$row} found in index's hash table not present in index - -codegen_ssa_thorin_section_not_in_row = section not found in unit's row in index - -codegen_ssa_thorin_section_without_name = section without name at offset {$offset} - -codegen_ssa_thorin_str_at_offset = read string at offset {$offset} of `.debug_str.dwo` section - -codegen_ssa_thorin_top_level_die_not_unit = top-level debugging information entry is not a compilation/type unit - -codegen_ssa_thorin_unit_not_in_index = unit {$unit} from input package is not in its index - -codegen_ssa_thorin_unsupported_relocation = unsupported relocation for section {$section} at offset {$offset} - -codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}` - .note = {$error} - .command_note = {$command_formatted} - -codegen_ssa_unable_to_run = unable to run `{$util}`: {$error} - -codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error} - -codegen_ssa_unable_to_write_debugger_visualizer = unable to write debugger visualizer file `{$path}`: {$error} - -codegen_ssa_unexpected_parameter_name = unexpected parameter name - .label = expected `{$prefix_nops}` or `{$entry_nops}` - -codegen_ssa_unknown_archive_kind = - don't know how to build archive of type: {$kind} - -codegen_ssa_unknown_ctarget_feature = - unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}` - .note = it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future - .possible_feature = you might have meant: `{$rust_feature}` - .consider_filing_feature_request = consider filing a feature request - -codegen_ssa_unknown_ctarget_feature_prefix = - unknown feature specified for `-Ctarget-feature`: `{$feature}` - .note = features must begin with a `+` to enable or `-` to disable it - -codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified - -codegen_ssa_unstable_ctarget_feature = - unstable feature specified for `-Ctarget-feature`: `{$feature}` - .note = this feature is not stably supported; its behavior can change in the future - -codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]` - -codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target - -codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib) - -codegen_ssa_version_script_write_failure = failed to write version script: {$error} - -codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload - -codegen_ssa_xcrun_about = - the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file - -codegen_ssa_xcrun_command_line_tools_insufficient = - when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode - -codegen_ssa_xcrun_failed_invoking = invoking `{$command_formatted}` to find {$sdk_name}.sdk failed: {$error} - -codegen_ssa_xcrun_found_developer_dir = found active developer directory at "{$developer_dir}" - -# `xcrun` already outputs a message about missing Xcode installation, so we only augment it with details about env vars. -codegen_ssa_xcrun_no_developer_dir = - pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable - -codegen_ssa_xcrun_sdk_path_warning = output of `xcrun` while finding {$sdk_name}.sdk - .note = {$stderr} - -codegen_ssa_xcrun_unsuccessful = failed running `{$command_formatted}` to find {$sdk_name}.sdk - .note = {$stdout}{$stderr} diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 43e1e135a666..081fe0aa91aa 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -28,13 +28,13 @@ use std::fmt; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{DiagArgValue, IntoDiagArg}; -use rustc_hir as hir; +use rustc_hir::attrs::{AttributeKind, CguFields, CguKind}; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::{self as hir, find_attr}; use rustc_middle::mir::mono::CodegenUnitNameBuilder; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_span::{Span, Symbol, sym}; -use thin_vec::ThinVec; +use rustc_span::{Span, Symbol}; use tracing::debug; use crate::errors; @@ -63,9 +63,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>, set_reuse: &dyn Fn(&mut CguReuseTr }, }; - for attr in tcx.hir_attrs(rustc_hir::CRATE_HIR_ID) { - ams.check_attr(attr); - } + ams.check_attrs(tcx.hir_attrs(rustc_hir::CRATE_HIR_ID)); set_reuse(&mut ams.cgu_reuse_tracker); @@ -89,109 +87,91 @@ struct AssertModuleSource<'tcx> { } impl<'tcx> AssertModuleSource<'tcx> { - fn check_attr(&mut self, attr: &hir::Attribute) { - let (expected_reuse, comp_kind) = if attr.has_name(sym::rustc_partition_reused) { - (CguReuse::PreLto, ComparisonKind::AtLeast) - } else if attr.has_name(sym::rustc_partition_codegened) { - (CguReuse::No, ComparisonKind::Exact) - } else if attr.has_name(sym::rustc_expected_cgu_reuse) { - match self.field(attr, sym::kind) { - sym::no => (CguReuse::No, ComparisonKind::Exact), - sym::pre_dash_lto => (CguReuse::PreLto, ComparisonKind::Exact), - sym::post_dash_lto => (CguReuse::PostLto, ComparisonKind::Exact), - sym::any => (CguReuse::PreLto, ComparisonKind::AtLeast), - other => { - self.tcx - .dcx() - .emit_fatal(errors::UnknownReuseKind { span: attr.span(), kind: other }); - } + fn check_attrs(&mut self, attrs: &[hir::Attribute]) { + for &(span, cgu_fields) in find_attr!(attrs, + AttributeKind::RustcCguTestAttr(e) => e) + .into_iter() + .flatten() + { + let (expected_reuse, comp_kind) = match cgu_fields { + CguFields::PartitionReused { .. } => (CguReuse::PreLto, ComparisonKind::AtLeast), + CguFields::PartitionCodegened { .. } => (CguReuse::No, ComparisonKind::Exact), + CguFields::ExpectedCguReuse { kind, .. } => match kind { + CguKind::No => (CguReuse::No, ComparisonKind::Exact), + CguKind::PreDashLto => (CguReuse::PreLto, ComparisonKind::Exact), + CguKind::PostDashLto => (CguReuse::PostLto, ComparisonKind::Exact), + CguKind::Any => (CguReuse::PreLto, ComparisonKind::AtLeast), + }, + }; + let (CguFields::ExpectedCguReuse { cfg, module, .. } + | CguFields::PartitionCodegened { cfg, module } + | CguFields::PartitionReused { cfg, module }) = cgu_fields; + + if !self.tcx.sess.opts.unstable_opts.query_dep_graph { + self.tcx.dcx().emit_fatal(errors::MissingQueryDepGraph { span }); } - } else { - return; - }; - if !self.tcx.sess.opts.unstable_opts.query_dep_graph { - self.tcx.dcx().emit_fatal(errors::MissingQueryDepGraph { span: attr.span() }); - } + if !self.check_config(cfg) { + debug!("check_attr: config does not match, ignoring attr"); + return; + } - if !self.check_config(attr) { - debug!("check_attr: config does not match, ignoring attr"); - return; - } + let user_path = module.as_str(); + let crate_name = self.tcx.crate_name(LOCAL_CRATE); + let crate_name = crate_name.as_str(); - let user_path = self.field(attr, sym::module).to_string(); - let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string(); + if !user_path.starts_with(&crate_name) { + self.tcx.dcx().emit_fatal(errors::MalformedCguName { span, user_path, crate_name }); + } - if !user_path.starts_with(&crate_name) { - self.tcx.dcx().emit_fatal(errors::MalformedCguName { - span: attr.span(), - user_path, - crate_name, - }); - } + // Split of the "special suffix" if there is one. + let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind('.') { + (&user_path[..index], Some(&user_path[index + 1..])) + } else { + (&user_path[..], None) + }; - // Split of the "special suffix" if there is one. - let (user_path, cgu_special_suffix) = if let Some(index) = user_path.rfind('.') { - (&user_path[..index], Some(&user_path[index + 1..])) - } else { - (&user_path[..], None) - }; + let mut iter = user_path.split('-'); - let mut iter = user_path.split('-'); + // Remove the crate name + assert_eq!(iter.next().unwrap(), crate_name); - // Remove the crate name - assert_eq!(iter.next().unwrap(), crate_name); + let cgu_path_components = iter.collect::>(); - let cgu_path_components = iter.collect::>(); + let cgu_name_builder = &mut CodegenUnitNameBuilder::new(self.tcx); + let cgu_name = cgu_name_builder.build_cgu_name( + LOCAL_CRATE, + cgu_path_components, + cgu_special_suffix, + ); - let cgu_name_builder = &mut CodegenUnitNameBuilder::new(self.tcx); - let cgu_name = - cgu_name_builder.build_cgu_name(LOCAL_CRATE, cgu_path_components, cgu_special_suffix); + debug!("mapping '{user_path}' to cgu name '{cgu_name}'"); - debug!("mapping '{}' to cgu name '{}'", self.field(attr, sym::module), cgu_name); + if !self.available_cgus.contains(&cgu_name) { + let cgu_names: Vec<&str> = + self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord(); + self.tcx.dcx().emit_err(errors::NoModuleNamed { + span, + user_path, + cgu_name, + cgu_names: cgu_names.join(", "), + }); + } - if !self.available_cgus.contains(&cgu_name) { - let cgu_names: Vec<&str> = - self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord(); - self.tcx.dcx().emit_err(errors::NoModuleNamed { - span: attr.span(), - user_path, + self.cgu_reuse_tracker.set_expectation( cgu_name, - cgu_names: cgu_names.join(", "), - }); + user_path, + span, + expected_reuse, + comp_kind, + ); } - - self.cgu_reuse_tracker.set_expectation( - cgu_name, - user_path, - attr.span(), - expected_reuse, - comp_kind, - ); - } - - fn field(&self, attr: &hir::Attribute, name: Symbol) -> Symbol { - for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { - if item.has_name(name) { - if let Some(value) = item.value_str() { - return value; - } else { - self.tcx.dcx().emit_fatal(errors::FieldAssociatedValueExpected { - span: item.span(), - name, - }); - } - } - } - - self.tcx.dcx().emit_fatal(errors::NoField { span: attr.span(), name }); } /// Scan for a `cfg="foo"` attribute and check whether we have a /// cfg flag called `foo`. - fn check_config(&self, attr: &hir::Attribute) -> bool { + fn check_config(&self, value: Symbol) -> bool { let config = &self.tcx.sess.psess.config; - let value = self.field(attr, sym::cfg); debug!("check_config(config={:?}, value={:?})", config, value); if config.iter().any(|&(name, _)| name == value) { debug!("check_config: matched"); diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs index 23808ade6c85..1b707a24066e 100644 --- a/compiler/rustc_codegen_ssa/src/back/apple.rs +++ b/compiler/rustc_codegen_ssa/src/back/apple.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use std::process::Command; use itertools::Itertools; +use rustc_errors::msg; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_session::Session; pub(super) use rustc_target::spec::apple::OSVersion; @@ -10,7 +11,6 @@ use rustc_target::spec::{Arch, Env, Os, Target}; use tracing::debug; use crate::errors::{XcrunError, XcrunSdkPathWarning}; -use crate::fluent_generated as fluent; #[cfg(test)] mod tests; @@ -185,19 +185,19 @@ pub(super) fn get_sdk_root(sess: &Session) -> Option { // FIXME(madsmtm): Make this a lint, to allow deny warnings to work. // (Or fix ). let mut diag = sess.dcx().create_warn(err); - diag.note(fluent::codegen_ssa_xcrun_about); + diag.note(msg!("the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file")); // Recognize common error cases, and give more Rust-specific error messages for those. if let Some(developer_dir) = xcode_select_developer_dir() { diag.arg("developer_dir", &developer_dir); - diag.note(fluent::codegen_ssa_xcrun_found_developer_dir); + diag.note(msg!("found active developer directory at \"{$developer_dir}\"")); if developer_dir.as_os_str().to_string_lossy().contains("CommandLineTools") { if sdk_name != "MacOSX" { - diag.help(fluent::codegen_ssa_xcrun_command_line_tools_insufficient); + diag.help(msg!("when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode")); } } } else { - diag.help(fluent::codegen_ssa_xcrun_no_developer_dir); + diag.help(msg!("pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable")); } diag.emit(); diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 93f6cb3b87e6..3f12e857391b 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -22,10 +22,11 @@ use tracing::trace; use super::metadata::{create_compressed_metadata_file, search_for_section}; use crate::common; -// Re-exporting for rustc_codegen_llvm::back::archive -pub use crate::errors::{ArchiveBuildFailure, ExtractBundledLibsError, UnknownArchiveKind}; +// Public for ArchiveBuilderBuilder::extract_bundled_libs +pub use crate::errors::ExtractBundledLibsError; use crate::errors::{ - DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, ErrorWritingDEFFile, + ArchiveBuildFailure, DlltoolFailImportLibrary, ErrorCallingDllTool, ErrorCreatingImportLibrary, + ErrorWritingDEFFile, UnknownArchiveKind, }; /// An item to be included in an import library. diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index d35c3b6bb189..acc1c0b9f0de 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -11,11 +11,11 @@ use std::{env, fmt, fs, io, mem, str}; use find_msvc_tools; use itertools::Itertools; +use object::{Object, ObjectSection, ObjectSymbol}; use regex::Regex; use rustc_arena::TypedArena; -use rustc_ast::CRATE_NODE_ID; -use rustc_attr_parsing::{ShouldEmit, eval_config_entry}; -use rustc_data_structures::fx::FxIndexSet; +use rustc_attr_parsing::eval_config_entry; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; @@ -104,17 +104,18 @@ pub fn link_binary( }); if outputs.outputs.should_link() { - let tmpdir = TempDirBuilder::new() - .prefix("rustc") - .tempdir() - .unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error })); - let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); let output = out_filename( sess, crate_type, outputs, codegen_results.crate_info.local_crate_name, ); + let tmpdir = TempDirBuilder::new() + .prefix("rustc") + .tempdir_in(output.parent().unwrap_or_else(|| Path::new("."))) + .unwrap_or_else(|error| sess.dcx().emit_fatal(errors::CreateTempDir { error })); + let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); + let crate_name = format!("{}", codegen_results.crate_info.local_crate_name); let out_filename = output.file_for_writing( outputs, @@ -136,7 +137,7 @@ pub fn link_binary( ) .build(&out_filename); } - CrateType::Staticlib => { + CrateType::StaticLib => { link_staticlib( sess, archive_builder_builder, @@ -278,7 +279,7 @@ pub fn each_linked_rlib( } let crate_name = info.crate_name[&cnum]; let used_crate_source = &info.used_crate_source[&cnum]; - if let Some((path, _)) = &used_crate_source.rlib { + if let Some(path) = &used_crate_source.rlib { f(cnum, path); } else if used_crate_source.rmeta.is_some() { return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name }); @@ -474,7 +475,7 @@ fn link_staticlib( let res = each_linked_rlib( &codegen_results.crate_info, - Some(CrateType::Staticlib), + Some(CrateType::StaticLib), &mut |cnum, path| { let lto = are_upstream_rust_objects_already_included(sess) && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); @@ -532,7 +533,7 @@ fn link_staticlib( let fmts = codegen_results .crate_info .dependency_formats - .get(&CrateType::Staticlib) + .get(&CrateType::StaticLib) .expect("no dependency formats for staticlib"); let mut all_rust_dylibs = vec![]; @@ -542,7 +543,7 @@ fn link_staticlib( }; let crate_name = codegen_results.crate_info.crate_name[&cnum]; let used_crate_source = &codegen_results.crate_info.used_crate_source[&cnum]; - if let Some((path, _)) = &used_crate_source.dylib { + if let Some(path) = &used_crate_source.dylib { all_rust_dylibs.push(&**path); } else if used_crate_source.rmeta.is_some() { sess.dcx().emit_fatal(errors::LinkRlibError::OnlyRmetaFound { crate_name }); @@ -620,7 +621,6 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out .used_crate_source .items() .filter_map(|(_, csource)| csource.rlib.as_ref()) - .map(|(path, _)| path) .into_sorted_stable_ord(); for input_rlib in input_rlibs { @@ -663,7 +663,7 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out } #[derive(LintDiagnostic)] -#[diag(codegen_ssa_linker_output)] +#[diag("{$inner}")] /// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just /// end up with inconsistent languages within the same diagnostic. struct LinkerOutput { @@ -1211,7 +1211,7 @@ fn add_sanitizer_libraries( return; } - if matches!(crate_type, CrateType::Rlib | CrateType::Staticlib) { + if matches!(crate_type, CrateType::Rlib | CrateType::StaticLib) { return; } @@ -2174,12 +2174,7 @@ fn add_rpath_args( .crate_info .used_crates .iter() - .filter_map(|cnum| { - codegen_results.crate_info.used_crate_source[cnum] - .dylib - .as_ref() - .map(|(path, _)| &**path) - }) + .filter_map(|cnum| codegen_results.crate_info.used_crate_source[cnum].dylib.as_deref()) .collect::>(); let rpath_config = RPathConfig { libs: &*libs, @@ -2191,6 +2186,71 @@ fn add_rpath_args( } } +fn add_c_staticlib_symbols( + sess: &Session, + lib: &NativeLib, + out: &mut Vec<(String, SymbolExportKind)>, +) -> io::Result<()> { + let file_path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess); + + let archive_map = unsafe { Mmap::map(File::open(&file_path)?)? }; + + let archive = object::read::archive::ArchiveFile::parse(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + for member in archive.members() { + let member = member.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + let data = member + .data(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // clang LTO: raw LLVM bitcode + if data.starts_with(b"BC\xc0\xde") { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LLVM bitcode object in C static library (LTO not supported)", + )); + } + + let object = object::File::parse(&*data) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // gcc / clang ELF / Mach-O LTO + if object.sections().any(|s| { + s.name().map(|n| n.starts_with(".gnu.lto_") || n == ".llvm.lto").unwrap_or(false) + }) { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LTO object in C static library is not supported", + )); + } + + for symbol in object.symbols() { + if symbol.scope() != object::SymbolScope::Dynamic { + continue; + } + + let name = match symbol.name() { + Ok(n) => n, + Err(_) => continue, + }; + + let export_kind = match symbol.kind() { + object::SymbolKind::Text => SymbolExportKind::Text, + object::SymbolKind::Data => SymbolExportKind::Data, + _ => continue, + }; + + // FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple. + // Need to be resolved. + out.push((name.to_string(), export_kind)); + } + } + + Ok(()) +} + /// Produce the linker command line containing linker path and arguments. /// /// When comments in the function say "order-(in)dependent" they mean order-dependence between @@ -2223,6 +2283,25 @@ fn linker_with_args( ); let link_output_kind = link_output_kind(sess, crate_type); + let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone(); + + if crate_type == CrateType::Cdylib { + let mut seen = FxHashSet::default(); + + for lib in &codegen_results.crate_info.used_libraries { + if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind + && seen.insert((lib.name, lib.verbatim)) + { + if let Err(err) = add_c_staticlib_symbols(&sess, lib, &mut export_symbols) { + sess.dcx().fatal(format!( + "failed to process C static library `{}`: {}", + lib.name, err + )); + } + } + } + } + // ------------ Early order-dependent options ------------ // If we're building something like a dynamic library then some platforms @@ -2230,11 +2309,7 @@ fn linker_with_args( // dynamic library. // Must be passed before any libraries to prevent the symbols to export from being thrown away, // at least on some platforms (e.g. windows-gnu). - cmd.export_symbols( - tmpdir, - crate_type, - &codegen_results.crate_info.exported_symbols[&crate_type], - ); + cmd.export_symbols(tmpdir, crate_type, &export_symbols); // Can be used for adding custom CRT objects or overriding order-dependent options above. // FIXME: In practice built-in target specs use this for arbitrary order-independent options, @@ -2657,7 +2732,7 @@ fn add_native_libs_from_crate( if link_static && cnum != LOCAL_CRATE && !bundled_libs.is_empty() { // If rlib contains native libs as archives, unpack them to tmpdir. - let rlib = &codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap().0; + let rlib = codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap(); archive_builder_builder .extract_bundled_libs(rlib, tmpdir, bundled_libs) .unwrap_or_else(|e| sess.dcx().emit_fatal(e)); @@ -2684,7 +2759,7 @@ fn add_native_libs_from_crate( let name = lib.name.as_str(); let verbatim = lib.verbatim; match lib.kind { - NativeLibKind::Static { bundle, whole_archive } => { + NativeLibKind::Static { bundle, whole_archive, .. } => { if link_static { let bundle = bundle.unwrap_or(true); let whole_archive = whole_archive == Some(true); @@ -2799,11 +2874,9 @@ fn add_upstream_rust_crates( // We must always link crates `compiler_builtins` and `profiler_builtins` statically. // Even if they were already included into a dylib // (e.g. `libstd` when `-C prefer-dynamic` is used). - // FIXME: `dependency_formats` can report `profiler_builtins` as `NotLinked` for some - // reason, it shouldn't do that because `profiler_builtins` should indeed be linked. let linkage = data[cnum]; let link_static_crate = linkage == Linkage::Static - || (linkage == Linkage::IncludedFromDylib || linkage == Linkage::NotLinked) + || linkage == Linkage::IncludedFromDylib && (codegen_results.crate_info.compiler_builtins == Some(cnum) || codegen_results.crate_info.profiler_runtime == Some(cnum)); @@ -2828,7 +2901,7 @@ fn add_upstream_rust_crates( } Linkage::Dynamic => { let src = &codegen_results.crate_info.used_crate_source[&cnum]; - add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0); + add_dynamic_crate(cmd, sess, src.dylib.as_ref().unwrap()); } } @@ -2956,7 +3029,7 @@ fn add_static_crate( bundled_lib_file_names: &FxIndexSet, ) { let src = &codegen_results.crate_info.used_crate_source[&cnum]; - let cratepath = &src.rlib.as_ref().unwrap().0; + let cratepath = src.rlib.as_ref().unwrap(); let mut link_upstream = |path: &Path| cmd.link_staticlib_by_path(&rehome_lib_path(sess, path), false); @@ -3029,9 +3102,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) { fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { - Some(ref cfg) => { - eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool() - } + Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(), None => true, } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index c73e950bed40..10c4eedb58e8 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -2,7 +2,7 @@ use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; use std::io::prelude::*; use std::path::{Path, PathBuf}; -use std::{env, io, iter, mem, str}; +use std::{env, iter, mem, str}; use find_msvc_tools; use rustc_hir::attrs::WindowsSubsystemKind; @@ -809,7 +809,7 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.target.is_like_darwin { // Write a plain, newline-separated list of symbols - let res: io::Result<()> = try { + let res = try { let mut f = File::create_buffered(&path)?; for (sym, _) in symbols { debug!(" _{sym}"); @@ -821,7 +821,7 @@ impl<'a> Linker for GccLinker<'a> { } self.link_arg("-exported_symbols_list").link_arg(path); } else if self.sess.target.is_like_windows { - let res: io::Result<()> = try { + let res = try { let mut f = File::create_buffered(&path)?; // .def file similar to MSVC one but without LIBRARY section @@ -839,8 +839,13 @@ impl<'a> Linker for GccLinker<'a> { self.sess.dcx().emit_fatal(errors::LibDefWriteFailure { error }); } self.link_arg(path); + } else if self.sess.target.is_like_wasm { + self.link_arg("--no-export-dynamic"); + for (sym, _) in symbols { + self.link_arg("--export").link_arg(sym); + } } else if crate_type == CrateType::Executable && !self.sess.target.is_like_solaris { - let res: io::Result<()> = try { + let res = try { let mut f = File::create_buffered(&path)?; writeln!(f, "{{")?; for (sym, _) in symbols { @@ -853,14 +858,9 @@ impl<'a> Linker for GccLinker<'a> { self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error }); } self.link_arg("--dynamic-list").link_arg(path); - } else if self.sess.target.is_like_wasm { - self.link_arg("--no-export-dynamic"); - for (sym, _) in symbols { - self.link_arg("--export").link_arg(sym); - } } else { // Write an LD version script - let res: io::Result<()> = try { + let res = try { let mut f = File::create_buffered(&path)?; writeln!(f, "{{")?; if !symbols.is_empty() { @@ -1139,7 +1139,7 @@ impl<'a> Linker for MsvcLinker<'a> { } let path = tmpdir.join("lib.def"); - let res: io::Result<()> = try { + let res = try { let mut f = File::create_buffered(&path)?; // Start off with the standard module name header and then go @@ -1208,10 +1208,23 @@ impl<'a> Linker for EmLinker<'a> { fn set_output_kind( &mut self, - _output_kind: LinkOutputKind, + output_kind: LinkOutputKind, _crate_type: CrateType, _out_filename: &Path, ) { + match output_kind { + LinkOutputKind::DynamicNoPicExe | LinkOutputKind::DynamicPicExe => { + self.cmd.arg("-sMAIN_MODULE=2"); + } + LinkOutputKind::DynamicDylib | LinkOutputKind::StaticDylib => { + self.cmd.arg("-sSIDE_MODULE=2"); + } + // -fno-pie is the default on Emscripten. + LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => {} + LinkOutputKind::WasiReactorExe => { + unreachable!(); + } + } } fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { @@ -1722,7 +1735,7 @@ impl<'a> Linker for AixLinker<'a> { symbols: &[(String, SymbolExportKind)], ) { let path = tmpdir.join("list.exp"); - let res: io::Result<()> = try { + let res = try { let mut f = File::create_buffered(&path)?; // FIXME: use llvm-nm to generate export list. for (symbol, _) in symbols { @@ -1827,9 +1840,9 @@ fn exported_symbols_for_non_proc_macro( // Mark allocator shim symbols as exported only if they were generated. if export_threshold == SymbolExportLevel::Rust && needs_allocator_shim_for_linking(tcx.dependency_formats(()), crate_type) - && tcx.allocator_kind(()).is_some() + && let Some(kind) = tcx.allocator_kind(()) { - symbols.extend(allocator_shim_symbols(tcx)); + symbols.extend(allocator_shim_symbols(tcx, kind)); } symbols @@ -1857,7 +1870,7 @@ pub(crate) fn linked_symbols( | CrateType::Cdylib | CrateType::Dylib | CrateType::Sdylib => (), - CrateType::Staticlib | CrateType::Rlib => { + CrateType::StaticLib | CrateType::Rlib => { // These are not linked, so no need to generate symbols.o for them. return Vec::new(); } @@ -2075,7 +2088,7 @@ impl<'a> Linker for BpfLinker<'a> { } fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { - panic!("staticlibs not supported") + self.sess.dcx().emit_fatal(errors::BpfStaticlibNotSupported) } fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) { @@ -2122,7 +2135,7 @@ impl<'a> Linker for BpfLinker<'a> { symbols: &[(String, SymbolExportKind)], ) { let path = tmpdir.join("symbols"); - let res: io::Result<()> = try { + let res = try { let mut f = File::create_buffered(&path)?; for (sym, _) in symbols { writeln!(f, "{sym}")?; diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index e6df6a2469f3..80b3b5a4d7c0 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -2,6 +2,7 @@ use std::ffi::CString; use std::sync::Arc; use rustc_data_structures::memmap::Mmap; +use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportLevel}; use rustc_middle::ty::TyCtxt; @@ -66,7 +67,7 @@ fn crate_type_allows_lto(crate_type: CrateType) -> bool { match crate_type { CrateType::Executable | CrateType::Dylib - | CrateType::Staticlib + | CrateType::StaticLib | CrateType::Cdylib | CrateType::ProcMacro | CrateType::Sdylib => true, @@ -117,35 +118,35 @@ pub(super) fn exported_symbols_for_lto( } // Mark allocator shim symbols as exported only if they were generated. - if export_threshold == SymbolExportLevel::Rust && allocator_kind_for_codegen(tcx).is_some() { - symbols_below_threshold.extend(allocator_shim_symbols(tcx).map(|(name, _kind)| name)); + if export_threshold == SymbolExportLevel::Rust + && let Some(kind) = allocator_kind_for_codegen(tcx) + { + symbols_below_threshold.extend(allocator_shim_symbols(tcx, kind).map(|(name, _kind)| name)); } symbols_below_threshold } -pub(super) fn check_lto_allowed(cgcx: &CodegenContext) { +pub(super) fn check_lto_allowed(cgcx: &CodegenContext, dcx: DiagCtxtHandle<'_>) { if cgcx.lto == Lto::ThinLocal { // Crate local LTO is always allowed return; } - let dcx = cgcx.create_dcx(); - // Make sure we actually can run LTO for crate_type in cgcx.crate_types.iter() { if !crate_type_allows_lto(*crate_type) { dcx.handle().emit_fatal(LtoDisallowed); } else if *crate_type == CrateType::Dylib { - if !cgcx.opts.unstable_opts.dylib_lto { + if !cgcx.dylib_lto { dcx.handle().emit_fatal(LtoDylib); } - } else if *crate_type == CrateType::ProcMacro && !cgcx.opts.unstable_opts.dylib_lto { + } else if *crate_type == CrateType::ProcMacro && !cgcx.dylib_lto { dcx.handle().emit_fatal(LtoProcMacro); } } - if cgcx.opts.cg.prefer_dynamic && !cgcx.opts.unstable_opts.dylib_lto { + if cgcx.prefer_dynamic && !cgcx.dylib_lto { dcx.handle().emit_fatal(DynamicLinkingWithLTO); } } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 6dff79374f20..8a2a6823fdf4 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -330,14 +330,12 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 { let mut e_flags: u32 = 0x0; // Check if compression is enabled - // `unstable_target_features` is used here because "zca" is gated behind riscv_target_feature. - if sess.unstable_target_features.contains(&sym::zca) { + if sess.target_features.contains(&sym::zca) { e_flags |= elf::EF_RISCV_RVC; } // Check if RVTSO is enabled - // `unstable_target_features` is used here because "ztso" is gated behind riscv_target_feature. - if sess.unstable_target_features.contains(&sym::ztso) { + if sess.target_features.contains(&sym::ztso) { e_flags |= elf::EF_RISCV_TSO; } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index a80976fad02a..557b00b911aa 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,9 +1,7 @@ use std::collections::hash_map::Entry::*; use rustc_abi::{CanonAbi, X86Call}; -use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name, -}; +use rustc_ast::expand::allocator::{AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name}; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; @@ -15,12 +13,14 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::query::LocalCrate; use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, Instance, SymbolName, Ty, TyCtxt}; use rustc_middle::util::Providers; -use rustc_session::config::{CrateType, OomStrategy}; +use rustc_session::config::CrateType; +use rustc_span::Span; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{Arch, Os, TlsModel}; use tracing::debug; use crate::back::symbol_export; +use crate::base::allocator_shim_contents; fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(tcx.crate_types()) @@ -28,7 +28,7 @@ fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { fn crate_export_threshold(crate_type: CrateType) -> SymbolExportLevel { match crate_type { - CrateType::Executable | CrateType::Staticlib | CrateType::ProcMacro | CrateType::Cdylib => { + CrateType::Executable | CrateType::StaticLib | CrateType::ProcMacro | CrateType::Cdylib => { SymbolExportLevel::C } CrateType::Rlib | CrateType::Dylib | CrateType::Sdylib => SymbolExportLevel::Rust, @@ -127,7 +127,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap, def_id: LocalDefId) } pub(crate) fn provide(providers: &mut Providers) { - providers.reachable_non_generics = reachable_non_generics_provider; - providers.is_reachable_non_generic = is_reachable_non_generic_provider_local; - providers.exported_non_generic_symbols = exported_non_generic_symbols_provider_local; - providers.exported_generic_symbols = exported_generic_symbols_provider_local; - providers.upstream_monomorphizations = upstream_monomorphizations_provider; - providers.is_unreachable_local_definition = is_unreachable_local_definition_provider; - providers.upstream_drop_glue_for = upstream_drop_glue_for_provider; - providers.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider; - providers.wasm_import_module_map = wasm_import_module_map; + providers.queries.reachable_non_generics = reachable_non_generics_provider; + providers.queries.is_reachable_non_generic = is_reachable_non_generic_provider_local; + providers.queries.exported_non_generic_symbols = exported_non_generic_symbols_provider_local; + providers.queries.exported_generic_symbols = exported_generic_symbols_provider_local; + providers.queries.upstream_monomorphizations = upstream_monomorphizations_provider; + providers.queries.is_unreachable_local_definition = is_unreachable_local_definition_provider; + providers.queries.upstream_drop_glue_for = upstream_drop_glue_for_provider; + providers.queries.upstream_async_drop_glue_for = upstream_async_drop_glue_for_provider; + providers.queries.wasm_import_module_map = wasm_import_module_map; providers.extern_queries.is_reachable_non_generic = is_reachable_non_generic_provider_extern; providers.extern_queries.upstream_monomorphizations_for = upstream_monomorphizations_for_provider; @@ -487,15 +490,12 @@ pub(crate) fn provide(providers: &mut Providers) { pub(crate) fn allocator_shim_symbols( tcx: TyCtxt<'_>, + kind: AllocatorKind, ) -> impl Iterator { - ALLOCATOR_METHODS - .iter() + allocator_shim_contents(tcx, kind) + .into_iter() .map(move |method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str())) - .chain([ - mangle_internal_symbol(tcx, global_fn_name(ALLOC_ERROR_HANDLER).as_str()), - mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), - ]) + .chain([mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE)]) .map(move |symbol_name| { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); @@ -520,10 +520,12 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel let is_extern = codegen_fn_attrs.contains_extern_indicator(); let std_internal = codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); + let eii = codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM); - if is_extern && !std_internal { + if is_extern && !std_internal && !eii { let target = &tcx.sess.target.llvm_target; // WebAssembly cannot export data symbols, so reduce their export level + // FIXME(jdonszelmann) don't do a substring match here. if target.contains("emscripten") { if let DefKind::Static { .. } = tcx.def_kind(sym_def_id) { return SymbolExportLevel::Rust; @@ -763,3 +765,43 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap { ret } + +pub fn escape_symbol_name(tcx: TyCtxt<'_>, symbol: &str, span: Span) -> String { + // https://github.com/llvm/llvm-project/blob/a55fbab0cffc9b4af497b9e4f187b61143743e06/llvm/lib/MC/MCSymbol.cpp + use rustc_target::spec::{Arch, BinaryFormat}; + if !symbol.is_empty() + && symbol.chars().all(|c| matches!(c, '0'..='9' | 'A'..='Z' | 'a'..='z' | '_' | '$' | '.')) + { + return symbol.to_string(); + } + if tcx.sess.target.binary_format == BinaryFormat::Xcoff { + tcx.sess.dcx().span_fatal( + span, + format!( + "symbol escaping is not supported for the binary format {}", + tcx.sess.target.binary_format + ), + ); + } + if tcx.sess.target.arch == Arch::Nvptx64 { + tcx.sess.dcx().span_fatal( + span, + format!( + "symbol escaping is not supported for the architecture {}", + tcx.sess.target.arch + ), + ); + } + let mut escaped_symbol = String::new(); + escaped_symbol.push('\"'); + for c in symbol.chars() { + match c { + '\n' => escaped_symbol.push_str("\\\n"), + '"' => escaped_symbol.push_str("\\\""), + '\\' => escaped_symbol.push_str("\\\\"), + c => escaped_symbol.push(c), + } + } + escaped_symbol.push('\"'); + escaped_symbol +} diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 3e36bd8552b1..87a043fbdf24 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1,4 +1,3 @@ -use std::assert_matches::assert_matches; use std::marker::PhantomData; use std::panic::AssertUnwindSafe; use std::path::{Path, PathBuf}; @@ -7,7 +6,7 @@ use std::sync::mpsc::{Receiver, Sender, channel}; use std::{fs, io, mem, str, thread}; use rustc_abi::Size; -use rustc_ast::attr; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::{self, Acquired}; use rustc_data_structures::memmap::Mmap; @@ -15,23 +14,27 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard}; use rustc_errors::emitter::Emitter; use rustc_errors::translation::Translator; use rustc_errors::{ - Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FatalErrorMarker, Level, - MultiSpan, Style, Suggestions, + Diag, DiagArgMap, DiagCtxt, DiagCtxtHandle, DiagMessage, ErrCode, FatalError, FatalErrorMarker, + Level, MultiSpan, Style, Suggestions, catch_fatal_errors, }; use rustc_fs_util::link_or_copy; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use rustc_incremental::{ copy_cgu_workproduct_to_incr_comp_cache_dir, in_incr_comp_dir, in_incr_comp_dir_sess, }; +use rustc_macros::{Decodable, Encodable}; use rustc_metadata::fs::copy_to_stdout; use rustc_middle::bug; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{ - self, CrateType, Lto, OutFileName, OutputFilenames, OutputType, Passes, SwitchWithOptPath, + self, CrateType, Lto, OptLevel, OutFileName, OutputFilenames, OutputType, Passes, + SwitchWithOptPath, }; use rustc_span::source_map::SourceMap; -use rustc_span::{FileName, InnerSpan, Span, SpanData, sym}; +use rustc_span::{FileName, InnerSpan, Span, SpanData}; use rustc_target::spec::{MergeFunctions, SanitizerSet}; use tracing::debug; @@ -48,7 +51,7 @@ use crate::{ const PRE_LTO_BC_EXT: &str = "pre-lto.bc"; /// What kind of object file to emit. -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, PartialEq, Encodable, Decodable)] pub enum EmitObj { // No object file. None, @@ -62,7 +65,7 @@ pub enum EmitObj { } /// What kind of llvm bitcode section to embed in an object file. -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, PartialEq, Encodable, Decodable)] pub enum BitcodeSection { // No bitcode section. None, @@ -72,6 +75,7 @@ pub enum BitcodeSection { } /// Module-specific configuration for `optimize_and_codegen`. +#[derive(Encodable, Decodable)] pub struct ModuleConfig { /// Names of additional optimization passes to run. pub passes: Vec, @@ -286,10 +290,7 @@ pub struct TargetMachineFactoryConfig { } impl TargetMachineFactoryConfig { - pub fn new( - cgcx: &CodegenContext, - module_name: &str, - ) -> TargetMachineFactoryConfig { + pub fn new(cgcx: &CodegenContext, module_name: &str) -> TargetMachineFactoryConfig { let split_dwarf_file = if cgcx.target_can_use_split_dwarf { cgcx.output_filenames.split_dwarf_path( cgcx.split_debuginfo, @@ -312,30 +313,30 @@ impl TargetMachineFactoryConfig { pub type TargetMachineFactoryFn = Arc< dyn Fn( + DiagCtxtHandle<'_>, TargetMachineFactoryConfig, - ) -> Result< - ::TargetMachine, - ::TargetMachineError, - > + Send + ) -> ::TargetMachine + + Send + Sync, >; /// Additional resources used by optimize_and_codegen (not module specific) -#[derive(Clone)] -pub struct CodegenContext { +#[derive(Clone, Encodable, Decodable)] +pub struct CodegenContext { // Resources needed when running LTO - pub prof: SelfProfilerRef, pub lto: Lto, + pub use_linker_plugin_lto: bool, + pub dylib_lto: bool, + pub prefer_dynamic: bool, pub save_temps: bool, pub fewer_names: bool, pub time_trace: bool, - pub opts: Arc, pub crate_types: Vec, pub output_filenames: Arc, pub invocation_temp: Option, pub module_config: Arc, - pub allocator_config: Arc, - pub tm_factory: TargetMachineFactoryFn, + pub opt_level: OptLevel, + pub backend_features: Vec, pub msvc_imps_needed: bool, pub is_pe_coff: bool, pub target_can_use_split_dwarf: bool, @@ -347,8 +348,6 @@ pub struct CodegenContext { pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, pub pointer_size: Size, - /// Emitter to use for diagnostics produced during codegen. - pub diag_emitter: SharedEmitter, /// LLVM optimizations for which we want to print remarks. pub remark: Passes, /// Directory into which should the LLVM optimization remarks be written. @@ -363,23 +362,21 @@ pub struct CodegenContext { pub parallel: bool, } -impl CodegenContext { - pub fn create_dcx(&self) -> DiagCtxt { - DiagCtxt::new(Box::new(self.diag_emitter.clone())) - } -} - fn generate_thin_lto_work( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], needs_thin_lto: Vec<(String, B::ThinBuffer)>, import_only_modules: Vec<(SerializedModule, WorkProduct)>, ) -> Vec<(ThinLtoWorkItem, u64)> { - let _prof_timer = cgcx.prof.generic_activity("codegen_thin_generate_lto_work"); + let _prof_timer = prof.generic_activity("codegen_thin_generate_lto_work"); let (lto_modules, copy_jobs) = B::run_thin_lto( cgcx, + prof, + dcx, exported_symbols_for_lto, each_linked_rlib_for_lto, needs_thin_lto, @@ -403,9 +400,32 @@ fn generate_thin_lto_work( .collect() } -struct CompiledModules { - modules: Vec, - allocator_module: Option, +pub struct CompiledModules { + pub modules: Vec, + pub allocator_module: Option, +} + +enum MaybeLtoModules { + NoLto { + modules: Vec, + allocator_module: Option, + }, + FatLto { + cgcx: CodegenContext, + exported_symbols_for_lto: Arc>, + each_linked_rlib_file_for_lto: Vec, + needs_fat_lto: Vec>, + lto_import_only_modules: + Vec<(SerializedModule<::ModuleBuffer>, WorkProduct)>, + }, + ThinLto { + cgcx: CodegenContext, + exported_symbols_for_lto: Arc>, + each_linked_rlib_file_for_lto: Vec, + needs_thin_lto: Vec<(String, ::ThinBuffer)>, + lto_import_only_modules: + Vec<(SerializedModule<::ModuleBuffer>, WorkProduct)>, + }, } fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool { @@ -435,7 +455,7 @@ pub(crate) fn start_async_codegen( let (coordinator_send, coordinator_receive) = channel(); let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); - let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); + let no_builtins = find_attr!(crate_attrs, AttributeKind::NoBuiltins); let crate_info = CrateInfo::new(tcx, target_cpu); @@ -515,7 +535,7 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( work_products } -fn produce_final_output_artifacts( +pub fn produce_final_output_artifacts( sess: &Session, compiled_modules: &CompiledModules, crate_output: &OutputFilenames, @@ -797,20 +817,12 @@ pub(crate) enum ComputedLtoType { pub(crate) fn compute_per_cgu_lto_type( sess_lto: &Lto, - opts: &config::Options, + linker_does_lto: bool, sess_crate_types: &[CrateType], - module_kind: ModuleKind, ) -> ComputedLtoType { // If the linker does LTO, we don't have to do it. Note that we // keep doing full LTO, if it is requested, as not to break the // assumption that the output will be a single module. - let linker_does_lto = opts.cg.linker_plugin_lto.enabled(); - - // When we're automatically doing ThinLTO for multi-codegen-unit - // builds we don't actually want to LTO the allocator module if - // it shows up. This is due to various linker shenanigans that - // we'll encounter later. - let is_allocator = module_kind == ModuleKind::Allocator; // We ignore a request for full crate graph LTO if the crate type // is only an rlib, as there is no full crate graph to process, @@ -823,7 +835,7 @@ pub(crate) fn compute_per_cgu_lto_type( let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]); match sess_lto { - Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin, + Lto::ThinLocal if !linker_does_lto => ComputedLtoType::Thin, Lto::Thin if !linker_does_lto && !is_rlib => ComputedLtoType::Thin, Lto::Fat if !is_rlib => ComputedLtoType::Fat, _ => ComputedLtoType::No, @@ -831,31 +843,26 @@ pub(crate) fn compute_per_cgu_lto_type( } fn execute_optimize_work_item( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: SharedEmitter, mut module: ModuleCodegen, ) -> WorkItemResult { - let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &*module.name); + let _timer = prof.generic_activity_with_arg("codegen_module_optimize", &*module.name); - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); - - let module_config = match module.kind { - ModuleKind::Regular => &cgcx.module_config, - ModuleKind::Allocator => &cgcx.allocator_config, - }; - - B::optimize(cgcx, dcx, &mut module, module_config); + B::optimize(cgcx, prof, &shared_emitter, &mut module, &cgcx.module_config); // After we've done the initial round of optimizations we need to // decide whether to synchronously codegen this module or ship it // back to the coordinator thread for further LTO processing (which // has to wait for all the initial modules to be optimized). - let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types, module.kind); + let lto_type = + compute_per_cgu_lto_type(&cgcx.lto, cgcx.use_linker_plugin_lto, &cgcx.crate_types); // If we're doing some form of incremental LTO then we need to be sure to // save our module to disk first. - let bitcode = if module_config.emit_pre_lto_bc { + let bitcode = if cgcx.module_config.emit_pre_lto_bc { let filename = pre_lto_bitcode_filename(&module.name); cgcx.incr_comp_session_dir.as_ref().map(|path| path.join(&filename)) } else { @@ -864,7 +871,7 @@ fn execute_optimize_work_item( match lto_type { ComputedLtoType::No => { - let module = B::codegen(cgcx, module, module_config); + let module = B::codegen(cgcx, &prof, &shared_emitter, module, &cgcx.module_config); WorkItemResult::Finished(module) } ComputedLtoType::Thin => { @@ -892,13 +899,17 @@ fn execute_optimize_work_item( } } -fn execute_copy_from_cache_work_item( - cgcx: &CodegenContext, +fn execute_copy_from_cache_work_item( + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: SharedEmitter, module: CachedModuleCodegen, ) -> CompiledModule { - let _timer = cgcx - .prof - .generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &*module.name); + let _timer = + prof.generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &*module.name); + + let dcx = DiagCtxt::new(Box::new(shared_emitter)); + let dcx = dcx.handle(); let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); @@ -918,11 +929,7 @@ fn execute_copy_from_cache_work_item( Some(output_path) } Err(error) => { - cgcx.create_dcx().handle().emit_err(errors::CopyPathBuf { - source_file, - output_path, - error, - }); + dcx.emit_err(errors::CopyPathBuf { source_file, output_path, error }); None } } @@ -965,7 +972,7 @@ fn execute_copy_from_cache_work_item( let bytecode = load_from_incr_cache(module_config.emit_bc, OutputType::Bitcode); let object = load_from_incr_cache(should_emit_obj, OutputType::Object); if should_emit_obj && object.is_none() { - cgcx.create_dcx().handle().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) + dcx.emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) } CompiledModule { @@ -981,15 +988,21 @@ fn execute_copy_from_cache_work_item( } fn do_fat_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: SharedEmitter, + tm_factory: TargetMachineFactoryFn, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], mut needs_fat_lto: Vec>, import_only_modules: Vec<(SerializedModule, WorkProduct)>, ) -> CompiledModule { - let _timer = cgcx.prof.verbose_generic_activity("LLVM_fatlto"); + let _timer = prof.verbose_generic_activity("LLVM_fatlto"); - check_lto_allowed(&cgcx); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); + + check_lto_allowed(&cgcx, dcx); for (module, wp) in import_only_modules { needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, buffer: module }) @@ -997,15 +1010,21 @@ fn do_fat_lto( let module = B::run_and_optimize_fat_lto( cgcx, + prof, + &shared_emitter, + tm_factory, exported_symbols_for_lto, each_linked_rlib_for_lto, needs_fat_lto, ); - B::codegen(cgcx, module, &cgcx.module_config) + B::codegen(cgcx, prof, &shared_emitter, module, &cgcx.module_config) } -fn do_thin_lto<'a, B: ExtraBackendMethods>( - cgcx: &'a CodegenContext, +fn do_thin_lto( + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: SharedEmitter, + tm_factory: TargetMachineFactoryFn, exported_symbols_for_lto: Arc>, each_linked_rlib_for_lto: Vec, needs_thin_lto: Vec<(String, ::ThinBuffer)>, @@ -1014,9 +1033,12 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( WorkProduct, )>, ) -> Vec { - let _timer = cgcx.prof.verbose_generic_activity("LLVM_thinlto"); + let _timer = prof.verbose_generic_activity("LLVM_thinlto"); - check_lto_allowed(&cgcx); + let dcx = DiagCtxt::new(Box::new(shared_emitter.clone())); + let dcx = dcx.handle(); + + check_lto_allowed(&cgcx, dcx); let (coordinator_send, coordinator_receive) = channel(); @@ -1039,8 +1061,10 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( // bunch of work items onto our queue to do LTO. This all // happens on the coordinator thread but it's very quick so // we don't worry about tokens. - for (work, cost) in generate_thin_lto_work( + for (work, cost) in generate_thin_lto_work::( cgcx, + prof, + dcx, &exported_symbols_for_lto, &each_linked_rlib_for_lto, needs_thin_lto, @@ -1082,7 +1106,14 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( while used_token_count < tokens.len() + 1 && let Some((item, _)) = work_items.pop() { - spawn_thin_lto_work(&cgcx, coordinator_send.clone(), item); + spawn_thin_lto_work( + &cgcx, + prof, + shared_emitter.clone(), + Arc::clone(&tm_factory), + coordinator_send.clone(), + item, + ); used_token_count += 1; } } else { @@ -1106,7 +1137,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( } Err(e) => { let msg = &format!("failed to acquire jobserver token: {e}"); - cgcx.diag_emitter.fatal(msg); + shared_emitter.fatal(msg); codegen_aborted = Some(FatalError); } }, @@ -1143,13 +1174,16 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>( } fn execute_thin_lto_work_item( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: SharedEmitter, + tm_factory: TargetMachineFactoryFn, module: lto::ThinModule, ) -> CompiledModule { - let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", module.name()); + let _timer = prof.generic_activity_with_arg("codegen_module_perform_lto", module.name()); - let module = B::optimize_thin(cgcx, module); - B::codegen(cgcx, module, &cgcx.module_config) + let module = B::optimize_thin(cgcx, prof, &shared_emitter, tm_factory, module); + B::codegen(cgcx, prof, &shared_emitter, module, &cgcx.module_config) } /// Messages sent to the coordinator. @@ -1245,10 +1279,11 @@ fn start_executing_work( coordinator_receive: Receiver>, regular_config: Arc, allocator_config: Arc, - allocator_module: Option>, + mut allocator_module: Option>, coordinator_send: Sender>, -) -> thread::JoinHandle> { +) -> thread::JoinHandle, ()>> { let sess = tcx.sess; + let prof = sess.prof.clone(); let mut each_linked_rlib_for_lto = Vec::new(); let mut each_linked_rlib_file_for_lto = Vec::new(); @@ -1276,8 +1311,9 @@ fn start_executing_work( }) .expect("failed to spawn helper thread"); - let ol = tcx.backend_optimization_level(()); - let backend_features = tcx.global_backend_features(()); + let opt_level = tcx.backend_optimization_level(()); + let backend_features = tcx.global_backend_features(()).clone(); + let tm_factory = backend.target_machine_factory(tcx.sess, opt_level, &backend_features); let remark_dir = if let Some(ref dir) = sess.opts.unstable_opts.remark_dir { let result = fs::create_dir_all(dir).and_then(|_| dir.canonicalize()); @@ -1289,22 +1325,22 @@ fn start_executing_work( None }; - let cgcx = CodegenContext:: { + let cgcx = CodegenContext { crate_types: tcx.crate_types().to_vec(), lto: sess.lto(), + use_linker_plugin_lto: sess.opts.cg.linker_plugin_lto.enabled(), + dylib_lto: sess.opts.unstable_opts.dylib_lto, + prefer_dynamic: sess.opts.cg.prefer_dynamic, fewer_names: sess.fewer_names(), save_temps: sess.opts.cg.save_temps, time_trace: sess.opts.unstable_opts.llvm_time_trace, - opts: Arc::new(sess.opts.clone()), - prof: sess.prof.clone(), remark: sess.opts.cg.remark.clone(), remark_dir, incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()), - diag_emitter: shared_emitter.clone(), output_filenames: Arc::clone(tcx.output_filenames(())), module_config: regular_config, - allocator_config, - tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features), + opt_level, + backend_features, msvc_imps_needed: msvc_imps_needed(tcx), is_pe_coff: tcx.sess.target.is_like_windows, target_can_use_split_dwarf: tcx.sess.target_can_use_split_dwarf(), @@ -1497,16 +1533,9 @@ fn start_executing_work( let mut llvm_start_time: Option> = None; - let compiled_allocator_module = allocator_module.and_then(|allocator_module| { - match execute_optimize_work_item(&cgcx, allocator_module) { - WorkItemResult::Finished(compiled_module) => return Some(compiled_module), - WorkItemResult::NeedsFatLto(fat_lto_input) => needs_fat_lto.push(fat_lto_input), - WorkItemResult::NeedsThinLto(name, thin_buffer) => { - needs_thin_lto.push((name, thin_buffer)) - } - } - None - }); + if let Some(allocator_module) = &mut allocator_module { + B::optimize(&cgcx, &prof, &shared_emitter, allocator_module, &allocator_config); + } // Run the message loop while there's still anything that needs message // processing. Note that as soon as codegen is aborted we simply want to @@ -1543,7 +1572,14 @@ fn start_executing_work( let (item, _) = work_items.pop().expect("queue empty - queue_full_enough() broken?"); main_thread_state = MainThreadState::Lending; - spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); + spawn_work( + &cgcx, + &prof, + shared_emitter.clone(), + coordinator_send.clone(), + &mut llvm_start_time, + item, + ); } } } else if codegen_state == Completed { @@ -1561,7 +1597,14 @@ fn start_executing_work( MainThreadState::Idle => { if let Some((item, _)) = work_items.pop() { main_thread_state = MainThreadState::Lending; - spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); + spawn_work( + &cgcx, + &prof, + shared_emitter.clone(), + coordinator_send.clone(), + &mut llvm_start_time, + item, + ); } else { // There is no unstarted work, so let the main thread // take over for a running worker. Otherwise the @@ -1597,7 +1640,14 @@ fn start_executing_work( while running_with_own_token < tokens.len() && let Some((item, _)) = work_items.pop() { - spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); + spawn_work( + &cgcx, + &prof, + shared_emitter.clone(), + coordinator_send.clone(), + &mut llvm_start_time, + item, + ); running_with_own_token += 1; } } @@ -1733,36 +1783,53 @@ fn start_executing_work( assert!(compiled_modules.is_empty()); assert!(needs_thin_lto.is_empty()); - // This uses the implicit token - let module = do_fat_lto( - &cgcx, - &exported_symbols_for_lto, - &each_linked_rlib_file_for_lto, + if let Some(allocator_module) = allocator_module.take() { + needs_fat_lto.push(FatLtoInput::InMemory(allocator_module)); + } + + return Ok(MaybeLtoModules::FatLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, needs_fat_lto, lto_import_only_modules, - ); - compiled_modules.push(module); + }); } else if !needs_thin_lto.is_empty() || !lto_import_only_modules.is_empty() { assert!(compiled_modules.is_empty()); assert!(needs_fat_lto.is_empty()); - compiled_modules.extend(do_thin_lto( - &cgcx, - exported_symbols_for_lto, - each_linked_rlib_file_for_lto, - needs_thin_lto, - lto_import_only_modules, - )); + if cgcx.lto == Lto::ThinLocal { + compiled_modules.extend(do_thin_lto::( + &cgcx, + &prof, + shared_emitter.clone(), + tm_factory, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + )); + } else { + if let Some(allocator_module) = allocator_module.take() { + let (name, thin_buffer) = B::prepare_thin(allocator_module); + needs_thin_lto.push((name, thin_buffer)); + } + + return Ok(MaybeLtoModules::ThinLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + }); + } } - // Regardless of what order these modules completed in, report them to - // the backend in the same order every time to ensure that we're handing - // out deterministic results. - compiled_modules.sort_by(|a, b| a.name.cmp(&b.name)); - - Ok(CompiledModules { + Ok(MaybeLtoModules::NoLto { modules: compiled_modules, - allocator_module: compiled_allocator_module, + allocator_module: allocator_module.map(|allocator_module| { + B::codegen(&cgcx, &prof, &shared_emitter, allocator_module, &allocator_config) + }), }) }) .expect("failed to spawn coordinator thread"); @@ -1830,23 +1897,26 @@ fn start_executing_work( pub(crate) struct WorkerFatalError; fn spawn_work<'a, B: ExtraBackendMethods>( - cgcx: &'a CodegenContext, + cgcx: &CodegenContext, + prof: &'a SelfProfilerRef, + shared_emitter: SharedEmitter, coordinator_send: Sender>, llvm_start_time: &mut Option>, work: WorkItem, ) { if llvm_start_time.is_none() { - *llvm_start_time = Some(cgcx.prof.verbose_generic_activity("LLVM_passes")); + *llvm_start_time = Some(prof.verbose_generic_activity("LLVM_passes")); } let cgcx = cgcx.clone(); + let prof = prof.clone(); B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || { let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work { - WorkItem::Optimize(m) => execute_optimize_work_item(&cgcx, m), - WorkItem::CopyPostLtoArtifacts(m) => { - WorkItemResult::Finished(execute_copy_from_cache_work_item(&cgcx, m)) - } + WorkItem::Optimize(m) => execute_optimize_work_item(&cgcx, &prof, shared_emitter, m), + WorkItem::CopyPostLtoArtifacts(m) => WorkItemResult::Finished( + execute_copy_from_cache_work_item(&cgcx, &prof, shared_emitter, m), + ), })); let msg = match result { @@ -1866,17 +1936,25 @@ fn spawn_work<'a, B: ExtraBackendMethods>( .expect("failed to spawn work thread"); } -fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>( - cgcx: &'a CodegenContext, +fn spawn_thin_lto_work( + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: SharedEmitter, + tm_factory: TargetMachineFactoryFn, coordinator_send: Sender, work: ThinLtoWorkItem, ) { let cgcx = cgcx.clone(); + let prof = prof.clone(); B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || { let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work { - ThinLtoWorkItem::CopyPostLtoArtifacts(m) => execute_copy_from_cache_work_item(&cgcx, m), - ThinLtoWorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, m), + ThinLtoWorkItem::CopyPostLtoArtifacts(m) => { + execute_copy_from_cache_work_item(&cgcx, &prof, shared_emitter, m) + } + ThinLtoWorkItem::ThinLto(m) => { + execute_thin_lto_work_item(&cgcx, &prof, shared_emitter, tm_factory, m) + } })); let msg = match result { @@ -1935,11 +2013,7 @@ impl SharedEmitter { } impl Emitter for SharedEmitter { - fn emit_diagnostic( - &mut self, - mut diag: rustc_errors::DiagInner, - _registry: &rustc_errors::registry::Registry, - ) { + fn emit_diagnostic(&mut self, mut diag: rustc_errors::DiagInner) { // Check that we aren't missing anything interesting when converting to // the cut-down local `DiagInner`. assert!(!diag.span.has_span_labels()); @@ -2052,13 +2126,13 @@ impl SharedEmitterMain { pub struct Coordinator { sender: Sender>, - future: Option>>, + future: Option, ()>>>, // Only used for the Message type. phantom: PhantomData, } impl Coordinator { - fn join(mut self) -> std::thread::Result> { + fn join(mut self) -> std::thread::Result, ()>> { self.future.take().unwrap().join() } } @@ -2089,8 +2163,9 @@ pub struct OngoingCodegen { impl OngoingCodegen { pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap) { self.shared_emitter_main.check(sess, true); - let compiled_modules = sess.time("join_worker_thread", || match self.coordinator.join() { - Ok(Ok(compiled_modules)) => compiled_modules, + + let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { + Ok(Ok(maybe_lto_modules)) => maybe_lto_modules, Ok(Err(())) => { sess.dcx().abort_if_errors(); panic!("expected abort due to worker thread errors") @@ -2102,6 +2177,82 @@ impl OngoingCodegen { sess.dcx().abort_if_errors(); + let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); + + // Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics + let compiled_modules = catch_fatal_errors(|| match maybe_lto_modules { + MaybeLtoModules::NoLto { modules, allocator_module } => { + drop(shared_emitter); + CompiledModules { modules, allocator_module } + } + MaybeLtoModules::FatLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_fat_lto, + lto_import_only_modules, + } => { + let tm_factory = self.backend.target_machine_factory( + sess, + cgcx.opt_level, + &cgcx.backend_features, + ); + + CompiledModules { + modules: vec![do_fat_lto( + &cgcx, + &sess.prof, + shared_emitter, + tm_factory, + &exported_symbols_for_lto, + &each_linked_rlib_file_for_lto, + needs_fat_lto, + lto_import_only_modules, + )], + allocator_module: None, + } + } + MaybeLtoModules::ThinLto { + cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + } => { + let tm_factory = self.backend.target_machine_factory( + sess, + cgcx.opt_level, + &cgcx.backend_features, + ); + + CompiledModules { + modules: do_thin_lto::( + &cgcx, + &sess.prof, + shared_emitter, + tm_factory, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + ), + allocator_module: None, + } + } + }); + + shared_emitter_main.check(sess, true); + + sess.dcx().abort_if_errors(); + + let mut compiled_modules = + compiled_modules.expect("fatal error emitted but not sent to SharedEmitter"); + + // Regardless of what order these modules completed in, report them to + // the backend in the same order every time to ensure that we're handing + // out deterministic results. + compiled_modules.modules.sort_by(|a, b| a.name.cmp(&b.name)); + let work_products = copy_all_cgu_workproducts_to_incr_comp_cache_dir(sess, &compiled_modules); produce_final_output_artifacts(sess, &compiled_modules, &self.output_filenames); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 8ab0b367f08a..85c8890d661c 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -6,7 +6,8 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; use rustc_ast::expand::allocator::{ - ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorTy, + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorMethodInput, + AllocatorTy, }; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; @@ -48,9 +49,7 @@ use crate::meth::load_vtable; use crate::mir::operand::OperandValue; use crate::mir::place::PlaceRef; use crate::traits::*; -use crate::{ - CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, ModuleKind, errors, meth, mir, -}; +use crate::{CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, errors, meth, mir}; pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate { match (op, signed) { @@ -671,7 +670,7 @@ pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec { + CrateType::StaticLib | CrateType::Rlib => { // We don't invoke the linker for these, so we don't need to collect the NatVis for // them. false @@ -1112,7 +1111,7 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> // know that later). If we are not doing LTO, there is only one optimized // version of each module, so we re-use that. let dep_node = cgu.codegen_dep_node(tcx); - tcx.dep_graph.assert_dep_node_not_yet_allocated_in_current_session(&dep_node, || { + tcx.dep_graph.assert_dep_node_not_yet_allocated_in_current_session(tcx.sess, &dep_node, || { format!( "CompileCodegenUnit dep-node for CGU `{}` already exists before marking.", cgu.name() @@ -1125,9 +1124,8 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> // reuse pre-LTO artifacts match compute_per_cgu_lto_type( &tcx.sess.lto(), - &tcx.sess.opts, + tcx.sess.opts.cg.linker_plugin_lto.enabled(), tcx.crate_types(), - ModuleKind::Regular, ) { ComputedLtoType::No => CguReuse::PostLto, _ => CguReuse::PreLto, diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 0ab0cb0ef88a..edd73f418036 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -2,20 +2,23 @@ use std::str::FromStr; use rustc_abi::{Align, ExternAbi}; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; -use rustc_ast::{LitKind, MetaItem, MetaItemInner, attr}; -use rustc_hir::attrs::{AttributeKind, InlineAttr, InstructionSetAttr, RtsanSetting, UsedBy}; +use rustc_ast::{LitKind, MetaItem, MetaItemInner}; +use rustc_hir::attrs::{ + AttributeKind, EiiImplResolution, InlineAttr, Linkage, RtsanSetting, UsedBy, +}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; -use rustc_hir::{self as hir, Attribute, LangItem, find_attr, lang_items}; +use rustc_hir::{self as hir, Attribute, find_attr}; use rustc_middle::middle::codegen_fn_attrs::{ CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs, }; +use rustc_middle::mir::mono::Visibility; use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; -use rustc_span::{Ident, Span, sym}; +use rustc_span::{Span, sym}; use rustc_target::spec::Os; use crate::errors; @@ -44,90 +47,6 @@ fn try_fn_sig<'tcx>( } } -// FIXME(jdonszelmann): remove when instruction_set becomes a parsed attr -fn parse_instruction_set_attr(tcx: TyCtxt<'_>, attr: &Attribute) -> Option { - let list = attr.meta_item_list()?; - - match &list[..] { - [MetaItemInner::MetaItem(set)] => { - let segments = set.path.segments.iter().map(|x| x.ident.name).collect::>(); - match segments.as_slice() { - [sym::arm, sym::a32 | sym::t32] if !tcx.sess.target.has_thumb_interworking => { - tcx.dcx().emit_err(errors::UnsupportedInstructionSet { span: attr.span() }); - None - } - [sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32), - [sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32), - _ => { - tcx.dcx().emit_err(errors::InvalidInstructionSet { span: attr.span() }); - None - } - } - } - [] => { - tcx.dcx().emit_err(errors::BareInstructionSet { span: attr.span() }); - None - } - _ => { - tcx.dcx().emit_err(errors::MultipleInstructionSet { span: attr.span() }); - None - } - } -} - -// FIXME(jdonszelmann): remove when patchable_function_entry becomes a parsed attr -fn parse_patchable_function_entry( - tcx: TyCtxt<'_>, - attr: &Attribute, -) -> Option { - attr.meta_item_list().and_then(|l| { - let mut prefix = None; - let mut entry = None; - for item in l { - let Some(meta_item) = item.meta_item() else { - tcx.dcx().emit_err(errors::ExpectedNameValuePair { span: item.span() }); - continue; - }; - - let Some(name_value_lit) = meta_item.name_value_literal() else { - tcx.dcx().emit_err(errors::ExpectedNameValuePair { span: item.span() }); - continue; - }; - - let attrib_to_write = match meta_item.name() { - Some(sym::prefix_nops) => &mut prefix, - Some(sym::entry_nops) => &mut entry, - _ => { - tcx.dcx().emit_err(errors::UnexpectedParameterName { - span: item.span(), - prefix_nops: sym::prefix_nops, - entry_nops: sym::entry_nops, - }); - continue; - } - }; - - let rustc_ast::LitKind::Int(val, _) = name_value_lit.kind else { - tcx.dcx().emit_err(errors::InvalidLiteralValue { span: name_value_lit.span }); - continue; - }; - - let Ok(val) = val.get().try_into() else { - tcx.dcx().emit_err(errors::OutOfRangeInteger { span: name_value_lit.span }); - continue; - }; - - *attrib_to_write = Some(val); - } - - if let (None, None) = (prefix, entry) { - tcx.dcx().span_err(attr.span(), "must specify at least one parameter"); - } - - Some(PatchableFunctionEntry::from_prefix_and_entry(prefix.unwrap_or(0), entry.unwrap_or(0))) - }) -} - /// Spans that are collected when processing built-in attributes, /// that are useful for emitting diagnostics later. #[derive(Default)] @@ -149,194 +68,236 @@ fn process_builtin_attrs( let mut interesting_spans = InterestingAttributeDiagnosticSpans::default(); let rust_target_features = tcx.rust_target_features(LOCAL_CRATE); - for attr in attrs.iter() { - if let hir::Attribute::Parsed(p) = attr { - match p { - AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD, - AttributeKind::ExportName { name, .. } => { - codegen_fn_attrs.symbol_name = Some(*name) - } - AttributeKind::Inline(inline, span) => { - codegen_fn_attrs.inline = *inline; - interesting_spans.inline = Some(*span); - } - AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED, - AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align), - AttributeKind::LinkName { name, .. } => { - // FIXME Remove check for foreign functions once #[link_name] on non-foreign - // functions is a hard error - if tcx.is_foreign_item(did) { - codegen_fn_attrs.symbol_name = Some(*name); - } - } - AttributeKind::LinkOrdinal { ordinal, span } => { - codegen_fn_attrs.link_ordinal = Some(*ordinal); - interesting_spans.link_ordinal = Some(*span); - } - AttributeKind::LinkSection { name, .. } => { - codegen_fn_attrs.link_section = Some(*name) - } - AttributeKind::NoMangle(attr_span) => { - interesting_spans.no_mangle = Some(*attr_span); - if tcx.opt_item_name(did.to_def_id()).is_some() { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; - } else { - tcx.dcx().span_delayed_bug( - *attr_span, - "no_mangle should be on a named function", - ); - } - } - AttributeKind::Optimize(optimize, _) => codegen_fn_attrs.optimize = *optimize, - AttributeKind::TargetFeature { features, attr_span, was_forced } => { - let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else { - tcx.dcx().span_delayed_bug(*attr_span, "target_feature applied to non-fn"); - continue; - }; - let safe_target_features = - matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures); - codegen_fn_attrs.safe_target_features = safe_target_features; - if safe_target_features && !was_forced { - if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { - // The `#[target_feature]` attribute is allowed on - // WebAssembly targets on all functions. Prior to stabilizing - // the `target_feature_11` feature, `#[target_feature]` was - // only permitted on unsafe functions because on most targets - // execution of instructions that are not supported is - // considered undefined behavior. For WebAssembly which is a - // 100% safe target at execution time it's not possible to - // execute undefined instructions, and even if a future - // feature was added in some form for this it would be a - // deterministic trap. There is no undefined behavior when - // executing WebAssembly so `#[target_feature]` is allowed - // on safe functions (but again, only for WebAssembly) - // - // Note that this is also allowed if `actually_rustdoc` so - // if a target is documenting some wasm-specific code then - // it's not spuriously denied. - // - // Now that `#[target_feature]` is permitted on safe functions, - // this exception must still exist for allowing the attribute on - // `main`, `start`, and other functions that are not usually - // allowed. - } else { - check_target_feature_trait_unsafe(tcx, did, *attr_span); - } - } - from_target_feature_attr( - tcx, - did, - features, - *was_forced, - rust_target_features, - &mut codegen_fn_attrs.target_features, - ); - } - AttributeKind::TrackCaller(attr_span) => { - let is_closure = tcx.is_closure_like(did.to_def_id()); - - if !is_closure - && let Some(fn_sig) = try_fn_sig(tcx, did, *attr_span) - && fn_sig.skip_binder().abi() != ExternAbi::Rust - { - tcx.dcx().emit_err(errors::RequiresRustAbi { span: *attr_span }); - } - if is_closure - && !tcx.features().closure_track_caller() - && !attr_span.allows_unstable(sym::closure_track_caller) - { - feature_err( - &tcx.sess, - sym::closure_track_caller, - *attr_span, - "`#[track_caller]` on closures is currently unstable", - ) - .emit(); - } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER - } - AttributeKind::Used { used_by, .. } => match used_by { - UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER, - UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER, - UsedBy::Default => { - let used_form = if tcx.sess.target.os == Os::Illumos { - // illumos' `ld` doesn't support a section header that would represent - // `#[used(linker)]`, see - // https://github.com/rust-lang/rust/issues/146169. For that target, - // downgrade as if `#[used(compiler)]` was requested and hope for the - // best. - CodegenFnAttrFlags::USED_COMPILER - } else { - CodegenFnAttrFlags::USED_LINKER - }; - codegen_fn_attrs.flags |= used_form; - } - }, - AttributeKind::FfiConst(_) => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST - } - AttributeKind::FfiPure(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, - AttributeKind::StdInternalSymbol(_) => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL - } - AttributeKind::Linkage(linkage, span) => { - let linkage = Some(*linkage); - - if tcx.is_foreign_item(did) { - codegen_fn_attrs.import_linkage = linkage; - - if tcx.is_mutable_static(did.into()) { - let mut diag = tcx.dcx().struct_span_err( - *span, - "extern mutable statics are not allowed with `#[linkage]`", - ); - diag.note( - "marking the extern static mutable would allow changing which \ - symbol the static references rather than make the target of the \ - symbol mutable", - ); - diag.emit(); - } - } else { - codegen_fn_attrs.linkage = linkage; - } - } - AttributeKind::Sanitize { span, .. } => { - interesting_spans.sanitize = Some(*span); - } - AttributeKind::ObjcClass { classname, .. } => { - codegen_fn_attrs.objc_class = Some(*classname); - } - AttributeKind::ObjcSelector { methname, .. } => { - codegen_fn_attrs.objc_selector = Some(*methname); - } - _ => {} + let parsed_attrs = attrs + .iter() + .filter_map(|attr| if let hir::Attribute::Parsed(attr) = attr { Some(attr) } else { None }); + for attr in parsed_attrs { + match attr { + AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD, + AttributeKind::ExportName { name, .. } => codegen_fn_attrs.symbol_name = Some(*name), + AttributeKind::Inline(inline, span) => { + codegen_fn_attrs.inline = *inline; + interesting_spans.inline = Some(*span); } - } + AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED, + AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align), + AttributeKind::LinkName { name, .. } => { + // FIXME Remove check for foreign functions once #[link_name] on non-foreign + // functions is a hard error + if tcx.is_foreign_item(did) { + codegen_fn_attrs.symbol_name = Some(*name); + } + } + AttributeKind::LinkOrdinal { ordinal, span } => { + codegen_fn_attrs.link_ordinal = Some(*ordinal); + interesting_spans.link_ordinal = Some(*span); + } + AttributeKind::LinkSection { name, .. } => codegen_fn_attrs.link_section = Some(*name), + AttributeKind::NoMangle(attr_span) => { + interesting_spans.no_mangle = Some(*attr_span); + if tcx.opt_item_name(did.to_def_id()).is_some() { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; + } else { + tcx.dcx() + .span_delayed_bug(*attr_span, "no_mangle should be on a named function"); + } + } + AttributeKind::Optimize(optimize, _) => codegen_fn_attrs.optimize = *optimize, + AttributeKind::TargetFeature { features, attr_span, was_forced } => { + let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else { + tcx.dcx().span_delayed_bug(*attr_span, "target_feature applied to non-fn"); + continue; + }; + let safe_target_features = + matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures); + codegen_fn_attrs.safe_target_features = safe_target_features; + if safe_target_features && !was_forced { + if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { + // The `#[target_feature]` attribute is allowed on + // WebAssembly targets on all functions. Prior to stabilizing + // the `target_feature_11` feature, `#[target_feature]` was + // only permitted on unsafe functions because on most targets + // execution of instructions that are not supported is + // considered undefined behavior. For WebAssembly which is a + // 100% safe target at execution time it's not possible to + // execute undefined instructions, and even if a future + // feature was added in some form for this it would be a + // deterministic trap. There is no undefined behavior when + // executing WebAssembly so `#[target_feature]` is allowed + // on safe functions (but again, only for WebAssembly) + // + // Note that this is also allowed if `actually_rustdoc` so + // if a target is documenting some wasm-specific code then + // it's not spuriously denied. + // + // Now that `#[target_feature]` is permitted on safe functions, + // this exception must still exist for allowing the attribute on + // `main`, `start`, and other functions that are not usually + // allowed. + } else { + check_target_feature_trait_unsafe(tcx, did, *attr_span); + } + } + from_target_feature_attr( + tcx, + did, + features, + *was_forced, + rust_target_features, + &mut codegen_fn_attrs.target_features, + ); + } + AttributeKind::TrackCaller(attr_span) => { + let is_closure = tcx.is_closure_like(did.to_def_id()); - let Some(Ident { name, .. }) = attr.ident() else { - continue; - }; + if !is_closure + && let Some(fn_sig) = try_fn_sig(tcx, did, *attr_span) + && fn_sig.skip_binder().abi() != ExternAbi::Rust + { + tcx.dcx().emit_err(errors::RequiresRustAbi { span: *attr_span }); + } + if is_closure + && !tcx.features().closure_track_caller() + && !attr_span.allows_unstable(sym::closure_track_caller) + { + feature_err( + &tcx.sess, + sym::closure_track_caller, + *attr_span, + "`#[track_caller]` on closures is currently unstable", + ) + .emit(); + } + codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER + } + AttributeKind::Used { used_by, .. } => match used_by { + UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER, + UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER, + UsedBy::Default => { + let used_form = if tcx.sess.target.os == Os::Illumos { + // illumos' `ld` doesn't support a section header that would represent + // `#[used(linker)]`, see + // https://github.com/rust-lang/rust/issues/146169. For that target, + // downgrade as if `#[used(compiler)]` was requested and hope for the + // best. + CodegenFnAttrFlags::USED_COMPILER + } else { + CodegenFnAttrFlags::USED_LINKER + }; + codegen_fn_attrs.flags |= used_form; + } + }, + AttributeKind::FfiConst(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST, + AttributeKind::FfiPure(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, + AttributeKind::RustcStdInternalSymbol(_) => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL + } + AttributeKind::Linkage(linkage, span) => { + let linkage = Some(*linkage); - match name { - sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR, - sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, - sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, - sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR, - sym::rustc_allocator_zeroed => { + if tcx.is_foreign_item(did) { + codegen_fn_attrs.import_linkage = linkage; + + if tcx.is_mutable_static(did.into()) { + let mut diag = tcx.dcx().struct_span_err( + *span, + "extern mutable statics are not allowed with `#[linkage]`", + ); + diag.note( + "marking the extern static mutable would allow changing which \ + symbol the static references rather than make the target of the \ + symbol mutable", + ); + diag.emit(); + } + } else { + codegen_fn_attrs.linkage = linkage; + } + } + AttributeKind::Sanitize { span, .. } => { + interesting_spans.sanitize = Some(*span); + } + AttributeKind::RustcObjcClass { classname, .. } => { + codegen_fn_attrs.objc_class = Some(*classname); + } + AttributeKind::RustcObjcSelector { methname, .. } => { + codegen_fn_attrs.objc_selector = Some(*methname); + } + AttributeKind::EiiForeignItem => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM; + } + AttributeKind::EiiImpls(impls) => { + for i in impls { + let foreign_item = match i.resolution { + EiiImplResolution::Macro(def_id) => { + let Some(extern_item) = find_attr!( + tcx.get_all_attrs(def_id), + AttributeKind::EiiDeclaration(target) => target.foreign_item + ) else { + tcx.dcx().span_delayed_bug( + i.span, + "resolved to something that's not an EII", + ); + continue; + }; + extern_item + } + EiiImplResolution::Known(decl) => decl.foreign_item, + EiiImplResolution::Error(_eg) => continue, + }; + + // this is to prevent a bug where a single crate defines both the default and explicit implementation + // for an EII. In that case, both of them may be part of the same final object file. I'm not 100% sure + // what happens, either rustc deduplicates the symbol or llvm, or it's random/order-dependent. + // However, the fact that the default one of has weak linkage isn't considered and you sometimes get that + // the default implementation is used while an explicit implementation is given. + if + // if this is a default impl + i.is_default + // iterate over all implementations *in the current crate* + // (this is ok since we generate codegen fn attrs in the local crate) + // if any of them is *not default* then don't emit the alias. + && tcx.externally_implementable_items(LOCAL_CRATE).get(&foreign_item).expect("at least one").1.iter().any(|(_, imp)| !imp.is_default) + { + continue; + } + + codegen_fn_attrs.foreign_item_symbol_aliases.push(( + foreign_item, + if i.is_default { Linkage::LinkOnceAny } else { Linkage::External }, + Visibility::Default, + )); + codegen_fn_attrs.flags |= CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM; + } + } + AttributeKind::ThreadLocal => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL + } + AttributeKind::InstructionSet(instruction_set) => { + codegen_fn_attrs.instruction_set = Some(*instruction_set) + } + AttributeKind::RustcAllocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR + } + AttributeKind::RustcDeallocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR + } + AttributeKind::RustcReallocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR + } + AttributeKind::RustcAllocatorZeroed => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } - sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL, - sym::instruction_set => { - codegen_fn_attrs.instruction_set = parse_instruction_set_attr(tcx, attr) + AttributeKind::RustcNounwind => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND } - sym::patchable_function_entry => { - codegen_fn_attrs.patchable_function_entry = - parse_patchable_function_entry(tcx, attr); - } - sym::rustc_offload_kernel => { + AttributeKind::RustcOffloadKernel => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::OFFLOAD_KERNEL } + AttributeKind::PatchableFunctionEntry { prefix, entry } => { + codegen_fn_attrs.patchable_function_entry = + Some(PatchableFunctionEntry::from_prefix_and_entry(*prefix, *entry)); + } _ => {} } } @@ -392,7 +353,7 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // When `no_builtins` is applied at the crate level, we should add the // `no-builtins` attribute to each function to ensure it takes effect in LTO. let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID); - let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); + let no_builtins = find_attr!(crate_attrs, AttributeKind::NoBuiltins); if no_builtins { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_BUILTINS; } @@ -411,6 +372,12 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way // both for exports and imports through foreign items. This is handled further, // during symbol mangling logic. + } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) + { + // * externally implementable items keep their mangled symbol name. + // multiple EIIs can have the same name, so not mangling them would be a bug. + // Implementing an EII does the appropriate name resolution to make sure the implementations + // get the same symbol name as the *mangled* foreign item they refer to so that's all good. } else if codegen_fn_attrs.symbol_name.is_some() { // * This can be overridden with the `#[link_name]` attribute } else { @@ -537,7 +504,7 @@ fn handle_lang_items( attrs: &[Attribute], codegen_fn_attrs: &mut CodegenFnAttrs, ) { - let lang_item = lang_items::extract(attrs).and_then(|(name, _)| LangItem::from_name(name)); + let lang_item = find_attr!(attrs, AttributeKind::Lang(lang, _) => lang); // Weak lang items have the same semantics as "std internal" symbols in the // sense that they're preserved through all our LTO passes and only @@ -721,11 +688,10 @@ pub fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option { }; // First read the ret symbol from the attribute - let ret_symbol = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity { - p1.segments.first().unwrap().ident - } else { + let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity else { span_bug!(attr.span(), "rustc_autodiff attribute must contain the return activity"); }; + let ret_symbol = p1.segments.first().unwrap().ident; // Then parse it into an actual DiffActivity let Ok(ret_activity) = DiffActivity::from_str(ret_symbol.as_str()) else { diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 18279a4d05fe..1c88a8da5ea9 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -109,14 +109,14 @@ fn push_debuginfo_type_name<'tcx>( ty_and_layout, &|output, visited| { push_item_name(tcx, def.did(), true, output); - push_generic_params_internal(tcx, args, output, visited); + push_generic_args_internal(tcx, args, output, visited); }, output, visited, ); } else { push_item_name(tcx, def.did(), qualified, output); - push_generic_params_internal(tcx, args, output, visited); + push_generic_args_internal(tcx, args, output, visited); } } ty::Tuple(component_types) => { @@ -253,19 +253,18 @@ fn push_debuginfo_type_name<'tcx>( ); push_item_name(tcx, principal.def_id, qualified, output); let principal_has_generic_params = - push_generic_params_internal(tcx, principal.args, output, visited); + push_generic_args_internal(tcx, principal.args, output, visited); let projection_bounds: SmallVec<[_; 4]> = trait_data .projection_bounds() .map(|bound| { let ExistentialProjection { def_id: item_def_id, term, .. } = tcx.instantiate_bound_regions_with_erased(bound); - // FIXME(associated_const_equality): allow for consts here - (item_def_id, term.expect_type()) + (item_def_id, term) }) .collect(); - if projection_bounds.len() != 0 { + if !projection_bounds.is_empty() { if principal_has_generic_params { // push_generic_params_internal() above added a `>` but we actually // want to add more items to that list, so remove that again... @@ -279,17 +278,17 @@ fn push_debuginfo_type_name<'tcx>( output.push('<'); } - for (item_def_id, ty) in projection_bounds { + for (item_def_id, term) in projection_bounds { if cpp_like_debuginfo { output.push_str("assoc$<"); push_item_name(tcx, item_def_id, false, output); push_arg_separator(cpp_like_debuginfo, output); - push_debuginfo_type_name(tcx, ty, true, output, visited); + push_debuginfo_term_name(tcx, term, true, output, visited); push_close_angle_bracket(cpp_like_debuginfo, output); } else { push_item_name(tcx, item_def_id, false, output); output.push('='); - push_debuginfo_type_name(tcx, ty, true, output, visited); + push_debuginfo_term_name(tcx, term, true, output, visited); } push_arg_separator(cpp_like_debuginfo, output); } @@ -533,7 +532,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>( tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref); push_item_name(tcx, trait_ref.def_id, true, &mut vtable_name); visited.clear(); - push_generic_params_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); + push_generic_args_internal(tcx, trait_ref.args, &mut vtable_name, &mut visited); } else { vtable_name.push('_'); } @@ -631,7 +630,13 @@ fn push_unqualified_item_name( }; } -fn push_generic_params_internal<'tcx>( +pub fn push_generic_args<'tcx>(tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, output: &mut String) { + let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name"); + let mut visited = FxHashSet::default(); + push_generic_args_internal(tcx, args, output, &mut visited); +} + +fn push_generic_args_internal<'tcx>( tcx: TyCtxt<'tcx>, args: GenericArgsRef<'tcx>, output: &mut String, @@ -646,14 +651,10 @@ fn push_generic_params_internal<'tcx>( output.push('<'); - for type_parameter in args { - match type_parameter { - GenericArgKind::Type(type_parameter) => { - push_debuginfo_type_name(tcx, type_parameter, true, output, visited); - } - GenericArgKind::Const(ct) => { - push_const_param(tcx, ct, output); - } + for arg in args { + match arg { + GenericArgKind::Type(ty) => push_debuginfo_type_name(tcx, ty, true, output, visited), + GenericArgKind::Const(ct) => push_debuginfo_const_name(tcx, ct, output), other => bug!("Unexpected non-erasable generic: {:?}", other), } @@ -665,7 +666,20 @@ fn push_generic_params_internal<'tcx>( true } -fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut String) { +fn push_debuginfo_term_name<'tcx>( + tcx: TyCtxt<'tcx>, + term: ty::Term<'tcx>, + qualified: bool, + output: &mut String, + visited: &mut FxHashSet>, +) { + match term.kind() { + ty::TermKind::Ty(ty) => push_debuginfo_type_name(tcx, ty, qualified, output, visited), + ty::TermKind::Const(ct) => push_debuginfo_const_name(tcx, ct, output), + } +} + +fn push_debuginfo_const_name<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut String) { match ct.kind() { ty::ConstKind::Param(param) => { write!(output, "{}", param.name) @@ -715,16 +729,6 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S .unwrap(); } -pub fn push_generic_params<'tcx>( - tcx: TyCtxt<'tcx>, - args: GenericArgsRef<'tcx>, - output: &mut String, -) { - let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name"); - let mut visited = FxHashSet::default(); - push_generic_params_internal(tcx, args, output, &mut visited); -} - fn push_closure_or_coroutine_name<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, @@ -767,7 +771,7 @@ fn push_closure_or_coroutine_name<'tcx>( // FIXME(async_closures): This is probably not going to be correct w.r.t. // multiple coroutine flavors. Maybe truncate to (parent + 1)? let args = args.truncate_to(tcx, generics); - push_generic_params_internal(tcx, args, output, visited); + push_generic_args_internal(tcx, args, output, visited); } fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 84be2af3c9a7..74f7829ace95 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -8,7 +8,7 @@ use std::process::ExitStatus; use rustc_errors::codes::*; use rustc_errors::{ - Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, + Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level, msg, }; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_middle::ty::layout::LayoutError; @@ -17,10 +17,14 @@ use rustc_span::{Span, Symbol}; use crate::assert_module_sources::CguReuse; use crate::back::command::Command; -use crate::fluent_generated as fluent; #[derive(Diagnostic)] -#[diag(codegen_ssa_incorrect_cgu_reuse_type)] +#[diag( + "CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least -> + [one] {\"at least \"} + *[other] {\"\"} + }`{$expected_reuse}`" +)] pub(crate) struct IncorrectCguReuseType<'a> { #[primary_span] pub span: Span, @@ -31,38 +35,32 @@ pub(crate) struct IncorrectCguReuseType<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_cgu_not_recorded)] +#[diag("CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded")] pub(crate) struct CguNotRecorded<'a> { pub cgu_user_name: &'a str, pub cgu_name: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_reuse_kind)] -pub(crate) struct UnknownReuseKind { - #[primary_span] - pub span: Span, - pub kind: Symbol, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_missing_query_depgraph)] +#[diag("found CGU-reuse attribute but `-Zquery-dep-graph` was not specified")] pub(crate) struct MissingQueryDepGraph { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_malformed_cgu_name)] -pub(crate) struct MalformedCguName { +#[diag( + "found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case)" +)] +pub(crate) struct MalformedCguName<'a> { #[primary_span] pub span: Span, - pub user_path: String, - pub crate_name: String, + pub user_path: &'a str, + pub crate_name: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_no_module_named)] +#[diag("no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names}")] pub(crate) struct NoModuleNamed<'a> { #[primary_span] pub span: Span, @@ -72,133 +70,56 @@ pub(crate) struct NoModuleNamed<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_field_associated_value_expected)] -pub(crate) struct FieldAssociatedValueExpected { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_no_field)] -pub(crate) struct NoField { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_lib_def_write_failure)] +#[diag("failed to write lib.def file: {$error}")] pub(crate) struct LibDefWriteFailure { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_version_script_write_failure)] +#[diag("failed to write version script: {$error}")] pub(crate) struct VersionScriptWriteFailure { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_symbol_file_write_failure)] +#[diag("failed to write symbols file: {$error}")] pub(crate) struct SymbolFileWriteFailure { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_ld64_unimplemented_modifier)] +#[diag("`as-needed` modifier not implemented yet for ld64")] pub(crate) struct Ld64UnimplementedModifier; #[derive(Diagnostic)] -#[diag(codegen_ssa_linker_unsupported_modifier)] +#[diag("`as-needed` modifier not supported for current linker")] pub(crate) struct LinkerUnsupportedModifier; #[derive(Diagnostic)] -#[diag(codegen_ssa_L4Bender_exporting_symbols_unimplemented)] +#[diag("exporting symbols not implemented yet for L4Bender")] pub(crate) struct L4BenderExportingSymbolsUnimplemented; #[derive(Diagnostic)] -#[diag(codegen_ssa_no_natvis_directory)] +#[diag("error enumerating natvis directory: {$error}")] pub(crate) struct NoNatvisDirectory { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_no_saved_object_file)] +#[diag("cached cgu {$cgu_name} should have an object file, but doesn't")] pub(crate) struct NoSavedObjectFile<'a> { pub cgu_name: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_requires_rust_abi, code = E0737)] +#[diag("`#[track_caller]` requires Rust ABI", code = E0737)] pub(crate) struct RequiresRustAbi { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)] -pub(crate) struct UnsupportedInstructionSet { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_invalid_instruction_set, code = E0779)] -pub(crate) struct InvalidInstructionSet { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_bare_instruction_set, code = E0778)] -pub(crate) struct BareInstructionSet { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_multiple_instruction_set, code = E0779)] -pub(crate) struct MultipleInstructionSet { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_expected_name_value_pair)] -pub(crate) struct ExpectedNameValuePair { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_unexpected_parameter_name)] -pub(crate) struct UnexpectedParameterName { - #[primary_span] - #[label] - pub span: Span, - pub prefix_nops: Symbol, - pub entry_nops: Symbol, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_invalid_literal_value)] -pub(crate) struct InvalidLiteralValue { - #[primary_span] - #[label] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_out_of_range_integer)] -pub(crate) struct OutOfRangeInteger { - #[primary_span] - #[label] - pub span: Span, -} - -#[derive(Diagnostic)] -#[diag(codegen_ssa_copy_path_buf)] +#[diag("unable to copy {$source_file} to {$output_path}: {$error}")] pub(crate) struct CopyPathBuf { pub source_file: PathBuf, pub output_path: PathBuf, @@ -207,15 +128,15 @@ pub(crate) struct CopyPathBuf { // Reports Paths using `Debug` implementation rather than Path's `Display` implementation. #[derive(Diagnostic)] -#[diag(codegen_ssa_copy_path)] -pub struct CopyPath<'a> { +#[diag("could not copy {$from} to {$to}: {$error}")] +pub(crate) struct CopyPath<'a> { from: DebugArgPath<'a>, to: DebugArgPath<'a>, error: Error, } impl<'a> CopyPath<'a> { - pub fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> { + pub(crate) fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> { CopyPath { from: DebugArgPath(from), to: DebugArgPath(to), error } } } @@ -229,38 +150,42 @@ impl IntoDiagArg for DebugArgPath<'_> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_binary_output_to_tty)] -pub struct BinaryOutputToTty { +#[diag( + "option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty" +)] +pub(crate) struct BinaryOutputToTty { pub shorthand: &'static str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_ignoring_emit_path)] -pub struct IgnoringEmitPath { +#[diag("ignoring emit path because multiple .{$extension} files were produced")] +pub(crate) struct IgnoringEmitPath { pub extension: &'static str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_ignoring_output)] -pub struct IgnoringOutput { +#[diag("ignoring -o because multiple .{$extension} files were produced")] +pub(crate) struct IgnoringOutput { pub extension: &'static str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_create_temp_dir)] +#[diag("couldn't create a temp dir: {$error}")] pub(crate) struct CreateTempDir { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_add_native_library)] +#[diag("failed to add native library {$library_path}: {$error}")] pub(crate) struct AddNativeLibrary { pub library_path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_multiple_external_func_decl)] +#[diag( + "multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions" +)] pub(crate) struct MultipleExternalFuncDecl<'a> { #[primary_span] pub span: Span, @@ -270,16 +195,18 @@ pub(crate) struct MultipleExternalFuncDecl<'a> { #[derive(Diagnostic)] pub enum LinkRlibError { - #[diag(codegen_ssa_rlib_missing_format)] + #[diag("could not find formats for rlibs")] MissingFormat, - #[diag(codegen_ssa_rlib_only_rmeta_found)] + #[diag("could not find rlib for: `{$crate_name}`, found rmeta (metadata) file")] OnlyRmetaFound { crate_name: Symbol }, - #[diag(codegen_ssa_rlib_not_found)] + #[diag("could not find rlib for: `{$crate_name}`")] NotFound { crate_name: Symbol }, - #[diag(codegen_ssa_rlib_incompatible_dependency_formats)] + #[diag( + "`{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`)" + )] IncompatibleDependencyFormats { ty1: String, ty2: String, list1: String, list2: String }, } @@ -289,122 +216,122 @@ impl Diagnostic<'_, G> for ThorinErrorWrapper { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { let build = |msg| Diag::new(dcx, level, msg); match self.0 { - thorin::Error::ReadInput(_) => build(fluent::codegen_ssa_thorin_read_input_failure), + thorin::Error::ReadInput(_) => build(msg!("failed to read input file")), thorin::Error::ParseFileKind(_) => { - build(fluent::codegen_ssa_thorin_parse_input_file_kind) + build(msg!("failed to parse input file kind")) } thorin::Error::ParseObjectFile(_) => { - build(fluent::codegen_ssa_thorin_parse_input_object_file) + build(msg!("failed to parse input object file")) } thorin::Error::ParseArchiveFile(_) => { - build(fluent::codegen_ssa_thorin_parse_input_archive_file) + build(msg!("failed to parse input archive file")) } thorin::Error::ParseArchiveMember(_) => { - build(fluent::codegen_ssa_thorin_parse_archive_member) + build(msg!("failed to parse archive member")) } - thorin::Error::InvalidInputKind => build(fluent::codegen_ssa_thorin_invalid_input_kind), - thorin::Error::DecompressData(_) => build(fluent::codegen_ssa_thorin_decompress_data), + thorin::Error::InvalidInputKind => build(msg!("input is not an archive or elf object")), + thorin::Error::DecompressData(_) => build(msg!("failed to decompress compressed section")), thorin::Error::NamelessSection(_, offset) => { - build(fluent::codegen_ssa_thorin_section_without_name) + build(msg!("section without name at offset {$offset}")) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::RelocationWithInvalidSymbol(section, offset) => { - build(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol) + build(msg!("relocation with invalid symbol for section `{$section}` at offset {$offset}")) .with_arg("section", section) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::MultipleRelocations(section, offset) => { - build(fluent::codegen_ssa_thorin_multiple_relocations) + build(msg!("multiple relocations for section `{$section}` at offset {$offset}")) .with_arg("section", section) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::UnsupportedRelocation(section, offset) => { - build(fluent::codegen_ssa_thorin_unsupported_relocation) + build(msg!("unsupported relocation for section {$section} at offset {$offset}")) .with_arg("section", section) .with_arg("offset", format!("0x{offset:08x}")) } - thorin::Error::MissingDwoName(id) => build(fluent::codegen_ssa_thorin_missing_dwo_name) + thorin::Error::MissingDwoName(id) => build(msg!("missing path attribute to DWARF object ({$id})")) .with_arg("id", format!("0x{id:08x}")), thorin::Error::NoCompilationUnits => { - build(fluent::codegen_ssa_thorin_no_compilation_units) + build(msg!("input object has no compilation units")) } - thorin::Error::NoDie => build(fluent::codegen_ssa_thorin_no_die), + thorin::Error::NoDie => build(msg!("no top-level debugging information entry in compilation/type unit")), thorin::Error::TopLevelDieNotUnit => { - build(fluent::codegen_ssa_thorin_top_level_die_not_unit) + build(msg!("top-level debugging information entry is not a compilation/type unit")) } thorin::Error::MissingRequiredSection(section) => { - build(fluent::codegen_ssa_thorin_missing_required_section) + build(msg!("input object missing required section `{$section}`")) .with_arg("section", section) } thorin::Error::ParseUnitAbbreviations(_) => { - build(fluent::codegen_ssa_thorin_parse_unit_abbreviations) + build(msg!("failed to parse unit abbreviations")) } thorin::Error::ParseUnitAttribute(_) => { - build(fluent::codegen_ssa_thorin_parse_unit_attribute) + build(msg!("failed to parse unit attribute")) } thorin::Error::ParseUnitHeader(_) => { - build(fluent::codegen_ssa_thorin_parse_unit_header) + build(msg!("failed to parse unit header")) } - thorin::Error::ParseUnit(_) => build(fluent::codegen_ssa_thorin_parse_unit), + thorin::Error::ParseUnit(_) => build(msg!("failed to parse unit")), thorin::Error::IncompatibleIndexVersion(section, format, actual) => { - build(fluent::codegen_ssa_thorin_incompatible_index_version) + build(msg!("incompatible `{$section}` index version: found version {$actual}, expected version {$format}")) .with_arg("section", section) .with_arg("actual", actual) .with_arg("format", format) } thorin::Error::OffsetAtIndex(_, index) => { - build(fluent::codegen_ssa_thorin_offset_at_index).with_arg("index", index) + build(msg!("read offset at index {$index} of `.debug_str_offsets.dwo` section")).with_arg("index", index) } thorin::Error::StrAtOffset(_, offset) => { - build(fluent::codegen_ssa_thorin_str_at_offset) + build(msg!("read string at offset {$offset} of `.debug_str.dwo` section")) .with_arg("offset", format!("0x{offset:08x}")) } thorin::Error::ParseIndex(_, section) => { - build(fluent::codegen_ssa_thorin_parse_index).with_arg("section", section) + build(msg!("failed to parse `{$section}` index section")).with_arg("section", section) } thorin::Error::UnitNotInIndex(unit) => { - build(fluent::codegen_ssa_thorin_unit_not_in_index) + build(msg!("unit {$unit} from input package is not in its index")) .with_arg("unit", format!("0x{unit:08x}")) } thorin::Error::RowNotInIndex(_, row) => { - build(fluent::codegen_ssa_thorin_row_not_in_index).with_arg("row", row) + build(msg!("row {$row} found in index's hash table not present in index")).with_arg("row", row) } - thorin::Error::SectionNotInRow => build(fluent::codegen_ssa_thorin_section_not_in_row), - thorin::Error::EmptyUnit(unit) => build(fluent::codegen_ssa_thorin_empty_unit) + thorin::Error::SectionNotInRow => build(msg!("section not found in unit's row in index")), + thorin::Error::EmptyUnit(unit) => build(msg!("unit {$unit} in input DWARF object with no data")) .with_arg("unit", format!("0x{unit:08x}")), thorin::Error::MultipleDebugInfoSection => { - build(fluent::codegen_ssa_thorin_multiple_debug_info_section) + build(msg!("multiple `.debug_info.dwo` sections")) } thorin::Error::MultipleDebugTypesSection => { - build(fluent::codegen_ssa_thorin_multiple_debug_types_section) + build(msg!("multiple `.debug_types.dwo` sections in a package")) } - thorin::Error::NotSplitUnit => build(fluent::codegen_ssa_thorin_not_split_unit), - thorin::Error::DuplicateUnit(unit) => build(fluent::codegen_ssa_thorin_duplicate_unit) + thorin::Error::NotSplitUnit => build(msg!("regular compilation unit in object (missing dwo identifier)")), + thorin::Error::DuplicateUnit(unit) => build(msg!("duplicate split compilation unit ({$unit})")) .with_arg("unit", format!("0x{unit:08x}")), thorin::Error::MissingReferencedUnit(unit) => { - build(fluent::codegen_ssa_thorin_missing_referenced_unit) + build(msg!("unit {$unit} referenced by executable was not found")) .with_arg("unit", format!("0x{unit:08x}")) } thorin::Error::NoOutputObjectCreated => { - build(fluent::codegen_ssa_thorin_not_output_object_created) + build(msg!("no output object was created from inputs")) } thorin::Error::MixedInputEncodings => { - build(fluent::codegen_ssa_thorin_mixed_input_encodings) + build(msg!("input objects have mixed encodings")) } thorin::Error::Io(e) => { - build(fluent::codegen_ssa_thorin_io).with_arg("error", format!("{e}")) + build(msg!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::ObjectRead(e) => { - build(fluent::codegen_ssa_thorin_object_read).with_arg("error", format!("{e}")) + build(msg!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::ObjectWrite(e) => { - build(fluent::codegen_ssa_thorin_object_write).with_arg("error", format!("{e}")) + build(msg!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::GimliRead(e) => { - build(fluent::codegen_ssa_thorin_gimli_read).with_arg("error", format!("{e}")) + build(msg!("{$error}")).with_arg("error", format!("{e}")) } thorin::Error::GimliWrite(e) => { - build(fluent::codegen_ssa_thorin_gimli_write).with_arg("error", format!("{e}")) + build(msg!("{$error}")).with_arg("error", format!("{e}")) } _ => unimplemented!("Untranslated thorin error"), } @@ -422,7 +349,8 @@ pub(crate) struct LinkingFailed<'a> { impl Diagnostic<'_, G> for LinkingFailed<'_> { fn into_diag(mut self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_linking_failed); + let mut diag = + Diag::new(dcx, level, msg!("linking with `{$linker_path}` failed: {$exit_status}")); diag.arg("linker_path", format!("{}", self.linker_path.display())); diag.arg("exit_status", format!("{}", self.exit_status)); @@ -531,11 +459,11 @@ impl Diagnostic<'_, G> for LinkingFailed<'_> { // Trying to match an error from OS linkers // which by now we have no way to translate. if contains_undefined_ref { - diag.note(fluent::codegen_ssa_extern_funcs_not_found) - .note(fluent::codegen_ssa_specify_libraries_to_link); + diag.note(msg!("some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified")) + .note(msg!("use the `-l` flag to specify native libraries to link")); if rustc_session::utils::was_invoked_from_cargo() { - diag.note(fluent::codegen_ssa_use_cargo_directive); + diag.note(msg!("use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)")); } } diag @@ -543,49 +471,50 @@ impl Diagnostic<'_, G> for LinkingFailed<'_> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_link_exe_unexpected_error)] +#[diag("`link.exe` returned an unexpected error")] pub(crate) struct LinkExeUnexpectedError; pub(crate) struct LinkExeStatusStackBufferOverrun; impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for LinkExeStatusStackBufferOverrun { fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let mut diag = - Diag::new(dcx, level, fluent::codegen_ssa_link_exe_status_stack_buffer_overrun); - diag.note(fluent::codegen_ssa_abort_note); - diag.note(fluent::codegen_ssa_event_log_note); + let mut diag = Diag::new(dcx, level, msg!("0xc0000409 is `STATUS_STACK_BUFFER_OVERRUN`")); + diag.note(msg!( + "this may have been caused by a program abort and not a stack buffer overrun" + )); + diag.note(msg!("consider checking the Application Event Log for Windows Error Reporting events to see the fail fast error code")); diag } } #[derive(Diagnostic)] -#[diag(codegen_ssa_repair_vs_build_tools)] +#[diag("the Visual Studio build tools may need to be repaired using the Visual Studio installer")] pub(crate) struct RepairVSBuildTools; #[derive(Diagnostic)] -#[diag(codegen_ssa_missing_cpp_build_tool_component)] +#[diag("or a necessary component may be missing from the \"C++ build tools\" workload")] pub(crate) struct MissingCppBuildToolComponent; #[derive(Diagnostic)] -#[diag(codegen_ssa_select_cpp_build_tool_workload)] +#[diag("in the Visual Studio installer, ensure the \"C++ build tools\" workload is selected")] pub(crate) struct SelectCppBuildToolWorkload; #[derive(Diagnostic)] -#[diag(codegen_ssa_visual_studio_not_installed)] +#[diag("you may need to install Visual Studio build tools with the \"C++ build tools\" workload")] pub(crate) struct VisualStudioNotInstalled; #[derive(Diagnostic)] -#[diag(codegen_ssa_linker_not_found)] -#[note] +#[diag("linker `{$linker_path}` not found")] +#[note("{$error}")] pub(crate) struct LinkerNotFound { pub linker_path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_exe_linker)] -#[note] -#[note(codegen_ssa_command_note)] +#[diag("could not exec the linker `{$linker_path}`")] +#[note("{$error}")] +#[note("{$command_formatted}")] pub(crate) struct UnableToExeLinker { pub linker_path: PathBuf, pub error: Error, @@ -593,42 +522,46 @@ pub(crate) struct UnableToExeLinker { } #[derive(Diagnostic)] -#[diag(codegen_ssa_msvc_missing_linker)] +#[diag("the msvc targets depend on the msvc linker but `link.exe` was not found")] pub(crate) struct MsvcMissingLinker; #[derive(Diagnostic)] -#[diag(codegen_ssa_self_contained_linker_missing)] +#[diag( + "the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot" +)] pub(crate) struct SelfContainedLinkerMissing; #[derive(Diagnostic)] -#[diag(codegen_ssa_check_installed_visual_studio)] +#[diag( + "please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option" +)] pub(crate) struct CheckInstalledVisualStudio; #[derive(Diagnostic)] -#[diag(codegen_ssa_insufficient_vs_code_product)] +#[diag("VS Code is a different product, and is not sufficient")] pub(crate) struct InsufficientVSCodeProduct; #[derive(Diagnostic)] -#[diag(codegen_ssa_cpu_required)] +#[diag("target requires explicitly specifying a cpu with `-C target-cpu`")] pub(crate) struct CpuRequired; #[derive(Diagnostic)] -#[diag(codegen_ssa_processing_dymutil_failed)] -#[note] +#[diag("processing debug info with `dsymutil` failed: {$status}")] +#[note("{$output}")] pub(crate) struct ProcessingDymutilFailed { pub status: ExitStatus, pub output: String, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_run_dsymutil)] +#[diag("unable to run `dsymutil`: {$error}")] pub(crate) struct UnableToRunDsymutil { pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_stripping_debug_info_failed)] -#[note] +#[diag("stripping debug info with `{$util}` failed: {$status}")] +#[note("{$output}")] pub(crate) struct StrippingDebugInfoFailed<'a> { pub util: &'a str, pub status: ExitStatus, @@ -636,121 +569,129 @@ pub(crate) struct StrippingDebugInfoFailed<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_run)] +#[diag("unable to run `{$util}`: {$error}")] pub(crate) struct UnableToRun<'a> { pub util: &'a str, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_linker_file_stem)] +#[diag("couldn't extract file stem from specified linker")] pub(crate) struct LinkerFileStem; #[derive(Diagnostic)] -#[diag(codegen_ssa_static_library_native_artifacts)] +#[diag( + "link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms" +)] pub(crate) struct StaticLibraryNativeArtifacts; #[derive(Diagnostic)] -#[diag(codegen_ssa_static_library_native_artifacts_to_file)] +#[diag( + "native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms" +)] pub(crate) struct StaticLibraryNativeArtifactsToFile<'a> { pub path: &'a Path, } #[derive(Diagnostic)] -#[diag(codegen_ssa_link_script_unavailable)] +#[diag("can only use link script when linking with GNU-like linker")] pub(crate) struct LinkScriptUnavailable; #[derive(Diagnostic)] -#[diag(codegen_ssa_link_script_write_failure)] +#[diag("failed to write link script to {$path}: {$error}")] pub(crate) struct LinkScriptWriteFailure { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_failed_to_write)] +#[diag("failed to write {$path}: {$error}")] pub(crate) struct FailedToWrite { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unable_to_write_debugger_visualizer)] +#[diag("unable to write debugger visualizer file `{$path}`: {$error}")] pub(crate) struct UnableToWriteDebuggerVisualizer { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_rlib_archive_build_failure)] +#[diag("failed to build archive from rlib at `{$path}`: {$error}")] pub(crate) struct RlibArchiveBuildFailure { pub path: PathBuf, pub error: Error, } #[derive(Diagnostic)] -// Public for rustc_codegen_llvm::back::archive +// Public for ArchiveBuilderBuilder::extract_bundled_libs pub enum ExtractBundledLibsError<'a> { - #[diag(codegen_ssa_extract_bundled_libs_open_file)] + #[diag("failed to open file '{$rlib}': {$error}")] OpenFile { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_mmap_file)] + #[diag("failed to mmap file '{$rlib}': {$error}")] MmapFile { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_parse_archive)] + #[diag("failed to parse archive '{$rlib}': {$error}")] ParseArchive { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_read_entry)] + #[diag("failed to read entry '{$rlib}': {$error}")] ReadEntry { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_archive_member)] + #[diag("failed to get data from archive member '{$rlib}': {$error}")] ArchiveMember { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_convert_name)] + #[diag("failed to convert name '{$rlib}': {$error}")] ConvertName { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_write_file)] + #[diag("failed to write file '{$rlib}': {$error}")] WriteFile { rlib: &'a Path, error: Box }, - #[diag(codegen_ssa_extract_bundled_libs_write_file)] + #[diag("failed to write file '{$rlib}': {$error}")] ExtractSection { rlib: &'a Path, error: Box }, } #[derive(Diagnostic)] -#[diag(codegen_ssa_read_file)] +#[diag("failed to read file: {$message}")] pub(crate) struct ReadFileError { pub message: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unsupported_link_self_contained)] +#[diag("option `-C link-self-contained` is not supported on this target")] pub(crate) struct UnsupportedLinkSelfContained; #[derive(Diagnostic)] -#[diag(codegen_ssa_archive_build_failure)] -// Public for rustc_codegen_llvm::back::archive -pub struct ArchiveBuildFailure { +#[diag("failed to build archive at `{$path}`: {$error}")] +pub(crate) struct ArchiveBuildFailure { pub path: PathBuf, pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_archive_kind)] -// Public for rustc_codegen_llvm::back::archive -pub struct UnknownArchiveKind<'a> { +#[diag("don't know how to build archive of type: {$kind}")] +pub(crate) struct UnknownArchiveKind<'a> { pub kind: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_multiple_main_functions)] -#[help] +#[diag("linking static libraries is not supported for BPF")] +pub(crate) struct BpfStaticlibNotSupported; + +#[derive(Diagnostic)] +#[diag("entry symbol `main` declared multiple times")] +#[help( + "did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point" +)] pub(crate) struct MultipleMainFunctions { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_shuffle_indices_evaluation)] +#[diag("could not evaluate shuffle_indices at compile time")] pub(crate) struct ShuffleIndicesEvaluation { #[primary_span] pub span: Span, @@ -758,7 +699,7 @@ pub(crate) struct ShuffleIndicesEvaluation { #[derive(Diagnostic)] pub enum InvalidMonomorphization<'tcx> { - #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`", code = E0511)] BasicIntegerType { #[primary_span] span: Span, @@ -766,7 +707,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_basic_integer_or_ptr_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected basic integer or pointer type, found `{$ty}`", code = E0511)] BasicIntegerOrPtrType { #[primary_span] span: Span, @@ -774,7 +715,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}`", code = E0511)] BasicFloatType { #[primary_span] span: Span, @@ -782,14 +723,14 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = E0511)] + #[diag("invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}`", code = E0511)] FloatToIntUnchecked { #[primary_span] span: Span, ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}`", code = E0511)] FloatingPointVector { #[primary_span] span: Span, @@ -798,7 +739,7 @@ pub enum InvalidMonomorphization<'tcx> { in_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type", code = E0511)] FloatingPointType { #[primary_span] span: Span, @@ -806,14 +747,14 @@ pub enum InvalidMonomorphization<'tcx> { in_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`", code = E0511)] UnrecognizedIntrinsic { #[primary_span] span: Span, name: Symbol, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}`", code = E0511)] SimdArgument { #[primary_span] span: Span, @@ -821,7 +762,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}`", code = E0511)] SimdInput { #[primary_span] span: Span, @@ -829,7 +770,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}`", code = E0511)] SimdFirst { #[primary_span] span: Span, @@ -837,7 +778,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`", code = E0511)] SimdSecond { #[primary_span] span: Span, @@ -845,7 +786,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`", code = E0511)] SimdThird { #[primary_span] span: Span, @@ -853,7 +794,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}`", code = E0511)] SimdReturn { #[primary_span] span: Span, @@ -861,7 +802,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`", code = E0511)] InvalidBitmask { #[primary_span] span: Span, @@ -871,7 +812,7 @@ pub enum InvalidMonomorphization<'tcx> { expected_bytes: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}", code = E0511)] ReturnLengthInputType { #[primary_span] span: Span, @@ -882,7 +823,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}", code = E0511)] SecondArgumentLength { #[primary_span] span: Span, @@ -893,7 +834,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}", code = E0511)] ThirdArgumentLength { #[primary_span] span: Span, @@ -904,7 +845,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`", code = E0511)] ReturnIntegerType { #[primary_span] span: Span, @@ -913,7 +854,7 @@ pub enum InvalidMonomorphization<'tcx> { out_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `{$ty}`", code = E0511)] SimdShuffle { #[primary_span] span: Span, @@ -921,7 +862,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_return_length, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}", code = E0511)] ReturnLength { #[primary_span] span: Span, @@ -931,7 +872,7 @@ pub enum InvalidMonomorphization<'tcx> { out_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_return_element, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`", code = E0511)] ReturnElement { #[primary_span] span: Span, @@ -942,7 +883,7 @@ pub enum InvalidMonomorphization<'tcx> { out_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_simd_index_out_of_bounds, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: SIMD index #{$arg_idx} is out of bounds (limit {$total_len})", code = E0511)] SimdIndexOutOfBounds { #[primary_span] span: Span, @@ -951,7 +892,7 @@ pub enum InvalidMonomorphization<'tcx> { total_len: u128, }, - #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`", code = E0511)] InsertedType { #[primary_span] span: Span, @@ -961,7 +902,7 @@ pub enum InvalidMonomorphization<'tcx> { out_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_return_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`", code = E0511)] ReturnType { #[primary_span] span: Span, @@ -971,7 +912,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}`", code = E0511)] ExpectedReturnType { #[primary_span] span: Span, @@ -980,7 +921,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`", code = E0511)] MismatchedLengths { #[primary_span] span: Span, @@ -989,7 +930,7 @@ pub enum InvalidMonomorphization<'tcx> { v_len: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_mask_wrong_element_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected mask element type to be an integer, found `{$ty}`", code = E0511)] MaskWrongElementType { #[primary_span] span: Span, @@ -997,7 +938,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`", code = E0511)] CannotReturn { #[primary_span] span: Span, @@ -1007,7 +948,7 @@ pub enum InvalidMonomorphization<'tcx> { expected_bytes: u64, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}`", code = E0511)] ExpectedElementType { #[primary_span] span: Span, @@ -1019,7 +960,7 @@ pub enum InvalidMonomorphization<'tcx> { mutability: ExpectedPointerMutability, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`", code = E0511)] UnsupportedSymbolOfSize { #[primary_span] span: Span, @@ -1031,7 +972,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}`", code = E0511)] UnsupportedSymbol { #[primary_span] span: Span, @@ -1042,7 +983,7 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_cast_wide_pointer, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: cannot cast wide pointer `{$ty}`", code = E0511)] CastWidePointer { #[primary_span] span: Span, @@ -1050,7 +991,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}`", code = E0511)] ExpectedPointer { #[primary_span] span: Span, @@ -1058,7 +999,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}`", code = E0511)] ExpectedUsize { #[primary_span] span: Span, @@ -1066,7 +1007,7 @@ pub enum InvalidMonomorphization<'tcx> { ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`", code = E0511)] UnsupportedCast { #[primary_span] span: Span, @@ -1077,7 +1018,7 @@ pub enum InvalidMonomorphization<'tcx> { out_elem: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`", code = E0511)] UnsupportedOperation { #[primary_span] span: Span, @@ -1086,7 +1027,7 @@ pub enum InvalidMonomorphization<'tcx> { in_elem: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = E0511)] + #[diag("invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type", code = E0511)] ExpectedVectorElementType { #[primary_span] span: Span, @@ -1094,6 +1035,14 @@ pub enum InvalidMonomorphization<'tcx> { expected_element: Ty<'tcx>, vector_type: Ty<'tcx>, }, + + #[diag("invalid monomorphization of `{$name}` intrinsic: expected non-scalable type, found scalable type `{$ty}`", code = E0511)] + NonScalableType { + #[primary_span] + span: Span, + name: Symbol, + ty: Ty<'tcx>, + }, } pub enum ExpectedPointerMutability { @@ -1111,17 +1060,17 @@ impl IntoDiagArg for ExpectedPointerMutability { } #[derive(Diagnostic)] -#[diag(codegen_ssa_target_feature_safe_trait)] +#[diag("`#[target_feature(..)]` cannot be applied to safe trait method")] pub(crate) struct TargetFeatureSafeTrait { #[primary_span] - #[label] + #[label("cannot be applied to safe trait method")] pub span: Span, - #[label(codegen_ssa_label_def)] + #[label("not an `unsafe` function")] pub def: Span, } #[derive(Diagnostic)] -#[diag(codegen_ssa_forbidden_target_feature_attr)] +#[diag("target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason}")] pub struct ForbiddenTargetFeatureAttr<'a> { #[primary_span] pub span: Span, @@ -1130,7 +1079,7 @@ pub struct ForbiddenTargetFeatureAttr<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_failed_to_get_layout)] +#[diag("failed to get layout for {$ty}: {$err}")] pub struct FailedToGetLayout<'tcx> { #[primary_span] pub span: Span, @@ -1139,7 +1088,11 @@ pub struct FailedToGetLayout<'tcx> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_dlltool_fail_import_library)] +#[diag( + "dlltool could not create import library with {$dlltool_path} {$dlltool_args}: +{$stdout} +{$stderr}" +)] pub(crate) struct DlltoolFailImportLibrary<'a> { pub dlltool_path: Cow<'a, str>, pub dlltool_args: String, @@ -1148,26 +1101,28 @@ pub(crate) struct DlltoolFailImportLibrary<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_writing_def_file)] +#[diag("error writing .DEF file: {$error}")] pub(crate) struct ErrorWritingDEFFile { pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_calling_dlltool)] +#[diag("error calling dlltool '{$dlltool_path}': {$error}")] pub(crate) struct ErrorCallingDllTool<'a> { pub dlltool_path: Cow<'a, str>, pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_creating_remark_dir)] +#[diag("failed to create remark directory: {$error}")] pub(crate) struct ErrorCreatingRemarkDir { pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(codegen_ssa_compiler_builtins_cannot_call)] +#[diag( + "`compiler_builtins` cannot call functions through upstream monomorphizations; encountered invalid call from `{$caller}` to `{$callee}`" +)] pub struct CompilerBuiltinsCannotCall { pub caller: String, pub callee: String, @@ -1176,23 +1131,23 @@ pub struct CompilerBuiltinsCannotCall { } #[derive(Diagnostic)] -#[diag(codegen_ssa_error_creating_import_library)] +#[diag("error creating import library for {$lib_name}: {$error}")] pub(crate) struct ErrorCreatingImportLibrary<'a> { pub lib_name: &'a str, pub error: String, } #[derive(Diagnostic)] -#[diag(codegen_ssa_aix_strip_not_used)] +#[diag("using host's `strip` binary to cross-compile to AIX which is not guaranteed to work")] pub(crate) struct AixStripNotUsed; #[derive(Diagnostic, Debug)] pub(crate) enum XcrunError { - #[diag(codegen_ssa_xcrun_failed_invoking)] + #[diag("invoking `{$command_formatted}` to find {$sdk_name}.sdk failed: {$error}")] FailedInvoking { sdk_name: &'static str, command_formatted: String, error: std::io::Error }, - #[diag(codegen_ssa_xcrun_unsuccessful)] - #[note] + #[diag("failed running `{$command_formatted}` to find {$sdk_name}.sdk")] + #[note("{$stdout}{$stderr}")] Unsuccessful { sdk_name: &'static str, command_formatted: String, @@ -1202,35 +1157,37 @@ pub(crate) enum XcrunError { } #[derive(Diagnostic, Debug)] -#[diag(codegen_ssa_xcrun_sdk_path_warning)] -#[note] +#[diag("output of `xcrun` while finding {$sdk_name}.sdk")] +#[note("{$stderr}")] pub(crate) struct XcrunSdkPathWarning { pub sdk_name: &'static str, pub stderr: String, } #[derive(LintDiagnostic)] -#[diag(codegen_ssa_aarch64_softfloat_neon)] +#[diag("enabling the `neon` target feature on the current target is unsound due to ABI issues")] pub(crate) struct Aarch64SoftfloatNeon; #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_ctarget_feature_prefix)] -#[note] +#[diag("unknown feature specified for `-Ctarget-feature`: `{$feature}`")] +#[note("features must begin with a `+` to enable or `-` to disable it")] pub(crate) struct UnknownCTargetFeaturePrefix<'a> { pub feature: &'a str, } #[derive(Subdiagnostic)] pub(crate) enum PossibleFeature<'a> { - #[help(codegen_ssa_possible_feature)] + #[help("you might have meant: `{$rust_feature}`")] Some { rust_feature: &'a str }, - #[help(codegen_ssa_consider_filing_feature_request)] + #[help("consider filing a feature request")] None, } #[derive(Diagnostic)] -#[diag(codegen_ssa_unknown_ctarget_feature)] -#[note] +#[diag("unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`")] +#[note( + "it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future" +)] pub(crate) struct UnknownCTargetFeature<'a> { pub feature: &'a str, #[subdiagnostic] @@ -1238,16 +1195,18 @@ pub(crate) struct UnknownCTargetFeature<'a> { } #[derive(Diagnostic)] -#[diag(codegen_ssa_unstable_ctarget_feature)] -#[note] +#[diag("unstable feature specified for `-Ctarget-feature`: `{$feature}`")] +#[note("this feature is not stably supported; its behavior can change in the future")] pub(crate) struct UnstableCTargetFeature<'a> { pub feature: &'a str, } #[derive(Diagnostic)] -#[diag(codegen_ssa_forbidden_ctarget_feature)] -#[note] -#[note(codegen_ssa_forbidden_ctarget_feature_issue)] +#[diag("target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}")] +#[note( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] +#[note("for more information, see issue #116344 ")] pub(crate) struct ForbiddenCTargetFeature<'a> { pub feature: &'a str, pub enabled: &'a str, @@ -1261,12 +1220,16 @@ pub struct TargetFeatureDisableOrEnable<'a> { } #[derive(Subdiagnostic)] -#[help(codegen_ssa_missing_features)] +#[help("add the missing features in a `target_feature` attribute")] pub struct MissingFeatures; impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::codegen_ssa_target_feature_disable_or_enable); + let mut diag = Diag::new( + dcx, + level, + msg!("the target features {$features} must all be either enabled or disabled together"), + ); if let Some(span) = self.span { diag.span(span); }; @@ -1279,29 +1242,29 @@ impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_ } #[derive(Diagnostic)] -#[diag(codegen_ssa_feature_not_valid)] +#[diag("the feature named `{$feature}` is not valid for this target")] pub(crate) struct FeatureNotValid<'a> { pub feature: &'a str, #[primary_span] - #[label] + #[label("`{$feature}` is not valid for this target")] pub span: Span, - #[help] + #[help("consider removing the leading `+` in the feature name")] pub plus_hint: bool, } #[derive(Diagnostic)] -#[diag(codegen_ssa_lto_disallowed)] +#[diag("lto can only be run for executables, cdylibs and static library outputs")] pub(crate) struct LtoDisallowed; #[derive(Diagnostic)] -#[diag(codegen_ssa_lto_dylib)] +#[diag("lto cannot be used for `dylib` crate type without `-Zdylib-lto`")] pub(crate) struct LtoDylib; #[derive(Diagnostic)] -#[diag(codegen_ssa_lto_proc_macro)] +#[diag("lto cannot be used for `proc-macro` crate type without `-Zdylib-lto`")] pub(crate) struct LtoProcMacro; #[derive(Diagnostic)] -#[diag(codegen_ssa_dynamic_linking_with_lto)] -#[note] +#[diag("cannot prefer dynamic linking when performing LTO")] +#[note("only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO")] pub(crate) struct DynamicLinkingWithLTO; diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index d7461c76ff03..cbfa12e21eba 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -1,7 +1,5 @@ // tidy-alphabetical-start -#![allow(rustc::diagnostic_outside_of_impl)] -#![allow(rustc::untranslatable_diagnostic)] -#![feature(assert_matches)] +#![cfg_attr(bootstrap, feature(assert_matches))] #![feature(box_patterns)] #![feature(file_buffered)] #![feature(if_let_guard)] @@ -26,7 +24,7 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir::CRATE_HIR_ID; use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind}; use rustc_hir::def_id::CrateNum; -use rustc_macros::{Decodable, Encodable, HashStable}; +use rustc_macros::{Decodable, Encodable}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::lint::LevelAndSource; @@ -57,8 +55,6 @@ pub mod size_of_val; pub mod target_features; pub mod traits; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub struct ModuleCodegen { /// The name of the module. When the crate may be saved between /// compilations, incremental compilation requires that name be @@ -177,7 +173,12 @@ bitflags::bitflags! { } } -#[derive(Clone, Debug, Encodable, Decodable, HashStable)] +// This is the same as `rustc_session::cstore::NativeLib`, except: +// - (important) the `foreign_module` field is missing, because it contains a `DefId`, which can't +// be encoded with `FileEncoder`. +// - (less important) the `verbatim` field is a `bool` rather than an `Option`, because here +// we can treat `false` and `absent` the same. +#[derive(Clone, Debug, Encodable, Decodable)] pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol, @@ -266,9 +267,9 @@ pub enum CodegenErrors { pub fn provide(providers: &mut Providers) { crate::back::symbol_export::provide(providers); - crate::base::provide(providers); - crate::target_features::provide(providers); - crate::codegen_attrs::provide(providers); + crate::base::provide(&mut providers.queries); + crate::target_features::provide(&mut providers.queries); + crate::codegen_attrs::provide(&mut providers.queries); providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![]; } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index cce33107e2c2..35de8b5e1486 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -9,12 +9,12 @@ use rustc_lint_defs::builtin::TAIL_CALL_TRACK_CALLER; use rustc_middle::mir::{self, AssertKind, InlineAsmMacro, SwitchTargets, UnwindTerminateReason}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; -use rustc_middle::ty::{self, Instance, Ty}; +use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::OptLevel; use rustc_span::Span; use rustc_span::source_map::Spanned; -use rustc_target::callconv::{ArgAbi, CastTarget, FnAbi, PassMode}; +use rustc_target::callconv::{ArgAbi, ArgAttributes, CastTarget, FnAbi, PassMode}; use tracing::{debug, info}; use super::operand::OperandRef; @@ -199,12 +199,12 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { // do an invoke, otherwise do a call. let fn_ty = bx.fn_decl_backend_type(fn_abi); - let fn_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { + let caller_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { Some(bx.tcx().codegen_instance_attrs(fx.instance.def)) } else { None }; - let fn_attrs = fn_attrs.as_deref(); + let caller_attrs = caller_attrs.as_deref(); if !fn_abi.can_unwind { unwind = mir::UnwindAction::Unreachable; @@ -233,7 +233,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { }; if kind == CallKind::Tail { - bx.tail_call(fn_ty, fn_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance); + bx.tail_call(fn_ty, caller_attrs, fn_abi, fn_ptr, llargs, self.funclet(fx), instance); return MergingSucc::False; } @@ -245,7 +245,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { }; let invokeret = bx.invoke( fn_ty, - fn_attrs, + caller_attrs, Some(fn_abi), fn_ptr, llargs, @@ -268,8 +268,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } MergingSucc::False } else { - let llret = - bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance); + let llret = bx.call( + fn_ty, + caller_attrs, + Some(fn_abi), + fn_ptr, + llargs, + self.funclet(fx), + instance, + ); if fx.mir[self.bb].is_cleanup { bx.apply_attrs_to_cleanup_callsite(llret); } @@ -1036,6 +1043,59 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("{} is not callable", callee.layout.ty), }; + if let Some(instance) = instance + && let Some(name) = bx.tcx().codegen_fn_attrs(instance.def_id()).symbol_name + && name.as_str().starts_with("llvm.") + // This is the only LLVM intrinsic we use that unwinds + // FIXME either add unwind support to codegen_llvm_intrinsic_call or replace usage of + // this intrinsic with something else + && name.as_str() != "llvm.wasm.throw" + { + assert!(!instance.args.has_infer()); + assert!(!instance.args.has_escaping_bound_vars()); + + let result_layout = + self.cx.layout_of(self.monomorphized_place_ty(destination.as_ref())); + + let return_dest = if result_layout.is_zst() { + ReturnDest::Nothing + } else if let Some(index) = destination.as_local() { + match self.locals[index] { + LocalRef::Place(dest) => ReturnDest::Store(dest), + LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), + LocalRef::PendingOperand => { + // Handle temporary places, specifically `Operand` ones, as + // they don't have `alloca`s. + ReturnDest::DirectOperand(index) + } + LocalRef::Operand(_) => bug!("place local already assigned to"), + } + } else { + ReturnDest::Store(self.codegen_place(bx, destination.as_ref())) + }; + + let args = + args.into_iter().map(|arg| self.codegen_operand(bx, &arg.node)).collect::>(); + + self.set_debug_loc(bx, source_info); + + let llret = + bx.codegen_llvm_intrinsic_call(instance, &args, self.mir[helper.bb].is_cleanup); + + if let Some(target) = target { + self.store_return( + bx, + return_dest, + &ArgAbi { layout: result_layout, mode: PassMode::Direct(ArgAttributes::new()) }, + llret, + ); + return helper.funclet_br(self, bx, target, mergeable_succ); + } else { + bx.unreachable(); + return MergingSucc::False; + } + } + // FIXME(eddyb) avoid computing this if possible, when `instance` is // available - right now `sig` is only needed for getting the `abi` // and figuring out how many extra args were passed to a C-variadic `fn`. diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 11b6ab3cdf1a..abdac4c7c372 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -77,22 +77,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .flatten() .map(|val| { // A SIMD type has a single field, which is an array. - let fields = val.unwrap_branch(); + let fields = val.to_branch(); assert_eq!(fields.len(), 1); - let array = fields[0].unwrap_branch(); + let array = fields[0].to_branch(); // Iterate over the array elements to obtain the values in the vector. let values: Vec<_> = array .iter() .map(|field| { - if let Some(prim) = field.try_to_scalar() { - let layout = bx.layout_of(field_ty); - let BackendRepr::Scalar(scalar) = layout.backend_repr else { - bug!("from_const: invalid ByVal layout: {:#?}", layout); - }; - bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) - } else { + let Some(prim) = field.try_to_scalar() else { bug!("field is not a scalar {:?}", field) - } + }; + let layout = bx.layout_of(field_ty); + let BackendRepr::Scalar(scalar) = layout.backend_repr else { + bug!("from_const: invalid ByVal layout: {:#?}", layout); + }; + bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout)) }) .collect(); bx.const_vector(&values) diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 0c9acf087f9f..2f93f688c316 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -408,6 +408,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { return; } + // Don't spill `` for `N != 16`: + // + // SVE predicates are only one bit for each byte in an SVE vector (which makes + // sense, the predicate only needs to keep track of whether a lane is + // enabled/disabled). i.e. a `` vector has a `` + // predicate type. `` corresponds to two bytes of storage, + // multiplied by the `vscale`, with one bit for each of the sixteen lanes. + // + // For a vector with fewer elements, such as `svint32_t`/``, + // while only a `` predicate type would be strictly necessary, + // relevant intrinsics still take a `svbool_t`/`` - this is + // because a `` is only half of a byte (for `vscale=1`), and with + // memory being byte-addressable, it's unclear how to store that. + // + // Due to this, LLVM ultimately decided not to support stores of `` + // for `N != 16`. As for `vscale=1` and `N` fewer than sixteen, partial bytes would + // need to be stored (except for `N=8`, but that also isn't supported). `N` can + // never be greater than sixteen as that ends up larger than the 128-bit increment + // size. + // + // Internally, with an intrinsic operating on a `svint32_t`/`` + // (for example), the intrinsic takes the `svbool_t`/`` predicate + // and casts it to a `svbool4_t`/``. Therefore, it's important that + // the `` never spills because that'll cause errors during + // instruction selection. Spilling to the stack to create debuginfo for these + // intermediate values must be avoided and doing so won't affect the + // debugging experience anyway. + if operand.layout.ty.is_scalable_vector() + && bx.sess().target.arch == rustc_target::spec::Arch::AArch64 + { + let (count, element_ty) = + operand.layout.ty.scalable_vector_element_count_and_type(bx.tcx()); + // i.e. `` when `N != 16` + if element_ty.is_bool() && count != 16 { + return; + } + } + Self::spill_operand_to_stack(*operand, name, bx) } diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index aeb740118234..f5ee9406f4bf 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -102,7 +102,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let parse_atomic_ordering = |ord: ty::Value<'tcx>| { - let discr = ord.valtree.unwrap_branch()[0].unwrap_leaf(); + let discr = ord.to_branch()[0].to_leaf(); discr.to_atomic_ordering() }; @@ -112,6 +112,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | sym::unreachable | sym::cold_path | sym::breakpoint + | sym::amdgpu_dispatch_ptr | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid | sym::assert_inhabited diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 4a47799b2bdc..f12410c65d98 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -1,5 +1,6 @@ use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind}; use rustc_hir::attrs::{InstructionSetAttr, Linkage}; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::mir::mono::{MonoItemData, Visibility}; use rustc_middle::mir::{InlineAsmOperand, START_BLOCK}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; @@ -128,6 +129,15 @@ fn prefix_and_suffix<'tcx>( let is_arm = tcx.sess.target.arch == Arch::Arm; let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode); + // If we're compiling the compiler-builtins crate, e.g., the equivalent of + // compiler-rt, then we want to implicitly compile everything with hidden + // visibility as we're going to link this object all over the place but + // don't want the symbols to get exported. For naked asm we set the visibility here. + let mut visibility = item_data.visibility; + if item_data.linkage != Linkage::Internal && tcx.is_compiler_builtins(LOCAL_CRATE) { + visibility = Visibility::Hidden; + } + let attrs = tcx.codegen_instance_attrs(instance.def); let link_section = attrs.link_section.map(|symbol| symbol.as_str().to_string()); @@ -181,7 +191,8 @@ fn prefix_and_suffix<'tcx>( } } Linkage::Internal => { - // write nothing + // LTO can fail when internal linkage is used. + emit_fatal("naked functions may not have internal linkage") } Linkage::Common => emit_fatal("Functions may not have common linkage"), Linkage::AvailableExternally => { @@ -216,7 +227,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap(); writeln!(begin, ".balign {align_bytes}").unwrap(); write_linkage(&mut begin).unwrap(); - match item_data.visibility { + match visibility { Visibility::Default => {} Visibility::Protected => writeln!(begin, ".protected {asm_name}").unwrap(), Visibility::Hidden => writeln!(begin, ".hidden {asm_name}").unwrap(), @@ -242,7 +253,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap(); writeln!(begin, ".balign {align_bytes}").unwrap(); write_linkage(&mut begin).unwrap(); - match item_data.visibility { + match visibility { Visibility::Default | Visibility::Protected => {} Visibility::Hidden => writeln!(begin, ".private_extern {asm_name}").unwrap(), } @@ -279,7 +290,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, ".section {section},\"\",@").unwrap(); // wasm functions cannot be aligned, so skip write_linkage(&mut begin).unwrap(); - if let Visibility::Hidden = item_data.visibility { + if let Visibility::Hidden = visibility { writeln!(begin, ".hidden {asm_name}").unwrap(); } writeln!(begin, ".type {asm_name}, @function").unwrap(); @@ -312,7 +323,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, ".align {}", align_bytes).unwrap(); write_linkage(&mut begin).unwrap(); - if let Visibility::Hidden = item_data.visibility { + if let Visibility::Hidden = visibility { // FIXME apparently `.globl {asm_name}, hidden` is valid // but due to limitations with `.weak` (see above) we can't really use that in general yet } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 5a139702f81d..50ca676b5d05 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -405,7 +405,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { imm } } - BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { .. } => bug!(), + BackendRepr::ScalarPair(_, _) + | BackendRepr::Memory { .. } + | BackendRepr::ScalableVector { .. } => bug!(), }) }; @@ -692,7 +694,9 @@ impl<'a, 'tcx, V: CodegenObject> OperandRefBuilder<'tcx, V> { BackendRepr::ScalarPair(a, b) => { OperandValueBuilder::Pair(Either::Right(a), Either::Right(b)) } - BackendRepr::SimdVector { .. } => OperandValueBuilder::Vector(Either::Right(())), + BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { + OperandValueBuilder::Vector(Either::Right(())) + } BackendRepr::Memory { .. } => { bug!("Cannot use non-ZST Memory-ABI type in operand builder: {layout:?}"); } @@ -1052,6 +1056,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { move_annotation, ..self.codegen_consume(bx, place.as_ref()) } } + mir::Operand::RuntimeChecks(checks) => { + let layout = bx.layout_of(bx.tcx().types.bool); + let BackendRepr::Scalar(scalar) = layout.backend_repr else { + bug!("from_const: invalid ByVal layout: {:#?}", layout); + }; + let x = Scalar::from_bool(checks.value(bx.tcx().sess)); + let llval = bx.scalar_to_backend(x, scalar, bx.immediate_backend_type(layout)); + let val = OperandValue::Immediate(llval); + OperandRef { val, layout, move_annotation: None } + } + mir::Operand::Constant(ref constant) => { let constant_ty = self.monomorphize(constant.ty()); // Most SIMD vector constants should be passed as immediates. @@ -1059,8 +1074,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if constant_ty.is_simd() { // However, some SIMD types do not actually use the vector ABI // (in particular, packed SIMD types do not). Ensure we exclude those. + // + // We also have to exclude vectors of pointers because `immediate_const_vector` + // does not work for those. let layout = bx.layout_of(constant_ty); - if let BackendRepr::SimdVector { .. } = layout.backend_repr { + let (_, element_ty) = constant_ty.simd_size_and_type(bx.tcx()); + if let BackendRepr::SimdVector { .. } = layout.backend_repr + && element_ty.is_numeric() + { let (llval, ty) = self.immediate_const_vector(bx, constant); return OperandRef { val: OperandValue::Immediate(llval), diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 50f56f913a51..d62e622b6fed 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -109,7 +109,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx: &mut Bx, layout: TyAndLayout<'tcx>, ) -> Self { - Self::alloca_size(bx, layout.size, layout) + if layout.is_runtime_sized() { + Self::alloca_runtime_sized(bx, layout) + } else { + Self::alloca_size(bx, layout.size, layout) + } } pub fn alloca_size>( @@ -146,6 +150,18 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bug!("unexpected layout `{:#?}` in PlaceRef::len", self.layout) } } + + fn alloca_runtime_sized>( + bx: &mut Bx, + layout: TyAndLayout<'tcx>, + ) -> Self { + let (element_count, ty) = layout.ty.scalable_vector_element_count_and_type(bx.tcx()); + PlaceValue::new_sized( + bx.scalable_alloca(element_count as u64, layout.align.abi, ty), + layout.align.abi, + ) + .with_type(layout) + } } impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index de626d04e785..2cb96c4ec0f5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -619,21 +619,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - mir::Rvalue::NullaryOp(ref null_op) => { - let val = match null_op { - mir::NullOp::RuntimeChecks(kind) => { - let val = kind.value(bx.tcx().sess); - bx.cx().const_bool(val) - } - }; - let tcx = self.cx.tcx(); - OperandRef { - val: OperandValue::Immediate(val), - layout: self.cx.layout_of(null_op.ty(tcx)), - move_annotation: None, - } - } - mir::Rvalue::ThreadLocalRef(def_id) => { assert!(bx.cx().tcx().is_static(def_id)); let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id, bx.typing_env())); @@ -725,7 +710,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: operand.val, layout, move_annotation: None } } mir::Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), - mir::Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), } } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 85bff4540814..7ebff77710fb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -37,10 +37,6 @@ pub trait BackendTypes { } pub trait CodegenBackend { - /// Locale resources for diagnostic messages - a string the content of the Fluent resource. - /// Called before `init` so that all other functions are able to emit translatable diagnostics. - fn locale_resource(&self) -> &'static str; - fn name(&self) -> &'static str; fn init(&self, _sess: &Session) {} @@ -67,7 +63,7 @@ pub trait CodegenBackend { CrateType::Executable, CrateType::Dylib, CrateType::Rlib, - CrateType::Staticlib, + CrateType::StaticLib, CrateType::Cdylib, CrateType::ProcMacro, CrateType::Sdylib, @@ -78,6 +74,25 @@ pub trait CodegenBackend { fn print_version(&self) {} + /// Returns a list of all intrinsics that this backend definitely + /// replaces, which means their fallback bodies do not need to be monomorphized. + fn replaced_intrinsics(&self) -> Vec { + vec![] + } + + /// Is ThinLTO supported by this backend? + fn thin_lto_supported(&self) -> bool { + true + } + + /// Value printed by `--print=backend-has-zstd`. + /// + /// Used by compiletest to determine whether tests involving zstd compression + /// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped. + fn has_zstd(&self) -> bool { + false + } + /// The metadata loader used to load rlib and dylib metadata. /// /// Alternative codegen backends may want to use different rlib or dylib formats than the diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index f57f9108f744..3486bd140ece 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -1,7 +1,7 @@ -use std::assert_matches::assert_matches; use std::ops::Deref; use rustc_abi::{Align, Scalar, Size, WrappingRange}; +use rustc_data_structures::assert_matches; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; @@ -235,6 +235,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; fn alloca(&mut self, size: Size, align: Align) -> Self::Value; + fn scalable_alloca(&mut self, elt: u64, align: Align, element_ty: Ty<'_>) -> Self::Value; fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value; @@ -599,10 +600,13 @@ pub trait BuilderMethods<'a, 'tcx>: /// /// ## Arguments /// - /// The `fn_attrs`, `fn_abi`, and `instance` arguments are Options because they are advisory. - /// They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI per se. - /// Any ABI-related transformations should be handled by different, earlier stages of codegen. - /// For instance, in the caller of `BuilderMethods::call`. + /// `caller_attrs` are the attributes of the surrounding caller; they have nothing to do with + /// the callee. + /// + /// The `caller_attrs`, `fn_abi`, and `callee_instance` arguments are Options because they are + /// advisory. They relate to optional codegen enhancements like LLVM CFI, and do not affect ABI + /// per se. Any ABI-related transformations should be handled by different, earlier stages of + /// codegen. For instance, in the caller of `BuilderMethods::call`. /// /// This means that a codegen backend which disregards `fn_attrs`, `fn_abi`, and `instance` /// should still do correct codegen, and code should not be miscompiled if they are omitted. @@ -619,23 +623,23 @@ pub trait BuilderMethods<'a, 'tcx>: fn call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, fn_val: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ) -> Self::Value; fn tail_call( &mut self, llty: Self::Type, - fn_attrs: Option<&CodegenFnAttrs>, + caller_attrs: Option<&CodegenFnAttrs>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, - instance: Option>, + callee_instance: Option>, ); fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index c5ecf43046c7..04183c2801e7 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -25,6 +25,13 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { span: Span, ) -> Result<(), ty::Instance<'tcx>>; + fn codegen_llvm_intrinsic_call( + &mut self, + instance: ty::Instance<'tcx>, + args: &[OperandRef<'tcx, Self::Value>], + is_cleanup: bool, + ) -> Self::Value; + fn abort(&mut self); fn assume(&mut self, val: Self::Value); fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value; @@ -36,10 +43,10 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { vtable_byte_offset: u64, typeid: Self::Metadata, ) -> Self::Value; - /// Trait method used to inject `va_start` on the "spoofed" `VaListImpl` in + /// Trait method used to inject `va_start` on the "spoofed" `VaList` in /// Rust defined C-variadic functions. fn va_start(&mut self, val: Self::Value) -> Self::Value; - /// Trait method used to inject `va_end` on the "spoofed" `VaListImpl` before + /// Trait method used to inject `va_end` on the "spoofed" `VaList` before /// Rust defined C-variadic functions return. fn va_end(&mut self, val: Self::Value) -> Self::Value; } diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 1ac1d7ef2e2e..5f5d0ac5d9fc 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -1,16 +1,18 @@ use std::path::PathBuf; +use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::DiagCtxtHandle; use rustc_middle::dep_graph::WorkProduct; use crate::back::lto::{SerializedModule, ThinModule}; -use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig}; +use crate::back::write::{ + CodegenContext, FatLtoInput, ModuleConfig, SharedEmitter, TargetMachineFactoryFn, +}; use crate::{CompiledModule, ModuleCodegen}; pub trait WriteBackendMethods: Clone + 'static { type Module: Send + Sync; type TargetMachine; - type TargetMachineError; type ModuleBuffer: ModuleBufferMethods; type ThinData: Send + Sync; type ThinBuffer: ThinBufferMethods; @@ -18,7 +20,10 @@ pub trait WriteBackendMethods: Clone + 'static { /// Performs fat LTO by merging all modules into a single one, running autodiff /// if necessary and running any further optimizations fn run_and_optimize_fat_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, + tm_factory: TargetMachineFactoryFn, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec>, @@ -27,7 +32,9 @@ pub trait WriteBackendMethods: Clone + 'static { /// lists, one of the modules that need optimization and another for modules that /// can simply be copied over from the incr. comp. cache. fn run_thin_lto( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + dcx: DiagCtxtHandle<'_>, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], modules: Vec<(String, Self::ThinBuffer)>, @@ -36,17 +43,23 @@ pub trait WriteBackendMethods: Clone + 'static { fn print_pass_timings(&self); fn print_statistics(&self); fn optimize( - cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: &mut ModuleCodegen, config: &ModuleConfig, ); fn optimize_thin( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, + tm_factory: TargetMachineFactoryFn, thin: ThinModule, ) -> ModuleCodegen; fn codegen( - cgcx: &CodegenContext, + cgcx: &CodegenContext, + prof: &SelfProfilerRef, + shared_emitter: &SharedEmitter, module: ModuleCodegen, config: &ModuleConfig, ) -> CompiledModule; diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 51dcee8d8822..aa013cf61f48 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -11,7 +11,6 @@ rustc_apfloat = "0.2.0" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl deleted file mode 100644 index 38ab46a7bb5b..000000000000 --- a/compiler/rustc_const_eval/messages.ftl +++ /dev/null @@ -1,507 +0,0 @@ -const_eval_address_space_full = - there are no more free addresses in the address space - -const_eval_alignment_check_failed = - {$msg -> - [AccessedPtr] accessing memory - *[other] accessing memory based on pointer - } with alignment {$has}, but alignment {$required} is required - -const_eval_already_reported = - an error has already been reported elsewhere (this should not usually be printed) -const_eval_assume_false = - `assume` called with `false` - -const_eval_bad_pointer_op = {$operation -> - [MemoryAccess] memory access failed - [InboundsPointerArithmetic] in-bounds pointer arithmetic failed - *[Dereferenceable] pointer not dereferenceable -} -const_eval_bad_pointer_op_attempting = {const_eval_bad_pointer_op}: {$operation -> - [MemoryAccess] attempting to access {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> - [1] 1 byte - *[x] {$inbounds_size} bytes - } - *[Dereferenceable] pointer must {$inbounds_size -> - [0] point to some allocation - [1] be dereferenceable for 1 byte - *[x] be dereferenceable for {$inbounds_size} bytes - } - } - -const_eval_bounds_check_failed = - indexing out of bounds: the len is {$len} but the index is {$index} -const_eval_call_nonzero_intrinsic = - `{$name}` called on 0 - -const_eval_closure_call = - closures need an RFC before allowed to be called in {const_eval_const_context}s -const_eval_closure_fndef_not_const = - function defined here, but it is not `const` - -const_eval_consider_dereferencing = - consider dereferencing here - -const_eval_const_accesses_mut_global = - constant accesses mutable global memory - -const_eval_const_context = {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -} - -const_eval_const_heap_ptr_in_final = encountered `const_allocate` pointer in final value that was not made global - .note = use `const_make_global` to turn allocated pointers into immutable globals before returning - -const_eval_const_make_global_ptr_already_made_global = attempting to call `const_make_global` twice on the same allocation {$alloc} - -const_eval_const_make_global_ptr_is_non_heap = pointer passed to `const_make_global` does not point to a heap allocation: {$ptr} - -const_eval_const_make_global_with_dangling_ptr = pointer passed to `const_make_global` is dangling: {$ptr} - -const_eval_const_make_global_with_offset = making {$ptr} global which does not point to the beginning of an object - -const_eval_copy_nonoverlapping_overlapping = - `copy_nonoverlapping` called on overlapping ranges - -const_eval_dangling_int_pointer = - {const_eval_bad_pointer_op_attempting}, but got {$pointer} which is a dangling pointer (it has no provenance) -const_eval_dangling_null_pointer = - {const_eval_bad_pointer_op_attempting}, but got null pointer - -const_eval_dangling_ptr_in_final = encountered dangling pointer in final value of {const_eval_intern_kind} -const_eval_dead_local = - accessing a dead local variable -const_eval_dealloc_immutable = - deallocating immutable allocation {$alloc} - -const_eval_dealloc_incorrect_layout = - incorrect layout on deallocation: {$alloc} has size {$size} and alignment {$align}, but gave size {$size_found} and alignment {$align_found} - -const_eval_dealloc_kind_mismatch = - deallocating {$alloc}, which is {$alloc_kind} memory, using {$kind} deallocation operation - -const_eval_deref_function_pointer = - accessing {$allocation} which contains a function -const_eval_deref_typeid_pointer = - accessing {$allocation} which contains a `TypeId` -const_eval_deref_vtable_pointer = - accessing {$allocation} which contains a vtable -const_eval_division_by_zero = - dividing by zero -const_eval_division_overflow = - overflow in signed division (dividing MIN by -1) - -const_eval_dyn_call_not_a_method = - `dyn` call trying to call something that is not a method - -const_eval_error = evaluation of `{$instance}` failed {$num_frames -> - [0] here - *[other] inside this call -} - -const_eval_exact_div_has_remainder = - exact_div: {$a} cannot be divided by {$b} without remainder - -const_eval_extern_static = - cannot access extern static `{$did}` -const_eval_extern_type_field = `extern type` field does not have a known offset - -const_eval_fn_ptr_call = - function pointers need an RFC before allowed to be called in {const_eval_const_context}s -const_eval_frame_note = {$times -> - [0] {const_eval_frame_note_inner} - *[other] [... {$times} additional calls {const_eval_frame_note_inner} ...] -} - -const_eval_frame_note_inner = inside {$where_ -> - [closure] closure - [instance] `{$instance}` - *[other] {""} -} - -const_eval_frame_note_last = the failure occurred here - -const_eval_incompatible_arg_types = - calling a function whose parameter #{$arg_idx} has type {$callee_ty} passing argument of type {$caller_ty} - -const_eval_incompatible_calling_conventions = - calling a function with calling convention "{$callee_conv}" using calling convention "{$caller_conv}" - -const_eval_incompatible_return_types = - calling a function with return type {$callee_ty} passing return place of type {$caller_ty} - -const_eval_interior_mutable_borrow_escaping = - interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed - .label = this borrow of an interior mutable value refers to such a temporary - .note = Temporaries in constants and statics can have their lifetime extended until the end of the program - .note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable - .help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` - -const_eval_intern_kind = {$kind -> - [static] static - [static_mut] mutable static - [const] constant - [promoted] promoted - *[other] {""} -} - -const_eval_interrupted = compilation was interrupted - -const_eval_invalid_align_details = - invalid align passed to `{$name}`: {$align} is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {""} - } - -const_eval_invalid_bool = - interpreting an invalid 8-bit value as a bool: 0x{$value} -const_eval_invalid_char = - interpreting an invalid 32-bit value as a char: 0x{$value} -const_eval_invalid_dealloc = - deallocating {$alloc_id}, which is {$kind -> - [fn] a function - [vtable] a vtable - [static_mem] static memory - *[other] {""} - } - -const_eval_invalid_function_pointer = - using {$pointer} as function pointer but it does not point to a function -const_eval_invalid_meta = - invalid metadata in wide pointer: total size is bigger than largest supported object -const_eval_invalid_meta_slice = - invalid metadata in wide pointer: slice is bigger than largest supported object - -const_eval_invalid_niched_enum_variant_written = - trying to set discriminant of a {$ty} to the niched variant, but the value does not match - -const_eval_invalid_str = - this string is not valid UTF-8: {$err} -const_eval_invalid_tag = - enum value has invalid tag: {$tag} -const_eval_invalid_transmute = - transmuting from {$src_bytes}-byte type to {$dest_bytes}-byte type: `{$src}` -> `{$dest}` - -const_eval_invalid_uninit_bytes = - reading memory at {$alloc}{$access}, but memory is uninitialized at {$uninit}, and this operation requires initialized memory -const_eval_invalid_uninit_bytes_unknown = - using uninitialized data, but this operation requires initialized memory - -const_eval_invalid_vtable_pointer = - using {$pointer} as vtable pointer but it does not point to a vtable - -const_eval_invalid_vtable_trait = - using vtable for `{$vtable_dyn_type}` but `{$expected_dyn_type}` was expected - -const_eval_lazy_lock = - consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - -const_eval_live_drop = - destructor of `{$dropped_ty}` cannot be evaluated at compile-time - .label = the destructor for this type cannot be evaluated in {const_eval_const_context}s - .dropped_at_label = value is dropped here - -const_eval_long_running = - constant evaluation is taking a long time - .note = this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. - .label = the const evaluator is currently interpreting this expression - .help = the constant being evaluated - -const_eval_memory_exhausted = - tried to allocate more memory than available to compiler - -const_eval_modified_global = - modifying a static's initial value from another static's initializer - -const_eval_mutable_borrow_escaping = - mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed - .label = this mutable borrow refers to such a temporary - .note = Temporaries in constants and statics can have their lifetime extended until the end of the program - .note2 = To avoid accidentally creating global mutable state, such temporaries must be immutable - .help = If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` - -const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind} - -const_eval_nested_static_in_thread_local = #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead - -const_eval_non_const_await = - cannot convert `{$ty}` into a future in {const_eval_const_context}s - -const_eval_non_const_closure = - cannot call {$non_or_conditionally}-const closure in {const_eval_const_context}s - -const_eval_non_const_deref_coercion = - cannot perform {$non_or_conditionally}-const deref coercion on `{$ty}` in {const_eval_const_context}s - .note = attempting to deref into `{$target_ty}` - .target_note = deref defined here - -const_eval_non_const_fmt_macro_call = - cannot call {$non_or_conditionally}-const formatting macro in {const_eval_const_context}s - -const_eval_non_const_fn_call = - cannot call {$non_or_conditionally}-const {$def_descr} `{$def_path_str}` in {const_eval_const_context}s - -const_eval_non_const_for_loop_into_iter = - cannot use `for` loop on `{$ty}` in {const_eval_const_context}s - -const_eval_non_const_impl = - impl defined here, but it is not `const` - -const_eval_non_const_intrinsic = - cannot call non-const intrinsic `{$name}` in {const_eval_const_context}s - -const_eval_non_const_match_eq = cannot match on `{$ty}` in {const_eval_const_context}s - .note = `{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es - -const_eval_non_const_operator = - cannot call {$non_or_conditionally}-const operator in {const_eval_const_context}s - -const_eval_non_const_question_branch = - `?` is not allowed on `{$ty}` in {const_eval_const_context}s -const_eval_non_const_question_from_residual = - `?` is not allowed on `{$ty}` in {const_eval_const_context}s - -const_eval_non_const_try_block_from_output = - `try` block cannot convert `{$ty}` to the result in {const_eval_const_context}s - -const_eval_not_enough_caller_args = - calling a function with fewer arguments than it requires - -const_eval_offset_from_different_allocations = - `{$name}` called on two different pointers that are not both derived from the same allocation -const_eval_offset_from_out_of_bounds = - `{$name}` called on two different pointers where the memory range between them is not in-bounds of an allocation -const_eval_offset_from_overflow = - `{$name}` called when first pointer is too far ahead of second -const_eval_offset_from_underflow = - `{$name}` called when first pointer is too far before second -const_eval_offset_from_unsigned_overflow = - `ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr -> - [true] address - *[false] offset - } than second: {$a_offset} < {$b_offset} - -const_eval_overflow_arith = - arithmetic overflow in `{$intrinsic}` -const_eval_overflow_shift = - overflowing shift by {$shift_amount} in `{$intrinsic}` - -const_eval_panic = evaluation panicked: {$msg} - -const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str` - -const_eval_partial_pointer_in_final = encountered partial pointer in final value of {const_eval_intern_kind} - .note = while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value - -const_eval_partial_pointer_read = - unable to read parts of a pointer from memory at {$ptr} -const_eval_pointer_arithmetic_overflow = - overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize` - -const_eval_pointer_out_of_bounds = - {const_eval_bad_pointer_op_attempting}, but got {$pointer} which {$ptr_offset_is_neg -> - [true] points to before the beginning of the allocation - *[false] {$inbounds_size_is_neg -> - [false] {$alloc_size_minus_ptr_offset -> - [0] is at or beyond the end of the allocation of size {$alloc_size -> - [1] 1 byte - *[x] {$alloc_size} bytes - } - [1] is only 1 byte from the end of the allocation - *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation - } - *[true] {$ptr_offset_abs -> - [0] is at the beginning of the allocation - *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation - } - } - } - -const_eval_pointer_use_after_free = - {const_eval_bad_pointer_op}: {$alloc_id} has been freed, so this pointer is dangling -const_eval_ptr_as_bytes_1 = - this code performed an operation that depends on the underlying bytes representing a pointer -const_eval_ptr_as_bytes_2 = - the absolute address of a pointer is not known at compile-time, so such operations are not supported - -const_eval_range = in the range {$lo}..={$hi} -const_eval_range_lower = greater or equal to {$lo} -const_eval_range_singular = equal to {$lo} -const_eval_range_upper = less or equal to {$hi} -const_eval_range_wrapping = less or equal to {$hi}, or greater or equal to {$lo} -const_eval_raw_bytes = the raw bytes of the constant (size: {$size}, align: {$align}) {"{"}{$bytes}{"}"} - -const_eval_raw_ptr_comparison = - pointers cannot be reliably compared during const eval - .note = see issue #53020 for more information - -const_eval_raw_ptr_to_int = - pointers cannot be cast to integers during const eval - .note = at compile-time, pointers do not have an integer value - .note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior - -const_eval_read_pointer_as_int = - unable to turn pointer into integer -const_eval_realloc_or_alloc_with_offset = - {$kind -> - [dealloc] deallocating - [realloc] reallocating - *[other] {""} - } {$ptr} which does not point to the beginning of an object - -const_eval_recursive_static = encountered static that tried to access itself during initialization - -const_eval_remainder_by_zero = - calculating the remainder with a divisor of zero -const_eval_remainder_overflow = - overflow in signed remainder (dividing MIN by -1) -const_eval_scalar_size_mismatch = - scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead -const_eval_size_overflow = - overflow computing total size of `{$name}` - -const_eval_stack_frame_limit_reached = - reached the configured maximum number of stack frames - -const_eval_thread_local_access = - thread-local statics cannot be accessed at compile-time - -const_eval_thread_local_static = - cannot access thread local static `{$did}` -const_eval_too_generic = - encountered overly generic constant -const_eval_too_many_caller_args = - calling a function with more arguments than it expected - -const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {const_eval_const_context}s - -const_eval_unallowed_heap_allocations = - allocations are not allowed in {const_eval_const_context}s - .label = allocation not allowed in {const_eval_const_context}s - .teach_note = - The runtime heap is not yet available at compile-time, so no runtime heap allocations can be created. - -const_eval_unallowed_inline_asm = - inline assembly is not allowed in {const_eval_const_context}s - -const_eval_unallowed_op_in_const_context = - {$msg} - -const_eval_uninhabited_enum_variant_read = - read discriminant of an uninhabited enum variant -const_eval_uninhabited_enum_variant_written = - writing discriminant of an uninhabited enum variant - -const_eval_unmarked_const_item_exposed = `{$def_path}` cannot be (indirectly) exposed to stable - .help = either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]` -const_eval_unmarked_intrinsic_exposed = intrinsic `{$def_path}` cannot be (indirectly) exposed to stable - .help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_intrinsic_const_stable_indirect]` (but this requires team approval) - -const_eval_unreachable = entering unreachable code -const_eval_unreachable_unwind = - unwinding past a stack frame that does not allow unwinding - -const_eval_unsized_local = unsized locals are not supported -const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn -const_eval_unstable_const_trait = `{$def_path}` is not yet stable as a const trait -const_eval_unstable_in_stable_exposed = - const function that might be (indirectly) exposed to stable cannot use `#[feature({$gate})]` - .is_function_call = mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unstable features - .unstable_sugg = if the {$is_function_call2 -> - [true] caller - *[false] function - } is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]` - -const_eval_unstable_intrinsic = `{$name}` is not yet stable as a const intrinsic -const_eval_unstable_intrinsic_suggestion = add `#![feature({$feature})]` to the crate attributes to enable - -const_eval_unterminated_c_string = - reading a null-terminated string starting at {$pointer} with no null found before end of allocation - -const_eval_unwind_past_top = - unwinding past the topmost frame of the stack - -## The `front_matter`s here refer to either `const_eval_front_matter_invalid_value` or `const_eval_front_matter_invalid_value_with_path`. -## (We'd love to sort this differently to make that more clear but tidy won't let us...) -const_eval_validation_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty} - -const_eval_validation_dangling_box_no_provenance = {$front_matter}: encountered a dangling box ({$pointer} has no provenance) -const_eval_validation_dangling_box_out_of_bounds = {$front_matter}: encountered a dangling box (going beyond the bounds of its allocation) -const_eval_validation_dangling_box_use_after_free = {$front_matter}: encountered a dangling box (use-after-free) -const_eval_validation_dangling_ref_no_provenance = {$front_matter}: encountered a dangling reference ({$pointer} has no provenance) -const_eval_validation_dangling_ref_out_of_bounds = {$front_matter}: encountered a dangling reference (going beyond the bounds of its allocation) -const_eval_validation_dangling_ref_use_after_free = {$front_matter}: encountered a dangling reference (use-after-free) - -const_eval_validation_expected_bool = expected a boolean -const_eval_validation_expected_box = expected a box -const_eval_validation_expected_char = expected a unicode scalar value -const_eval_validation_expected_enum_tag = expected a valid enum tag -const_eval_validation_expected_float = expected a floating point number -const_eval_validation_expected_fn_ptr = expected a function pointer -const_eval_validation_expected_init_scalar = expected initialized scalar value -const_eval_validation_expected_int = expected an integer -const_eval_validation_expected_raw_ptr = expected a raw pointer -const_eval_validation_expected_ref = expected a reference -const_eval_validation_expected_str = expected a string - -const_eval_validation_failure = - it is undefined behavior to use this value - -const_eval_validation_failure_note = - the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - -const_eval_validation_front_matter_invalid_value = constructing invalid value -const_eval_validation_front_matter_invalid_value_with_path = constructing invalid value at {$path} - -const_eval_validation_invalid_bool = {$front_matter}: encountered {$value}, but expected a boolean -const_eval_validation_invalid_box_meta = {$front_matter}: encountered invalid box metadata: total size is bigger than largest supported object -const_eval_validation_invalid_box_slice_meta = {$front_matter}: encountered invalid box metadata: slice is bigger than largest supported object -const_eval_validation_invalid_char = {$front_matter}: encountered {$value}, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`) - -const_eval_validation_invalid_enum_tag = {$front_matter}: encountered {$value}, but expected a valid enum tag -const_eval_validation_invalid_fn_ptr = {$front_matter}: encountered {$value}, but expected a function pointer -const_eval_validation_invalid_ref_meta = {$front_matter}: encountered invalid reference metadata: total size is bigger than largest supported object -const_eval_validation_invalid_ref_slice_meta = {$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object -const_eval_validation_invalid_vtable_ptr = {$front_matter}: encountered {$value}, but expected a vtable pointer -const_eval_validation_invalid_vtable_trait = {$front_matter}: wrong trait in wide pointer vtable: expected `{$expected_dyn_type}`, but encountered `{$vtable_dyn_type}` -const_eval_validation_mutable_ref_to_immutable = {$front_matter}: encountered mutable reference or box pointing to read-only memory -const_eval_validation_never_val = {$front_matter}: encountered a value of the never type `!` -const_eval_validation_nonnull_ptr_out_of_range = {$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero -const_eval_validation_null_box = {$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null - } box -const_eval_validation_null_fn_ptr = {$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null - } function pointer -const_eval_validation_null_ref = {$front_matter}: encountered a {$maybe -> - [true] maybe-null - *[false] null - } reference -const_eval_validation_out_of_range = {$front_matter}: encountered {$value}, but expected something {$in_range} -const_eval_validation_partial_pointer = {$front_matter}: encountered a partial pointer or a mix of pointers -const_eval_validation_pointer_as_int = {$front_matter}: encountered a pointer, but {$expected} -const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer with unknown absolute address, but expected something that is definitely {$in_range} -const_eval_validation_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty} -const_eval_validation_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes}) -const_eval_validation_unaligned_ref = {$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes}) -const_eval_validation_uninhabited_enum_variant = {$front_matter}: encountered an uninhabited enum variant -const_eval_validation_uninhabited_val = {$front_matter}: encountered a value of uninhabited type `{$ty}` -const_eval_validation_uninit = {$front_matter}: encountered uninitialized memory, but {$expected} -const_eval_validation_unsafe_cell = {$front_matter}: encountered `UnsafeCell` in read-only memory - -const_eval_write_through_immutable_pointer = - writing through a pointer that was derived from a shared (immutable) reference - -const_eval_write_to_read_only = - writing to {$allocation} which is read-only diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 78e4066ca910..9c9a921bd62d 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -1,15 +1,16 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. -use std::assert_matches::assert_matches; use std::borrow::Cow; use std::mem; use std::num::NonZero; use std::ops::Deref; +use rustc_data_structures::assert_matches; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, LangItem}; +use rustc_hir::{self as hir, LangItem, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::visit::Visitor; @@ -215,7 +216,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { return; } - if !tcx.has_attr(def_id, sym::rustc_do_not_const_check) { + if !find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcDoNotConstCheck) { self.visit_body(body); } @@ -251,7 +252,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { let mut transient = DenseBitSet::new_filled(ccx.body.local_decls.len()); // Make sure to only visit reachable blocks, the dataflow engine can ICE otherwise. for (bb, data) in traversal::reachable(&ccx.body) { - if matches!(data.terminator().kind, TerminatorKind::Return) { + if data.terminator().kind == TerminatorKind::Return { let location = ccx.body.terminator_loc(bb); maybe_storage_live.seek_after_primary_effect(location); // If a local may be live here, it is definitely not transient. @@ -645,9 +646,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(_, _, _) => {} - Rvalue::NullaryOp(NullOp::RuntimeChecks(_)) => {} - Rvalue::ShallowInitBox(_, _) => {} - Rvalue::UnaryOp(op, operand) => { let ty = operand.ty(self.body, self.tcx); match op { @@ -775,16 +773,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Attempting to call a trait method? if let Some(trait_did) = tcx.trait_of_assoc(callee) { - // We can't determine the actual callee here, so we have to do different checks - // than usual. + // We can't determine the actual callee (the underlying impl of the trait) here, so we have + // to do different checks than usual. trace!("attempting to call a trait method"); - let trait_is_const = tcx.is_const_trait(trait_did); + let is_const = tcx.constness(callee) == hir::Constness::Const; // Only consider a trait to be const if the const conditions hold. // Otherwise, it's really misleading to call something "conditionally" // const when it's very obviously not conditionally const. - if trait_is_const && has_const_conditions == Some(ConstConditionsHold::Yes) { + if is_const && has_const_conditions == Some(ConstConditionsHold::Yes) { // Trait calls are always conditionally-const. self.check_op(ops::ConditionallyConstCall { callee, @@ -816,6 +814,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }); } + if self.tcx.fn_sig(callee).skip_binder().c_variadic() { + self.check_op(ops::FnCallCVariadic) + } + // At this point, we are calling a function, `callee`, whose `DefId` is known... // `begin_panic` and `panic_display` functions accept generic @@ -834,24 +836,18 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // const-eval of `panic_display` assumes the argument is `&&str` if tcx.is_lang_item(callee, LangItem::PanicDisplay) { - match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() { - ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) => - {} - _ => { - self.check_op(ops::PanicNonStr); - } + if let ty::Ref(_, ty, _) = + args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() + && let ty::Ref(_, ty, _) = ty.kind() + && ty.is_str() + { + } else { + self.check_op(ops::PanicNonStr); } // Allow this call, skip all the checks below. return; } - // This can be called on stable via the `vec!` macro. - if tcx.is_lang_item(callee, LangItem::ExchangeMalloc) { - self.check_op(ops::HeapAllocation); - // Allow this call, skip all the checks below. - return; - } - // Intrinsics are language primitives, not regular calls, so treat them separately. if let Some(intrinsic) = tcx.intrinsic(callee) { if !tcx.is_const_fn(callee) { diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 4a88d039ef3c..1adba200caaf 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -83,7 +83,7 @@ pub fn rustc_allow_const_fn_unstable( ) -> bool { let attrs = tcx.hir_attrs(tcx.local_def_id_to_hir_id(def_id)); - find_attr!(attrs, AttributeKind::AllowConstFnUnstable(syms, _) if syms.contains(&feature_gate)) + find_attr!(attrs, AttributeKind::RustcAllowConstFnUnstable(syms, _) if syms.contains(&feature_gate)) } /// Returns `true` if the given `def_id` (trait or function) is "safe to expose on stable". @@ -95,8 +95,10 @@ pub fn rustc_allow_const_fn_unstable( /// unstable features, not even recursively), and those that are not. pub fn is_fn_or_trait_safe_to_expose_on_stable(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // A default body in a `const trait` is const-stable when the trait is const-stable. - if tcx.is_const_default_method(def_id) { - return is_fn_or_trait_safe_to_expose_on_stable(tcx, tcx.parent(def_id)); + if let Some(trait_id) = tcx.trait_of_assoc(def_id) + && tcx.is_const_trait(trait_id) + { + return is_fn_or_trait_safe_to_expose_on_stable(tcx, trait_id); } match tcx.lookup_const_stability(def_id) { diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index f606158e4018..13e78259e268 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -2,7 +2,7 @@ use hir::{ConstContext, LangItem}; use rustc_errors::codes::*; -use rustc_errors::{Applicability, Diag, MultiSpan}; +use rustc_errors::{Applicability, Diag, MultiSpan, msg}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; @@ -23,7 +23,7 @@ use rustc_trait_selection::traits::SelectionContext; use tracing::debug; use super::ConstCx; -use crate::{errors, fluent_generated}; +use crate::errors; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Status { @@ -75,6 +75,27 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect { } } +/// A c-variadic function call. +#[derive(Debug)] +pub(crate) struct FnCallCVariadic; +impl<'tcx> NonConstOp<'tcx> for FnCallCVariadic { + fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status { + Status::Unstable { + gate: sym::const_c_variadic, + gate_already_checked: false, + safe_to_expose_on_stable: false, + is_function_call: true, + } + } + + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { + ccx.tcx.sess.create_feature_err( + errors::NonConstCVariadicCall { span, kind: ccx.const_kind() }, + sym::const_c_variadic, + ) + } +} + /// A call to a function that is in a trait, or has trait bounds that make it conditionally-const. #[derive(Debug)] pub(crate) struct ConditionallyConstCall<'tcx> { @@ -125,9 +146,6 @@ pub(crate) struct FnCallNonConst<'tcx> { } impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { - // FIXME: make this translatable - #[allow(rustc::diagnostic_outside_of_impl)] - #[allow(rustc::untranslatable_diagnostic)] fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> { let tcx = ccx.tcx; let caller = ccx.def_id(); @@ -184,7 +202,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ); if let ConstContext::Static(_) = ccx.const_kind() { - err.note(fluent_generated::const_eval_lazy_lock); + err.note(msg!( + "consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`" + )); } err @@ -541,18 +561,6 @@ impl<'tcx> NonConstOp<'tcx> for Coroutine { } } -#[derive(Debug)] -pub(crate) struct HeapAllocation; -impl<'tcx> NonConstOp<'tcx> for HeapAllocation { - fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> { - ccx.dcx().create_err(errors::UnallowedHeapAllocations { - span, - kind: ccx.const_kind(), - teach: ccx.tcx.sess.teach(E0010), - }) - } -} - #[derive(Debug)] pub(crate) struct InlineAsm; impl<'tcx> NonConstOp<'tcx> for InlineAsm { diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index 16e142a85ee6..6189d9321dc0 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -1,3 +1,5 @@ +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, BasicBlock, Location}; use rustc_middle::ty::TyCtxt; @@ -34,7 +36,7 @@ pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) { return; } - if tcx.has_attr(body.source.def_id(), sym::rustc_do_not_const_check) { + if find_attr!(tcx.get_all_attrs(body.source.def_id()), AttributeKind::RustcDoNotConstCheck) { return; } diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index f50c6af53bf1..1fbd0cd23405 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -6,9 +6,7 @@ // having basically only two use-cases that act in different ways. use rustc_errors::ErrorGuaranteed; -use rustc_hir::attrs::AttributeKind; -use rustc_hir::def::DefKind; -use rustc_hir::{LangItem, find_attr}; +use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::*; use rustc_middle::ty::{self, AdtDef, Ty}; @@ -230,9 +228,7 @@ where F: FnMut(Local) -> bool, { match rvalue { - Rvalue::ThreadLocalRef(_) | Rvalue::NullaryOp(..) => { - Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) - } + Rvalue::ThreadLocalRef(_) => Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)), Rvalue::Discriminant(place) => in_place::(cx, in_local, place.as_ref()), @@ -241,8 +237,7 @@ where Rvalue::Use(operand) | Rvalue::Repeat(operand, _) | Rvalue::UnaryOp(_, operand) - | Rvalue::Cast(_, operand, _) - | Rvalue::ShallowInitBox(operand, _) => in_operand::(cx, in_local, operand), + | Rvalue::Cast(_, operand, _) => in_operand::(cx, in_local, operand), Rvalue::BinaryOp(_, box (lhs, rhs)) => { in_operand::(cx, in_local, lhs) || in_operand::(cx, in_local, rhs) @@ -314,7 +309,7 @@ where // i.e., we treat all qualifs as non-structural for deref projections. Generally, // we can say very little about `*ptr` even if we know that `ptr` satisfies all // sorts of properties. - if matches!(elem, ProjectionElem::Deref) { + if elem == ProjectionElem::Deref { // We have to assume that this qualifies. return true; } @@ -340,23 +335,25 @@ where Operand::Copy(place) | Operand::Move(place) => { return in_place::(cx, in_local, place.as_ref()); } + Operand::RuntimeChecks(_) => return Q::in_any_value_of_ty(cx, cx.tcx.types.bool), Operand::Constant(c) => c, }; // Check the qualifs of the value of `const` items. let uneval = match constant.const_ { - Const::Ty(_, ct) - if matches!( - ct.kind(), - ty::ConstKind::Param(_) | ty::ConstKind::Error(_) | ty::ConstKind::Value(_) - ) => - { - None - } - Const::Ty(_, c) => { - bug!("expected ConstKind::Param or ConstKind::Value here, found {:?}", c) - } + Const::Ty(_, ct) => match ct.kind() { + ty::ConstKind::Param(_) | ty::ConstKind::Error(_) => None, + // Unevaluated consts in MIR bodies don't have associated MIR (e.g. `type const`). + ty::ConstKind::Unevaluated(_) => None, + // FIXME(mgca): Investigate whether using `None` for `ConstKind::Value` is overly + // strict, and if instead we should be doing some kind of value-based analysis. + ty::ConstKind::Value(_) => None, + _ => bug!( + "expected ConstKind::Param, ConstKind::Value, ConstKind::Unevaluated, or ConstKind::Error here, found {:?}", + ct + ), + }, Const::Unevaluated(uv, _) => Some(uv), Const::Val(..) => None, }; @@ -367,14 +364,8 @@ where // check performed after the promotion. Verify that with an assertion. assert!(promoted.is_none() || Q::ALLOW_PROMOTED); - // Avoid looking at attrs of anon consts as that will ICE - let is_type_const_item = - matches!(cx.tcx.def_kind(def), DefKind::Const | DefKind::AssocConst) - && find_attr!(cx.tcx.get_all_attrs(def), AttributeKind::TypeConst(_)); - - // Don't peak inside trait associated constants, also `#[type_const] const` items - // don't have bodies so there's nothing to look at - if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() && !is_type_const_item { + // Don't peak inside trait associated constants. + if promoted.is_none() && cx.tcx.trait_of_assoc(def).is_none() { let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def); if !Q::in_qualifs(&qualifs) { diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index e6e3948305af..044b8b091b8d 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -192,13 +192,11 @@ where } mir::Rvalue::Cast(..) - | mir::Rvalue::ShallowInitBox(..) | mir::Rvalue::Use(..) | mir::Rvalue::CopyForDeref(..) | mir::Rvalue::ThreadLocalRef(..) | mir::Rvalue::Repeat(..) | mir::Rvalue::BinaryOp(..) - | mir::Rvalue::NullaryOp(..) | mir::Rvalue::UnaryOp(..) | mir::Rvalue::Discriminant(..) | mir::Rvalue::Aggregate(..) diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index 438aed41b8be..f41b68bb1f7e 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -122,6 +122,13 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine { unimplemented!() } + #[inline(always)] + fn runtime_checks(_ecx: &InterpCx<'tcx, Self>, r: RuntimeChecks) -> InterpResult<'tcx, bool> { + // Runtime checks have different value depending on the crate they are codegenned in. + // Verify we aren't trying to evaluate them in mir-optimizations. + panic!("compiletime machine evaluated {r:?}") + } + fn binary_ptr_op( ecx: &InterpCx<'tcx, Self>, bin_op: BinOp, diff --git a/compiler/rustc_const_eval/src/const_eval/dyn_trait.rs b/compiler/rustc_const_eval/src/const_eval/dyn_trait.rs new file mode 100644 index 000000000000..0976a7283ef3 --- /dev/null +++ b/compiler/rustc_const_eval/src/const_eval/dyn_trait.rs @@ -0,0 +1,178 @@ +use rustc_middle::mir::interpret::{CtfeProvenance, InterpResult, Scalar, interp_ok}; +use rustc_middle::ty::{Region, Ty}; +use rustc_middle::{span_bug, ty}; +use rustc_span::def_id::DefId; +use rustc_span::sym; + +use crate::const_eval::CompileTimeMachine; +use crate::interpret::{Immediate, InterpCx, MPlaceTy, MemoryKind, Writeable}; +impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { + pub(crate) fn write_dyn_trait_type_info( + &mut self, + dyn_place: impl Writeable<'tcx, CtfeProvenance>, + data: &'tcx ty::List>>, + region: Region<'tcx>, + ) -> InterpResult<'tcx> { + let tcx = self.tcx.tcx; + + // Find the principal trait ref (for super trait collection), collect auto traits, + // and collect all projection predicates (used when computing TypeId for each supertrait). + let mut principal: Option>> = None; + let mut auto_traits_def_ids: Vec> = Vec::new(); + let mut projections: Vec>> = Vec::new(); + + for b in data.iter() { + match b.skip_binder() { + ty::ExistentialPredicate::Trait(tr) => principal = Some(b.rebind(tr)), + ty::ExistentialPredicate::AutoTrait(did) => auto_traits_def_ids.push(b.rebind(did)), + ty::ExistentialPredicate::Projection(p) => projections.push(b.rebind(p)), + } + } + + // This is to make principal dyn type include Trait and projection predicates, excluding auto traits. + let principal_ty: Option> = principal.map(|_tr| { + let preds = tcx + .mk_poly_existential_predicates_from_iter(data.iter().filter(|b| { + !matches!(b.skip_binder(), ty::ExistentialPredicate::AutoTrait(_)) + })); + Ty::new_dynamic(tcx, preds, region) + }); + + // DynTrait { predicates: &'static [Trait] } + for (field_idx, field) in + dyn_place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&dyn_place, field_idx)?; + match field.name { + sym::predicates => { + self.write_dyn_trait_predicates_slice( + &field_place, + principal_ty, + &auto_traits_def_ids, + region, + )?; + } + other => { + span_bug!(self.tcx.def_span(field.did), "unimplemented DynTrait field {other}") + } + } + } + + interp_ok(()) + } + + fn mk_dyn_principal_auto_trait_ty( + &self, + auto_trait_def_id: ty::Binder<'tcx, DefId>, + region: Region<'tcx>, + ) -> Ty<'tcx> { + let tcx = self.tcx.tcx; + + // Preserve the binder vars from the original auto-trait predicate. + let pred_inner = ty::ExistentialPredicate::AutoTrait(auto_trait_def_id.skip_binder()); + let pred = ty::Binder::bind_with_vars(pred_inner, auto_trait_def_id.bound_vars()); + + let preds = tcx.mk_poly_existential_predicates_from_iter([pred].into_iter()); + Ty::new_dynamic(tcx, preds, region) + } + + fn write_dyn_trait_predicates_slice( + &mut self, + slice_place: &impl Writeable<'tcx, CtfeProvenance>, + principal_ty: Option>, + auto_trait_def_ids: &[ty::Binder<'tcx, DefId>], + region: Region<'tcx>, + ) -> InterpResult<'tcx> { + let tcx = self.tcx.tcx; + + // total entries in DynTrait predicates + let total_len = principal_ty.map(|_| 1).unwrap_or(0) + auto_trait_def_ids.len(); + + // element type = DynTraitPredicate + let slice_ty = slice_place.layout().ty.builtin_deref(false).unwrap(); // [DynTraitPredicate] + let elem_ty = slice_ty.sequence_element_type(tcx); // DynTraitPredicate + + let arr_layout = self.layout_of(Ty::new_array(tcx, elem_ty, total_len as u64))?; + let arr_place = self.allocate(arr_layout, MemoryKind::Stack)?; + let mut elems = self.project_array_fields(&arr_place)?; + + // principal entry (if any) - NOT an auto trait + if let Some(principal_ty) = principal_ty { + let Some((_i, elem_place)) = elems.next(self)? else { + span_bug!(self.tcx.span, "DynTrait.predicates length computed wrong (principal)"); + }; + self.write_dyn_trait_predicate(elem_place, principal_ty, false)?; + } + + // auto trait entries - these ARE auto traits + for auto in auto_trait_def_ids { + let Some((_i, elem_place)) = elems.next(self)? else { + span_bug!(self.tcx.span, "DynTrait.predicates length computed wrong (auto)"); + }; + let auto_ty = self.mk_dyn_principal_auto_trait_ty(*auto, region); + self.write_dyn_trait_predicate(elem_place, auto_ty, true)?; + } + + let arr_place = arr_place.map_provenance(CtfeProvenance::as_immutable); + let imm = Immediate::new_slice(arr_place.ptr(), total_len as u64, self); + self.write_immediate(imm, slice_place) + } + + fn write_dyn_trait_predicate( + &mut self, + predicate_place: MPlaceTy<'tcx>, + trait_ty: Ty<'tcx>, + is_auto: bool, + ) -> InterpResult<'tcx> { + // DynTraitPredicate { trait_ty: Trait } + for (field_idx, field) in predicate_place + .layout + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&predicate_place, field_idx)?; + match field.name { + sym::trait_ty => { + // Now write the Trait struct + self.write_trait(field_place, trait_ty, is_auto)?; + } + other => { + span_bug!( + self.tcx.def_span(field.did), + "unimplemented DynTraitPredicate field {other}" + ) + } + } + } + interp_ok(()) + } + fn write_trait( + &mut self, + trait_place: MPlaceTy<'tcx>, + trait_ty: Ty<'tcx>, + is_auto: bool, + ) -> InterpResult<'tcx> { + // Trait { ty: TypeId, is_auto: bool } + for (field_idx, field) in + trait_place.layout.ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&trait_place, field_idx)?; + match field.name { + sym::ty => { + self.write_type_id(trait_ty, &field_place)?; + } + sym::is_auto => { + self.write_scalar(Scalar::from_bool(is_auto), &field_place)?; + } + other => { + span_bug!(self.tcx.def_span(field.did), "unimplemented Trait field {other}") + } + } + } + interp_ok(()) + } +} diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 69a8f163ca93..69aef3b047df 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -43,21 +43,37 @@ pub enum ConstEvalErrKind { impl MachineStopType for ConstEvalErrKind { fn diagnostic_message(&self) -> DiagMessage { use ConstEvalErrKind::*; + use rustc_errors::msg; - use crate::fluent_generated::*; match self { - ConstAccessesMutGlobal => const_eval_const_accesses_mut_global, - ModifiedGlobal => const_eval_modified_global, - Panic { .. } => const_eval_panic, - RecursiveStatic => const_eval_recursive_static, - AssertFailure(x) => x.diagnostic_message(), - WriteThroughImmutablePointer => const_eval_write_through_immutable_pointer, - ConstMakeGlobalPtrAlreadyMadeGlobal { .. } => { - const_eval_const_make_global_ptr_already_made_global + ConstAccessesMutGlobal => "constant accesses mutable global memory".into(), + ModifiedGlobal => { + "modifying a static's initial value from another static's initializer".into() + } + Panic { .. } => msg!("evaluation panicked: {$msg}"), + RecursiveStatic => { + "encountered static that tried to access itself during initialization".into() + } + AssertFailure(x) => x.diagnostic_message(), + WriteThroughImmutablePointer => { + msg!( + "writing through a pointer that was derived from a shared (immutable) reference" + ) + } + ConstMakeGlobalPtrAlreadyMadeGlobal { .. } => { + msg!("attempting to call `const_make_global` twice on the same allocation {$alloc}") + } + ConstMakeGlobalPtrIsNonHeap(_) => { + msg!( + "pointer passed to `const_make_global` does not point to a heap allocation: {$ptr}" + ) + } + ConstMakeGlobalWithDanglingPtr(_) => { + msg!("pointer passed to `const_make_global` is dangling: {$ptr}") + } + ConstMakeGlobalWithOffset(_) => { + msg!("making {$ptr} global which does not point to the beginning of an object") } - ConstMakeGlobalPtrIsNonHeap(_) => const_eval_const_make_global_ptr_is_non_heap, - ConstMakeGlobalWithDanglingPtr(_) => const_eval_const_make_global_with_dangling_ptr, - ConstMakeGlobalWithOffset(_) => const_eval_const_make_global_with_offset, } } fn add_args(self: Box, adder: &mut dyn FnMut(DiagArgName, DiagArgValue)) { diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index beea1b4a28c9..d2b7e9a6b84f 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -2,7 +2,7 @@ use std::sync::atomic::Ordering::Relaxed; use either::{Left, Right}; use rustc_abi::{self as abi, BackendRepr}; -use rustc_errors::E0080; +use rustc_errors::{E0080, msg}; use rustc_hir::def::DefKind; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo, ReportedErrorInfo}; use rustc_middle::mir::{self, ConstAlloc, ConstValue}; @@ -394,8 +394,10 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>( typing_env: ty::TypingEnv<'tcx>, ) -> Result { let def = cid.instance.def.def_id(); - let is_static = tcx.is_static(def); + // `type const` don't have bodys + debug_assert!(!tcx.is_type_const(def), "CTFE tried to evaluate type-const: {:?}", def); + let is_static = tcx.is_static(def); let mut ecx = InterpCx::new( tcx, tcx.def_span(def), @@ -465,7 +467,15 @@ fn report_eval_error<'tcx>( let num_frames = frames.len(); // FIXME(oli-obk): figure out how to use structured diagnostics again. diag.code(E0080); - diag.span_label(span, crate::fluent_generated::const_eval_error); + diag.span_label( + span, + msg!( + "evaluation of `{$instance}` failed {$num_frames -> + [0] here + *[other] inside this call + }" + ), + ); for frame in frames { diag.subdiagnostic(frame); } @@ -504,8 +514,8 @@ fn report_validation_error<'tcx>( move |diag, span, frames| { // FIXME(oli-obk): figure out how to use structured diagnostics again. diag.code(E0080); - diag.span_label(span, crate::fluent_generated::const_eval_validation_failure); - diag.note(crate::fluent_generated::const_eval_validation_failure_note); + diag.span_label(span, "it is undefined behavior to use this value"); + diag.note("the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior."); for frame in frames { diag.subdiagnostic(frame); } diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index cdf0dcff381f..46cdca53ba8c 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -1,7 +1,8 @@ +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{ Constness, ExprKind, ForeignItemKind, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind, - Node, TraitItem, TraitItemKind, VariantData, + Node, TraitItem, TraitItemKind, VariantData, find_attr, }; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; @@ -36,7 +37,13 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness { Constness::NotConst => tcx.constness(tcx.local_parent(def_id)), } } - Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(..), .. }) => tcx.trait_def(tcx.local_parent(def_id)).constness, + Node::TraitItem(ti @ TraitItem { kind: TraitItemKind::Fn(..), .. }) => { + if find_attr!(tcx.hir_attrs(ti.hir_id()), AttributeKind::RustcNonConstTraitMethod) { + Constness::NotConst + } else { + tcx.trait_def(tcx.local_parent(def_id)).constness + } + } _ => { tcx.dcx().span_bug( tcx.def_span(def_id), diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index fccb6b171b1c..3b4f7ed3261a 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -5,8 +5,10 @@ use std::hash::Hash; use rustc_abi::{Align, Size}; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; +use rustc_errors::msg; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem}; +use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem, find_attr}; use rustc_middle::mir::AssertMessage; use rustc_middle::mir::interpret::ReportedErrorInfo; use rustc_middle::query::TyCtxtAt; @@ -19,7 +21,6 @@ use tracing::debug; use super::error::*; use crate::errors::{LongRunning, LongRunningWarn}; -use crate::fluent_generated as fluent; use crate::interpret::{ self, AllocId, AllocInit, AllocRange, ConstAllocation, CtfeProvenance, FnArg, Frame, GlobalAlloc, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, RangeSet, Scalar, @@ -208,15 +209,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); - use rustc_session::RemapFileNameExt; - use rustc_session::config::RemapPathScopeComponents; + use rustc_span::RemapPathScopeComponents; ( Symbol::intern( - &caller - .file - .name - .for_scope(self.tcx.sess, RemapPathScopeComponents::DIAGNOSTICS) - .to_string_lossy(), + &caller.file.name.display(RemapPathScopeComponents::DIAGNOSTICS).to_string_lossy(), ), u32::try_from(caller.line).unwrap(), u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(), @@ -240,7 +236,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> { if self.tcx.is_lang_item(def_id, LangItem::PanicDisplay) || self.tcx.is_lang_item(def_id, LangItem::BeginPanic) { - let args = self.copy_fn_args(args); + let args = Self::copy_fn_args(args); // &str or &&str assert!(args.len() == 1); @@ -445,7 +441,9 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { // sensitive check here. But we can at least rule out functions that are not const at // all. That said, we have to allow calling functions inside a `const trait`. These // *are* const-checked! - if !ecx.tcx.is_const_fn(def) || ecx.tcx.has_attr(def, sym::rustc_do_not_const_check) { + if !ecx.tcx.is_const_fn(def) + || find_attr!(ecx.tcx.get_all_attrs(def), AttributeKind::RustcDoNotConstCheck) + { // We certainly do *not* want to actually call the fn // though, so be sure we return here. throw_unsup_format!("calling non-const function `{}`", instance) @@ -494,7 +492,13 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { let align = match Align::from_bytes(align) { Ok(a) => a, Err(err) => throw_ub_custom!( - fluent::const_eval_invalid_align_details, + msg!( + "invalid align passed to `{$name}`: {$align} is {$err_kind -> + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" + ), name = "const_allocate", err_kind = err.diag_ident(), align = err.align() @@ -518,7 +522,13 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { let align = match Align::from_bytes(align) { Ok(a) => a, Err(err) => throw_ub_custom!( - fluent::const_eval_invalid_align_details, + msg!( + "invalid align passed to `{$name}`: {$align} is {$err_kind -> + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" + ), name = "const_deallocate", err_kind = err.diag_ident(), align = err.align() @@ -591,6 +601,11 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { } } + sym::type_of => { + let ty = ecx.read_type_id(&args[0])?; + ecx.write_type_info(ty, dest)?; + } + _ => { // We haven't handled the intrinsic, let's see if we can use a fallback body. if ecx.tcx.intrinsic(instance.def_id()).unwrap().must_be_overridden { @@ -642,6 +657,16 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { Err(ConstEvalErrKind::AssertFailure(err)).into() } + #[inline(always)] + fn runtime_checks( + _ecx: &InterpCx<'tcx, Self>, + _r: mir::RuntimeChecks, + ) -> InterpResult<'tcx, bool> { + // We can't look at `tcx.sess` here as that can differ across crates, which can lead to + // unsound differences in evaluating the same constant at different instantiation sites. + interp_ok(true) + } + fn binary_ptr_op( _ecx: &InterpCx<'tcx, Self>, _bin_op: mir::BinOp, diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 624ca1dd2da0..c17ff8621a50 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -9,10 +9,12 @@ use tracing::instrument; use crate::interpret::InterpCx; mod dummy_machine; +mod dyn_trait; mod error; mod eval_queries; mod fn_queries; mod machine; +mod type_info; mod valtrees; pub use self::dummy_machine::*; diff --git a/compiler/rustc_const_eval/src/const_eval/type_info.rs b/compiler/rustc_const_eval/src/const_eval/type_info.rs new file mode 100644 index 000000000000..0fd70d784d4f --- /dev/null +++ b/compiler/rustc_const_eval/src/const_eval/type_info.rs @@ -0,0 +1,430 @@ +mod adt; + +use std::borrow::Cow; + +use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_ast::Mutability; +use rustc_hir::LangItem; +use rustc_middle::span_bug; +use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::{self, Const, ScalarInt, Ty}; +use rustc_span::{Symbol, sym}; + +use crate::const_eval::CompileTimeMachine; +use crate::interpret::{ + CtfeProvenance, Immediate, InterpCx, InterpResult, MPlaceTy, MemoryKind, Projectable, Scalar, + Writeable, interp_ok, +}; + +impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { + /// Equivalent to `project_downcast`, but identifies the variant by name instead of index. + fn downcast<'a>( + &self, + place: &(impl Writeable<'tcx, CtfeProvenance> + 'a), + name: Symbol, + ) -> InterpResult<'tcx, (VariantIdx, impl Writeable<'tcx, CtfeProvenance> + 'a)> { + let variants = place.layout().ty.ty_adt_def().unwrap().variants(); + let variant_idx = variants + .iter_enumerated() + .find(|(_idx, var)| var.name == name) + .unwrap_or_else(|| panic!("got {name} but expected one of {variants:#?}")) + .0; + + interp_ok((variant_idx, self.project_downcast(place, variant_idx)?)) + } + + // A general method to write an array to a static slice place. + fn allocate_fill_and_write_slice_ptr( + &mut self, + slice_place: impl Writeable<'tcx, CtfeProvenance>, + len: u64, + writer: impl Fn(&mut Self, /* index */ u64, MPlaceTy<'tcx>) -> InterpResult<'tcx>, + ) -> InterpResult<'tcx> { + // Array element type + let field_ty = slice_place + .layout() + .ty + .builtin_deref(false) + .unwrap() + .sequence_element_type(self.tcx.tcx); + + // Allocate an array + let array_layout = self.layout_of(Ty::new_array(self.tcx.tcx, field_ty, len))?; + let array_place = self.allocate(array_layout, MemoryKind::Stack)?; + + // Fill the array fields + let mut field_places = self.project_array_fields(&array_place)?; + while let Some((i, place)) = field_places.next(self)? { + writer(self, i, place)?; + } + + // Write the slice pointing to the array + let array_place = array_place.map_provenance(CtfeProvenance::as_immutable); + let ptr = Immediate::new_slice(array_place.ptr(), len, self); + self.write_immediate(ptr, &slice_place) + } + + /// Writes a `core::mem::type_info::TypeInfo` for a given type, `ty` to the given place. + pub(crate) fn write_type_info( + &mut self, + ty: Ty<'tcx>, + dest: &impl Writeable<'tcx, CtfeProvenance>, + ) -> InterpResult<'tcx> { + let ty_struct = self.tcx.require_lang_item(LangItem::Type, self.tcx.span); + let ty_struct = self.tcx.type_of(ty_struct).no_bound_vars().unwrap(); + assert_eq!(ty_struct, dest.layout().ty); + let ty_struct = ty_struct.ty_adt_def().unwrap().non_enum_variant(); + // Fill all fields of the `TypeInfo` struct. + for (idx, field) in ty_struct.fields.iter_enumerated() { + let field_dest = self.project_field(dest, idx)?; + let ptr_bit_width = || self.tcx.data_layout.pointer_size().bits(); + match field.name { + sym::kind => { + let variant_index = match ty.kind() { + ty::Tuple(fields) => { + let (variant, variant_place) = + self.downcast(&field_dest, sym::Tuple)?; + // project to the single tuple variant field of `type_info::Tuple` struct type + let tuple_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + assert_eq!( + 1, + tuple_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .len() + ); + self.write_tuple_type_info(tuple_place, fields, ty)?; + variant + } + ty::Array(ty, len) => { + let (variant, variant_place) = + self.downcast(&field_dest, sym::Array)?; + let array_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + self.write_array_type_info(array_place, *ty, *len)?; + + variant + } + ty::Slice(ty) => { + let (variant, variant_place) = + self.downcast(&field_dest, sym::Slice)?; + let slice_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + self.write_slice_type_info(slice_place, *ty)?; + + variant + } + ty::Adt(adt_def, generics) => { + self.write_adt_type_info(&field_dest, (ty, *adt_def), generics)? + } + ty::Bool => { + let (variant, _variant_place) = + self.downcast(&field_dest, sym::Bool)?; + variant + } + ty::Char => { + let (variant, _variant_place) = + self.downcast(&field_dest, sym::Char)?; + variant + } + ty::Int(int_ty) => { + let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_int_type_info( + place, + int_ty.bit_width().unwrap_or_else(/* isize */ ptr_bit_width), + true, + )?; + variant + } + ty::Uint(uint_ty) => { + let (variant, variant_place) = self.downcast(&field_dest, sym::Int)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_int_type_info( + place, + uint_ty.bit_width().unwrap_or_else(/* usize */ ptr_bit_width), + false, + )?; + variant + } + ty::Float(float_ty) => { + let (variant, variant_place) = + self.downcast(&field_dest, sym::Float)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_float_type_info(place, float_ty.bit_width())?; + variant + } + ty::Str => { + let (variant, _variant_place) = self.downcast(&field_dest, sym::Str)?; + variant + } + ty::Ref(_, ty, mutability) => { + let (variant, variant_place) = + self.downcast(&field_dest, sym::Reference)?; + let reference_place = + self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_reference_type_info(reference_place, *ty, *mutability)?; + + variant + } + ty::RawPtr(ty, mutability) => { + let (variant, variant_place) = + self.downcast(&field_dest, sym::Pointer)?; + let pointer_place = + self.project_field(&variant_place, FieldIdx::ZERO)?; + + self.write_pointer_type_info(pointer_place, *ty, *mutability)?; + + variant + } + ty::Dynamic(predicates, region) => { + let (variant, variant_place) = + self.downcast(&field_dest, sym::DynTrait)?; + let dyn_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_dyn_trait_type_info(dyn_place, *predicates, *region)?; + variant + } + ty::Foreign(_) + | ty::Pat(_, _) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::UnsafeBinder(..) + | ty::Closure(..) + | ty::CoroutineClosure(..) + | ty::Coroutine(..) + | ty::CoroutineWitness(..) + | ty::Never + | ty::Alias(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Placeholder(_) + | ty::Infer(..) + | ty::Error(_) => self.downcast(&field_dest, sym::Other)?.0, + }; + self.write_discriminant(variant_index, &field_dest)? + } + sym::size => { + let layout = self.layout_of(ty)?; + let variant_index = if layout.is_sized() { + let (variant, variant_place) = self.downcast(&field_dest, sym::Some)?; + let size_field_place = + self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_scalar( + ScalarInt::try_from_target_usize(layout.size.bytes(), self.tcx.tcx) + .unwrap(), + &size_field_place, + )?; + variant + } else { + self.downcast(&field_dest, sym::None)?.0 + }; + self.write_discriminant(variant_index, &field_dest)?; + } + other => span_bug!(self.tcx.span, "unknown `Type` field {other}"), + } + } + + interp_ok(()) + } + + fn write_field( + &mut self, + field_ty: Ty<'tcx>, + place: MPlaceTy<'tcx>, + layout: TyAndLayout<'tcx>, + name: Option, + idx: u64, + ) -> InterpResult<'tcx> { + for (field_idx, field_ty_field) in + place.layout.ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field_ty_field.name { + sym::name => { + let name = match name.as_ref() { + Some(name) => Cow::Borrowed(name.as_str()), + None => Cow::Owned(idx.to_string()), // For tuples + }; + let name_place = self.allocate_str_dedup(&name)?; + let ptr = self.mplace_to_ref(&name_place)?; + self.write_immediate(*ptr, &field_place)? + } + sym::ty => { + let field_ty = self.tcx.erase_and_anonymize_regions(field_ty); + self.write_type_id(field_ty, &field_place)? + } + sym::offset => { + let offset = layout.fields.offset(idx as usize); + self.write_scalar( + ScalarInt::try_from_target_usize(offset.bytes(), self.tcx.tcx).unwrap(), + &field_place, + )?; + } + other => { + span_bug!(self.tcx.def_span(field_ty_field.did), "unimplemented field {other}") + } + } + } + interp_ok(()) + } + + pub(crate) fn write_tuple_type_info( + &mut self, + tuple_place: impl Writeable<'tcx, CtfeProvenance>, + fields: &[Ty<'tcx>], + tuple_ty: Ty<'tcx>, + ) -> InterpResult<'tcx> { + let tuple_layout = self.layout_of(tuple_ty)?; + let fields_slice_place = self.project_field(&tuple_place, FieldIdx::ZERO)?; + self.allocate_fill_and_write_slice_ptr( + fields_slice_place, + fields.len() as u64, + |this, i, place| { + let field_ty = fields[i as usize]; + this.write_field(field_ty, place, tuple_layout, None, i) + }, + ) + } + + pub(crate) fn write_array_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + len: Const<'tcx>, + ) -> InterpResult<'tcx> { + // Iterate over all fields of `type_info::Array`. + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + // Write the `TypeId` of the array's elements to the `element_ty` field. + sym::element_ty => self.write_type_id(ty, &field_place)?, + // Write the length of the array to the `len` field. + sym::len => self.write_scalar(len.to_leaf(), &field_place)?, + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + pub(crate) fn write_slice_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + ) -> InterpResult<'tcx> { + // Iterate over all fields of `type_info::Slice`. + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + // Write the `TypeId` of the slice's elements to the `element_ty` field. + sym::element_ty => self.write_type_id(ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + fn write_int_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + bit_width: u64, + signed: bool, + ) -> InterpResult<'tcx> { + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field.name { + sym::bits => self.write_scalar( + Scalar::from_u32(bit_width.try_into().expect("bit_width overflowed")), + &field_place, + )?, + sym::signed => self.write_scalar(Scalar::from_bool(signed), &field_place)?, + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } + + fn write_float_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + bit_width: u64, + ) -> InterpResult<'tcx> { + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field.name { + sym::bits => self.write_scalar( + Scalar::from_u32(bit_width.try_into().expect("bit_width overflowed")), + &field_place, + )?, + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } + + pub(crate) fn write_reference_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + mutability: Mutability, + ) -> InterpResult<'tcx> { + // Iterate over all fields of `type_info::Reference`. + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + // Write the `TypeId` of the reference's inner type to the `ty` field. + sym::pointee => self.write_type_id(ty, &field_place)?, + // Write the boolean representing the reference's mutability to the `mutable` field. + sym::mutable => { + self.write_scalar(Scalar::from_bool(mutability.is_mut()), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } + + pub(crate) fn write_pointer_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + ty: Ty<'tcx>, + mutability: Mutability, + ) -> InterpResult<'tcx> { + // Iterate over all fields of `type_info::Pointer`. + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + // Write the `TypeId` of the pointer's inner type to the `ty` field. + sym::pointee => self.write_type_id(ty, &field_place)?, + // Write the boolean representing the pointer's mutability to the `mutable` field. + sym::mutable => { + self.write_scalar(Scalar::from_bool(mutability.is_mut()), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } +} diff --git a/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs new file mode 100644 index 000000000000..60f7b95e799a --- /dev/null +++ b/compiler/rustc_const_eval/src/const_eval/type_info/adt.rs @@ -0,0 +1,276 @@ +use rustc_abi::{FieldIdx, VariantIdx}; +use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::{ + AdtDef, AdtKind, Const, ConstKind, GenericArgKind, GenericArgs, Region, Ty, VariantDef, +}; +use rustc_middle::{bug, span_bug}; +use rustc_span::sym; + +use crate::const_eval::CompileTimeMachine; +use crate::interpret::{ + CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Projectable, Scalar, Writeable, interp_ok, +}; + +impl<'tcx> InterpCx<'tcx, CompileTimeMachine<'tcx>> { + // FIXME(type_info): No semver considerations for now + pub(crate) fn write_adt_type_info( + &mut self, + place: &impl Writeable<'tcx, CtfeProvenance>, + adt: (Ty<'tcx>, AdtDef<'tcx>), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx, VariantIdx> { + let (adt_ty, adt_def) = adt; + let variant_idx = match adt_def.adt_kind() { + AdtKind::Struct => { + let (variant, variant_place) = self.downcast(place, sym::Struct)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_struct_type_info( + place, + (adt_ty, adt_def.variant(VariantIdx::ZERO)), + generics, + )?; + variant + } + AdtKind::Union => { + let (variant, variant_place) = self.downcast(place, sym::Union)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_union_type_info( + place, + (adt_ty, adt_def.variant(VariantIdx::ZERO)), + generics, + )?; + variant + } + AdtKind::Enum => { + let (variant, variant_place) = self.downcast(place, sym::Enum)?; + let place = self.project_field(&variant_place, FieldIdx::ZERO)?; + self.write_enum_type_info(place, adt, generics)?; + variant + } + }; + interp_ok(variant_idx) + } + + pub(crate) fn write_struct_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + struct_: (Ty<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (struct_ty, struct_def) = struct_; + let struct_layout = self.layout_of(struct_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::fields => { + self.write_variant_fields(field_place, struct_def, struct_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = struct_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + pub(crate) fn write_union_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + union_: (Ty<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (union_ty, union_def) = union_; + let union_layout = self.layout_of(union_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::fields => { + self.write_variant_fields(field_place, union_def, union_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = union_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + pub(crate) fn write_enum_type_info( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + enum_: (Ty<'tcx>, AdtDef<'tcx>), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (enum_ty, enum_def) = enum_; + let enum_layout = self.layout_of(enum_ty)?; + + for (field_idx, field) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + + match field.name { + sym::generics => self.write_generics(field_place, generics)?, + sym::variants => { + self.allocate_fill_and_write_slice_ptr( + field_place, + enum_def.variants().len() as u64, + |this, i, place| { + let variant_idx = VariantIdx::from_usize(i as usize); + let variant_def = &enum_def.variants()[variant_idx]; + let variant_layout = enum_layout.for_variant(this, variant_idx); + this.write_enum_variant(place, (variant_layout, &variant_def), generics) + }, + )?; + } + sym::non_exhaustive => { + let is_non_exhaustive = enum_def.is_variant_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field.did), "unimplemented field {other}"), + } + } + + interp_ok(()) + } + + fn write_enum_variant( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + variant: (TyAndLayout<'tcx>, &'tcx VariantDef), + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + let (variant_layout, variant_def) = variant; + + for (field_idx, field_def) in + place.layout().ty.ty_adt_def().unwrap().non_enum_variant().fields.iter_enumerated() + { + let field_place = self.project_field(&place, field_idx)?; + match field_def.name { + sym::name => { + let name_place = self.allocate_str_dedup(variant_def.name.as_str())?; + let ptr = self.mplace_to_ref(&name_place)?; + self.write_immediate(*ptr, &field_place)? + } + sym::fields => { + self.write_variant_fields(field_place, &variant_def, variant_layout, generics)? + } + sym::non_exhaustive => { + let is_non_exhaustive = variant_def.is_field_list_non_exhaustive(); + self.write_scalar(Scalar::from_bool(is_non_exhaustive), &field_place)? + } + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + interp_ok(()) + } + + // Write fields for struct, enum variants + fn write_variant_fields( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + variant_def: &'tcx VariantDef, + variant_layout: TyAndLayout<'tcx>, + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + self.allocate_fill_and_write_slice_ptr( + place, + variant_def.fields.len() as u64, + |this, i, place| { + let field_def = &variant_def.fields[FieldIdx::from_usize(i as usize)]; + let field_ty = field_def.ty(*this.tcx, generics); + this.write_field(field_ty, place, variant_layout, Some(field_def.name), i) + }, + ) + } + + fn write_generics( + &mut self, + place: impl Writeable<'tcx, CtfeProvenance>, + generics: &'tcx GenericArgs<'tcx>, + ) -> InterpResult<'tcx> { + self.allocate_fill_and_write_slice_ptr(place, generics.len() as u64, |this, i, place| { + match generics[i as usize].kind() { + GenericArgKind::Lifetime(region) => this.write_generic_lifetime(region, place), + GenericArgKind::Type(ty) => this.write_generic_type(ty, place), + GenericArgKind::Const(c) => this.write_generic_const(c, place), + } + }) + } + + fn write_generic_lifetime( + &mut self, + _region: Region<'tcx>, + place: MPlaceTy<'tcx>, + ) -> InterpResult<'tcx> { + let (variant_idx, _) = self.downcast(&place, sym::Lifetime)?; + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } + + fn write_generic_type(&mut self, ty: Ty<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { + let (variant_idx, variant_place) = self.downcast(&place, sym::Type)?; + let generic_type_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + for (field_idx, field_def) in generic_type_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&generic_type_place, field_idx)?; + match field_def.name { + sym::ty => self.write_type_id(ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } + + fn write_generic_const(&mut self, c: Const<'tcx>, place: MPlaceTy<'tcx>) -> InterpResult<'tcx> { + let ConstKind::Value(c) = c.kind() else { bug!("expected a computed const, got {c:?}") }; + + let (variant_idx, variant_place) = self.downcast(&place, sym::Const)?; + let const_place = self.project_field(&variant_place, FieldIdx::ZERO)?; + + for (field_idx, field_def) in const_place + .layout() + .ty + .ty_adt_def() + .unwrap() + .non_enum_variant() + .fields + .iter_enumerated() + { + let field_place = self.project_field(&const_place, field_idx)?; + match field_def.name { + sym::ty => self.write_type_id(c.ty, &field_place)?, + other => span_bug!(self.tcx.def_span(field_def.did), "unimplemented field {other}"), + } + } + + self.write_discriminant(variant_idx, &place)?; + interp_ok(()) + } +} diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 7c41258ebfe5..b771addb8df5 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -36,13 +36,17 @@ fn branches<'tcx>( // For enums, we prepend their variant index before the variant's fields so we can figure out // the variant again when just seeing a valtree. if let Some(variant) = variant { - branches.push(ty::ValTree::from_scalar_int(*ecx.tcx, variant.as_u32().into())); + branches.push(ty::Const::new_value( + *ecx.tcx, + ty::ValTree::from_scalar_int(*ecx.tcx, variant.as_u32().into()), + ecx.tcx.types.u32, + )); } for i in 0..field_count { let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap(); let valtree = const_to_valtree_inner(ecx, &field, num_nodes)?; - branches.push(valtree); + branches.push(ty::Const::new_value(*ecx.tcx, valtree, field.layout.ty)); } // Have to account for ZSTs here @@ -65,7 +69,7 @@ fn slice_branches<'tcx>( for i in 0..n { let place_elem = ecx.project_index(place, i).unwrap(); let valtree = const_to_valtree_inner(ecx, &place_elem, num_nodes)?; - elems.push(valtree); + elems.push(ty::Const::new_value(*ecx.tcx, valtree, place_elem.layout.ty)); } Ok(ty::ValTree::from_branches(*ecx.tcx, elems)) @@ -200,8 +204,8 @@ fn reconstruct_place_meta<'tcx>( &ObligationCause::dummy(), |ty| ty, || { - let branches = last_valtree.unwrap_branch(); - last_valtree = *branches.last().unwrap(); + let branches = last_valtree.to_branch(); + last_valtree = branches.last().unwrap().to_value().valtree; debug!(?branches, ?last_valtree); }, ); @@ -212,7 +216,7 @@ fn reconstruct_place_meta<'tcx>( }; // Get the number of elements in the unsized field. - let num_elems = last_valtree.unwrap_branch().len(); + let num_elems = last_valtree.to_branch().len(); MemPlaceMeta::Meta(Scalar::from_target_usize(num_elems as u64, &tcx)) } @@ -274,7 +278,7 @@ pub fn valtree_to_const_value<'tcx>( mir::ConstValue::ZeroSized } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(_, _) => { - mir::ConstValue::Scalar(Scalar::Int(cv.valtree.unwrap_leaf())) + mir::ConstValue::Scalar(Scalar::Int(cv.to_leaf())) } ty::Pat(ty, _) => { let cv = ty::Value { valtree: cv.valtree, ty }; @@ -301,12 +305,13 @@ pub fn valtree_to_const_value<'tcx>( || matches!(cv.ty.kind(), ty::Adt(def, _) if def.is_struct())) { // A Scalar tuple/struct; we can avoid creating an allocation. - let branches = cv.valtree.unwrap_branch(); + let branches = cv.to_branch(); // Find the non-ZST field. (There can be aligned ZST!) for (i, &inner_valtree) in branches.iter().enumerate() { let field = layout.field(&LayoutCx::new(tcx, typing_env), i); if !field.is_zst() { - let cv = ty::Value { valtree: inner_valtree, ty: field.ty }; + let cv = + ty::Value { valtree: inner_valtree.to_value().valtree, ty: field.ty }; return valtree_to_const_value(tcx, typing_env, cv); } } @@ -381,7 +386,7 @@ fn valtree_into_mplace<'tcx>( // Zero-sized type, nothing to do. } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char | ty::RawPtr(..) => { - let scalar_int = valtree.unwrap_leaf(); + let scalar_int = valtree.to_leaf(); debug!("writing trivial valtree {:?} to place {:?}", scalar_int, place); ecx.write_immediate(Immediate::Scalar(scalar_int.into()), place).unwrap(); } @@ -391,13 +396,13 @@ fn valtree_into_mplace<'tcx>( ecx.write_immediate(imm, place).unwrap(); } ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str | ty::Slice(_) => { - let branches = valtree.unwrap_branch(); + let branches = valtree.to_branch(); // Need to downcast place for enums let (place_adjusted, branches, variant_idx) = match ty.kind() { ty::Adt(def, _) if def.is_enum() => { // First element of valtree corresponds to variant - let scalar_int = branches[0].unwrap_leaf(); + let scalar_int = branches[0].to_leaf(); let variant_idx = VariantIdx::from_u32(scalar_int.to_u32()); let variant = def.variant(variant_idx); debug!(?variant); @@ -425,7 +430,7 @@ fn valtree_into_mplace<'tcx>( }; debug!(?place_inner); - valtree_into_mplace(ecx, &place_inner, *inner_valtree); + valtree_into_mplace(ecx, &place_inner, inner_valtree.to_value().valtree); dump_place(ecx, &place_inner); } diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 50f5448ec20a..6a33a9ae0597 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -5,7 +5,8 @@ use either::Either; use rustc_abi::WrappingRange; use rustc_errors::codes::*; use rustc_errors::{ - Diag, DiagArgValue, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan, Subdiagnostic, + Diag, DiagArgValue, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan, + Subdiagnostic, msg, }; use rustc_hir::ConstContext; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -17,11 +18,18 @@ use rustc_middle::mir::interpret::{ use rustc_middle::ty::{self, Mutability, Ty}; use rustc_span::{Span, Symbol}; -use crate::fluent_generated as fluent; use crate::interpret::InternKind; #[derive(Diagnostic)] -#[diag(const_eval_dangling_ptr_in_final)] +#[diag( + r#"encountered dangling pointer in final value of {$kind -> + [static] static + [static_mut] mutable static + [const] constant + [promoted] promoted + *[other] {""} +}"# +)] pub(crate) struct DanglingPtrInFinal { #[primary_span] pub span: Span, @@ -29,14 +37,24 @@ pub(crate) struct DanglingPtrInFinal { } #[derive(Diagnostic)] -#[diag(const_eval_nested_static_in_thread_local)] +#[diag( + "#[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead" +)] pub(crate) struct NestedStaticInThreadLocal { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(const_eval_mutable_ptr_in_final)] +#[diag( + r#"encountered mutable pointer in final value of {$kind -> + [static] static + [static_mut] mutable static + [const] constant + [promoted] promoted + *[other] {""} +}"# +)] pub(crate) struct MutablePtrInFinal { #[primary_span] pub span: Span, @@ -44,16 +62,28 @@ pub(crate) struct MutablePtrInFinal { } #[derive(Diagnostic)] -#[diag(const_eval_const_heap_ptr_in_final)] -#[note] +#[diag("encountered `const_allocate` pointer in final value that was not made global")] +#[note( + "use `const_make_global` to turn allocated pointers into immutable globals before returning" +)] pub(crate) struct ConstHeapPtrInFinal { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(const_eval_partial_pointer_in_final)] -#[note] +#[diag( + r#"encountered partial pointer in final value of {$kind -> + [static] static + [static_mut] mutable static + [const] constant + [promoted] promoted + *[other] {""} +}"# +)] +#[note( + "while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value" +)] pub(crate) struct PartialPtrInFinal { #[primary_span] pub span: Span, @@ -61,17 +91,24 @@ pub(crate) struct PartialPtrInFinal { } #[derive(Diagnostic)] -#[diag(const_eval_unstable_in_stable_exposed)] +#[diag( + "const function that might be (indirectly) exposed to stable cannot use `#[feature({$gate})]`" +)] pub(crate) struct UnstableInStableExposed { pub gate: String, #[primary_span] pub span: Span, - #[help(const_eval_is_function_call)] + #[help( + "mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unstable features" + )] pub is_function_call: bool, /// Need to duplicate the field so that fluent also provides it as a variable... pub is_function_call2: bool, #[suggestion( - const_eval_unstable_sugg, + "if the {$is_function_call2 -> + [true] caller + *[false] function + } is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`", code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n", applicability = "has-placeholders" )] @@ -79,38 +116,47 @@ pub(crate) struct UnstableInStableExposed { } #[derive(Diagnostic)] -#[diag(const_eval_thread_local_access, code = E0625)] +#[diag("thread-local statics cannot be accessed at compile-time", code = E0625)] pub(crate) struct ThreadLocalAccessErr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(const_eval_raw_ptr_to_int)] -#[note] -#[note(const_eval_note2)] +#[diag("pointers cannot be cast to integers during const eval")] +#[note("at compile-time, pointers do not have an integer value")] +#[note( + "avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior" +)] pub(crate) struct RawPtrToIntErr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(const_eval_raw_ptr_comparison)] -#[note] +#[diag("pointers cannot be reliably compared during const eval")] +#[note("see issue #53020 for more information")] pub(crate) struct RawPtrComparisonErr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(const_eval_panic_non_str)] +#[diag("argument to `panic!()` in a const context must have type `&str`")] pub(crate) struct PanicNonStrErr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(const_eval_unallowed_fn_pointer_call)] +#[diag( + r#"function pointer calls are not allowed in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"# +)] pub(crate) struct UnallowedFnPointerCall { #[primary_span] pub span: Span, @@ -118,7 +164,7 @@ pub(crate) struct UnallowedFnPointerCall { } #[derive(Diagnostic)] -#[diag(const_eval_unstable_const_fn)] +#[diag("`{$def_path}` is not yet stable as a const fn")] pub(crate) struct UnstableConstFn { #[primary_span] pub span: Span, @@ -126,7 +172,7 @@ pub(crate) struct UnstableConstFn { } #[derive(Diagnostic)] -#[diag(const_eval_unstable_const_trait)] +#[diag("`{$def_path}` is not yet stable as a const trait")] pub(crate) struct UnstableConstTrait { #[primary_span] pub span: Span, @@ -134,14 +180,14 @@ pub(crate) struct UnstableConstTrait { } #[derive(Diagnostic)] -#[diag(const_eval_unstable_intrinsic)] +#[diag("`{$name}` is not yet stable as a const intrinsic")] pub(crate) struct UnstableIntrinsic { #[primary_span] pub span: Span, pub name: Symbol, pub feature: Symbol, #[suggestion( - const_eval_unstable_intrinsic_suggestion, + "add `#![feature({$feature})]` to the crate attributes to enable", code = "#![feature({feature})]\n", applicability = "machine-applicable" )] @@ -149,8 +195,10 @@ pub(crate) struct UnstableIntrinsic { } #[derive(Diagnostic)] -#[diag(const_eval_unmarked_const_item_exposed)] -#[help] +#[diag("`{$def_path}` cannot be (indirectly) exposed to stable")] +#[help( + "either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`" +)] pub(crate) struct UnmarkedConstItemExposed { #[primary_span] pub span: Span, @@ -158,8 +206,10 @@ pub(crate) struct UnmarkedConstItemExposed { } #[derive(Diagnostic)] -#[diag(const_eval_unmarked_intrinsic_exposed)] -#[help] +#[diag("intrinsic `{$def_path}` cannot be (indirectly) exposed to stable")] +#[help( + "mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_intrinsic_const_stable_indirect]` (but this requires team approval)" +)] pub(crate) struct UnmarkedIntrinsicExposed { #[primary_span] pub span: Span, @@ -167,19 +217,31 @@ pub(crate) struct UnmarkedIntrinsicExposed { } #[derive(Diagnostic)] -#[diag(const_eval_mutable_borrow_escaping, code = E0764)] -#[note] -#[note(const_eval_note2)] -#[help] +#[diag("mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed", code = E0764)] +#[note( + "temporaries in constants and statics can have their lifetime extended until the end of the program" +)] +#[note("to avoid accidentally creating global mutable state, such temporaries must be immutable")] +#[help( + "if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`" +)] pub(crate) struct MutableBorrowEscaping { #[primary_span] - #[label] + #[label("this mutable borrow refers to such a temporary")] pub span: Span, pub kind: ConstContext, } #[derive(Diagnostic)] -#[diag(const_eval_non_const_fmt_macro_call, code = E0015)] +#[diag( + r#"cannot call {$non_or_conditionally}-const formatting macro in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, + code = E0015, +)] pub(crate) struct NonConstFmtMacroCall { #[primary_span] pub span: Span, @@ -188,7 +250,12 @@ pub(crate) struct NonConstFmtMacroCall { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_fn_call, code = E0015)] +#[diag(r#"cannot call {$non_or_conditionally}-const {$def_descr} `{$def_path_str}` in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub(crate) struct NonConstFnCall { #[primary_span] pub span: Span, @@ -199,7 +266,14 @@ pub(crate) struct NonConstFnCall { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_intrinsic)] +#[diag( + r#"cannot call non-const intrinsic `{$name}` in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"# +)] pub(crate) struct NonConstIntrinsic { #[primary_span] pub span: Span, @@ -208,7 +282,7 @@ pub(crate) struct NonConstIntrinsic { } #[derive(Diagnostic)] -#[diag(const_eval_unallowed_op_in_const_context)] +#[diag("{$msg}")] pub(crate) struct UnallowedOpInConstContext { #[primary_span] pub span: Span, @@ -216,18 +290,12 @@ pub(crate) struct UnallowedOpInConstContext { } #[derive(Diagnostic)] -#[diag(const_eval_unallowed_heap_allocations, code = E0010)] -pub(crate) struct UnallowedHeapAllocations { - #[primary_span] - #[label] - pub span: Span, - pub kind: ConstContext, - #[note(const_eval_teach_note)] - pub teach: bool, -} - -#[derive(Diagnostic)] -#[diag(const_eval_unallowed_inline_asm, code = E0015)] +#[diag(r#"inline assembly is not allowed in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub(crate) struct UnallowedInlineAsm { #[primary_span] pub span: Span, @@ -235,39 +303,46 @@ pub(crate) struct UnallowedInlineAsm { } #[derive(Diagnostic)] -#[diag(const_eval_interior_mutable_borrow_escaping, code = E0492)] -#[note] -#[note(const_eval_note2)] -#[help] +#[diag("interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed", code = E0492)] +#[note( + "temporaries in constants and statics can have their lifetime extended until the end of the program" +)] +#[note("to avoid accidentally creating global mutable state, such temporaries must be immutable")] +#[help( + "if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`" +)] pub(crate) struct InteriorMutableBorrowEscaping { #[primary_span] - #[label] + #[label("this borrow of an interior mutable value refers to such a temporary")] pub span: Span, pub kind: ConstContext, } #[derive(LintDiagnostic)] -#[diag(const_eval_long_running)] -#[note] +#[diag("constant evaluation is taking a long time")] +#[note( + "this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. + If your compilation actually takes a long time, you can safely allow the lint" +)] pub struct LongRunning { - #[help] + #[help("the constant being evaluated")] pub item_span: Span, } #[derive(Diagnostic)] -#[diag(const_eval_long_running)] +#[diag("constant evaluation is taking a long time")] pub struct LongRunningWarn { #[primary_span] - #[label] + #[label("the const evaluator is currently interpreting this expression")] pub span: Span, - #[help] + #[help("the constant being evaluated")] pub item_span: Span, // Used for evading `-Z deduplicate-diagnostics`. pub force_duplicate: usize, } #[derive(Subdiagnostic)] -#[note(const_eval_non_const_impl)] +#[note("impl defined here, but it is not `const`")] pub(crate) struct NonConstImplNote { #[primary_span] pub span: Span, @@ -289,9 +364,22 @@ impl Subdiagnostic for FrameNote { diag.arg("instance", self.instance); let mut span: MultiSpan = self.span.into(); if self.has_label && !self.span.is_dummy() { - span.push_span_label(self.span, fluent::const_eval_frame_note_last); + span.push_span_label(self.span, msg!("the failure occurred here")); } - let msg = diag.eagerly_translate(fluent::const_eval_frame_note); + let msg = diag.eagerly_translate(msg!( + r#"{$times -> + [0] inside {$where_ -> + [closure] closure + [instance] `{$instance}` + *[other] {""} + } + *[other] [... {$times} additional calls inside {$where_ -> + [closure] closure + [instance] `{$instance}` + *[other] {""} + } ...] + }"# + )); diag.remove_arg("times"); diag.remove_arg("where_"); diag.remove_arg("instance"); @@ -300,7 +388,7 @@ impl Subdiagnostic for FrameNote { } #[derive(Subdiagnostic)] -#[note(const_eval_raw_bytes)] +#[note(r#"the raw bytes of the constant (size: {$size}, align: {$align}) {"{"}{$bytes}{"}"}"#)] pub struct RawBytesNote { pub size: u64, pub align: u64, @@ -310,8 +398,15 @@ pub struct RawBytesNote { // FIXME(fee1-dead) do not use stringly typed `ConstContext` #[derive(Diagnostic)] -#[diag(const_eval_non_const_match_eq, code = E0015)] -#[note] +#[diag( + r#"cannot match on `{$ty}` in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"# +)] +#[note("`{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es")] pub struct NonConstMatchEq<'tcx> { #[primary_span] pub span: Span, @@ -321,7 +416,12 @@ pub struct NonConstMatchEq<'tcx> { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_for_loop_into_iter, code = E0015)] +#[diag(r#"cannot use `for` loop on `{$ty}` in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub struct NonConstForLoopIntoIter<'tcx> { #[primary_span] pub span: Span, @@ -331,7 +431,12 @@ pub struct NonConstForLoopIntoIter<'tcx> { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_question_branch, code = E0015)] +#[diag(r#"`?` is not allowed on `{$ty}` in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub struct NonConstQuestionBranch<'tcx> { #[primary_span] pub span: Span, @@ -341,7 +446,12 @@ pub struct NonConstQuestionBranch<'tcx> { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_question_from_residual, code = E0015)] +#[diag(r#"`?` is not allowed on `{$ty}` in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub struct NonConstQuestionFromResidual<'tcx> { #[primary_span] pub span: Span, @@ -351,7 +461,12 @@ pub struct NonConstQuestionFromResidual<'tcx> { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_try_block_from_output, code = E0015)] +#[diag(r#"`try` block cannot convert `{$ty}` to the result in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub struct NonConstTryBlockFromOutput<'tcx> { #[primary_span] pub span: Span, @@ -361,7 +476,12 @@ pub struct NonConstTryBlockFromOutput<'tcx> { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_await, code = E0015)] +#[diag(r#"cannot convert `{$ty}` into a future in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub struct NonConstAwait<'tcx> { #[primary_span] pub span: Span, @@ -371,7 +491,12 @@ pub struct NonConstAwait<'tcx> { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_closure, code = E0015)] +#[diag(r#"cannot call {$non_or_conditionally}-const closure in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub struct NonConstClosure { #[primary_span] pub span: Span, @@ -381,21 +506,48 @@ pub struct NonConstClosure { pub non_or_conditionally: &'static str, } +#[derive(Diagnostic)] +#[diag(r#"calling const c-variadic functions is unstable in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] +pub struct NonConstCVariadicCall { + #[primary_span] + pub span: Span, + pub kind: ConstContext, +} + #[derive(Subdiagnostic)] pub enum NonConstClosureNote { - #[note(const_eval_closure_fndef_not_const)] + #[note("function defined here, but it is not `const`")] FnDef { #[primary_span] span: Span, }, - #[note(const_eval_fn_ptr_call)] + #[note( + r#"function pointers need an RFC before allowed to be called in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} + }s"# + )] FnPtr, - #[note(const_eval_closure_call)] + #[note( + r#"closures need an RFC before allowed to be called in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} + }s"# + )] Closure, } #[derive(Subdiagnostic)] -#[multipart_suggestion(const_eval_consider_dereferencing, applicability = "machine-applicable")] +#[multipart_suggestion("consider dereferencing here", applicability = "machine-applicable")] pub struct ConsiderDereferencing { pub deref: String, #[suggestion_part(code = "{deref}")] @@ -405,7 +557,12 @@ pub struct ConsiderDereferencing { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_operator, code = E0015)] +#[diag(r#"cannot call {$non_or_conditionally}-const operator in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] pub struct NonConstOperator { #[primary_span] pub span: Span, @@ -416,28 +573,40 @@ pub struct NonConstOperator { } #[derive(Diagnostic)] -#[diag(const_eval_non_const_deref_coercion, code = E0015)] -#[note] +#[diag(r#"cannot perform {$non_or_conditionally}-const deref coercion on `{$ty}` in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} +}s"#, code = E0015)] +#[note("attempting to deref into `{$target_ty}`")] pub struct NonConstDerefCoercion<'tcx> { #[primary_span] pub span: Span, pub ty: Ty<'tcx>, pub kind: ConstContext, pub target_ty: Ty<'tcx>, - #[note(const_eval_target_note)] + #[note("deref defined here")] pub deref_target: Option, pub non_or_conditionally: &'static str, } #[derive(Diagnostic)] -#[diag(const_eval_live_drop, code = E0493)] +#[diag("destructor of `{$dropped_ty}` cannot be evaluated at compile-time", code = E0493)] pub struct LiveDrop<'tcx> { #[primary_span] - #[label] + #[label( + r#"the destructor for this type cannot be evaluated in {$kind -> + [const] constant + [static] static + [const_fn] constant function + *[other] {""} + }s"# + )] pub span: Span, pub kind: ConstContext, pub dropped_ty: Ty<'tcx>, - #[label(const_eval_dropped_at_label)] + #[label("value is dropped here")] pub dropped_at: Span, } @@ -466,51 +635,140 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { fn diagnostic_message(&self) -> DiagMessage { use UndefinedBehaviorInfo::*; - use crate::fluent_generated::*; match self { Ub(msg) => msg.clone().into(), Custom(x) => (x.msg)(), ValidationError(e) => e.diagnostic_message(), - Unreachable => const_eval_unreachable, - BoundsCheckFailed { .. } => const_eval_bounds_check_failed, - DivisionByZero => const_eval_division_by_zero, - RemainderByZero => const_eval_remainder_by_zero, - DivisionOverflow => const_eval_division_overflow, - RemainderOverflow => const_eval_remainder_overflow, - PointerArithOverflow => const_eval_pointer_arithmetic_overflow, - ArithOverflow { .. } => const_eval_overflow_arith, - ShiftOverflow { .. } => const_eval_overflow_shift, - InvalidMeta(InvalidMetaKind::SliceTooBig) => const_eval_invalid_meta_slice, - InvalidMeta(InvalidMetaKind::TooBig) => const_eval_invalid_meta, - UnterminatedCString(_) => const_eval_unterminated_c_string, - PointerUseAfterFree(_, _) => const_eval_pointer_use_after_free, - PointerOutOfBounds { .. } => const_eval_pointer_out_of_bounds, - DanglingIntPointer { addr: 0, .. } => const_eval_dangling_null_pointer, - DanglingIntPointer { .. } => const_eval_dangling_int_pointer, - AlignmentCheckFailed { .. } => const_eval_alignment_check_failed, - WriteToReadOnly(_) => const_eval_write_to_read_only, - DerefFunctionPointer(_) => const_eval_deref_function_pointer, - DerefVTablePointer(_) => const_eval_deref_vtable_pointer, - DerefTypeIdPointer(_) => const_eval_deref_typeid_pointer, - InvalidBool(_) => const_eval_invalid_bool, - InvalidChar(_) => const_eval_invalid_char, - InvalidTag(_) => const_eval_invalid_tag, - InvalidFunctionPointer(_) => const_eval_invalid_function_pointer, - InvalidVTablePointer(_) => const_eval_invalid_vtable_pointer, - InvalidVTableTrait { .. } => const_eval_invalid_vtable_trait, - InvalidStr(_) => const_eval_invalid_str, - InvalidUninitBytes(None) => const_eval_invalid_uninit_bytes_unknown, - InvalidUninitBytes(Some(_)) => const_eval_invalid_uninit_bytes, - DeadLocal => const_eval_dead_local, - ScalarSizeMismatch(_) => const_eval_scalar_size_mismatch, - UninhabitedEnumVariantWritten(_) => const_eval_uninhabited_enum_variant_written, - UninhabitedEnumVariantRead(_) => const_eval_uninhabited_enum_variant_read, + Unreachable => "entering unreachable code".into(), + BoundsCheckFailed { .. } => msg!("indexing out of bounds: the len is {$len} but the index is {$index}"), + DivisionByZero => "dividing by zero".into(), + RemainderByZero => "calculating the remainder with a divisor of zero".into(), + DivisionOverflow => "overflow in signed division (dividing MIN by -1)".into(), + RemainderOverflow => "overflow in signed remainder (dividing MIN by -1)".into(), + PointerArithOverflow => "overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`".into(), + ArithOverflow { .. } => msg!("arithmetic overflow in `{$intrinsic}`"), + ShiftOverflow { .. } => msg!("overflowing shift by {$shift_amount} in `{$intrinsic}`"), + InvalidMeta(InvalidMetaKind::SliceTooBig) => "invalid metadata in wide pointer: slice is bigger than largest supported object".into(), + InvalidMeta(InvalidMetaKind::TooBig) => "invalid metadata in wide pointer: total size is bigger than largest supported object".into(), + UnterminatedCString(_) => "reading a null-terminated string starting at {$pointer} with no null found before end of allocation".into(), + PointerUseAfterFree(_, _) => msg!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$alloc_id} has been freed, so this pointer is dangling" + ), + PointerOutOfBounds { .. } => msg!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got {$pointer} which {$ptr_offset_is_neg -> + [true] points to before the beginning of the allocation + *[false] {$inbounds_size_is_neg -> + [false] {$alloc_size_minus_ptr_offset -> + [0] is at or beyond the end of the allocation of size {$alloc_size -> + [1] 1 byte + *[x] {$alloc_size} bytes + } + [1] is only 1 byte from the end of the allocation + *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation + } + *[true] {$ptr_offset_abs -> + [0] is at the beginning of the allocation + *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation + } + } + }" + ), + DanglingIntPointer { addr: 0, .. } => msg!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got null pointer"), + DanglingIntPointer { .. } => msg!( + "{$operation -> + [MemoryAccess] memory access failed + [InboundsPointerArithmetic] in-bounds pointer arithmetic failed + *[Dereferenceable] pointer not dereferenceable + }: {$operation -> + [MemoryAccess] attempting to access {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size -> + [1] 1 byte + *[x] {$inbounds_size} bytes + } + *[Dereferenceable] pointer must {$inbounds_size -> + [0] point to some allocation + [1] be dereferenceable for 1 byte + *[x] be dereferenceable for {$inbounds_size} bytes + } + }, but got {$pointer} which is a dangling pointer (it has no provenance)"), + AlignmentCheckFailed { .. } => msg!( + "{$msg -> + [AccessedPtr] accessing memory + *[other] accessing memory based on pointer + } with alignment {$has}, but alignment {$required} is required" + ), + WriteToReadOnly(_) => msg!("writing to {$allocation} which is read-only"), + DerefFunctionPointer(_) => msg!("accessing {$allocation} which contains a function"), + DerefVTablePointer(_) => msg!("accessing {$allocation} which contains a vtable"), + DerefVaListPointer(_) => msg!("accessing {$allocation} which contains a variable argument list"), + DerefTypeIdPointer(_) => msg!("accessing {$allocation} which contains a `TypeId`"), + InvalidBool(_) => msg!("interpreting an invalid 8-bit value as a bool: 0x{$value}"), + InvalidChar(_) => msg!("interpreting an invalid 32-bit value as a char: 0x{$value}"), + InvalidTag(_) => msg!("enum value has invalid tag: {$tag}"), + InvalidFunctionPointer(_) => msg!("using {$pointer} as function pointer but it does not point to a function"), + InvalidVaListPointer(_) => msg!("using {$pointer} as variable argument list pointer but it does not point to a variable argument list"), + InvalidVTablePointer(_) => msg!("using {$pointer} as vtable pointer but it does not point to a vtable"), + InvalidVTableTrait { .. } => msg!("using vtable for `{$vtable_dyn_type}` but `{$expected_dyn_type}` was expected"), + InvalidStr(_) => msg!("this string is not valid UTF-8: {$err}"), + InvalidUninitBytes(None) => "using uninitialized data, but this operation requires initialized memory".into(), + InvalidUninitBytes(Some(_)) => msg!("reading memory at {$alloc}{$access}, but memory is uninitialized at {$uninit}, and this operation requires initialized memory"), + DeadLocal => "accessing a dead local variable".into(), + ScalarSizeMismatch(_) => msg!("scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead"), + UninhabitedEnumVariantWritten(_) => "writing discriminant of an uninhabited enum variant".into(), + UninhabitedEnumVariantRead(_) => "read discriminant of an uninhabited enum variant".into(), InvalidNichedEnumVariantWritten { .. } => { - const_eval_invalid_niched_enum_variant_written + msg!("trying to set discriminant of a {$ty} to the niched variant, but the value does not match") } - AbiMismatchArgument { .. } => const_eval_incompatible_arg_types, - AbiMismatchReturn { .. } => const_eval_incompatible_return_types, + AbiMismatchArgument { .. } => msg!("calling a function whose parameter #{$arg_idx} has type {$callee_ty} passing argument of type {$caller_ty}"), + AbiMismatchReturn { .. } => msg!("calling a function with return type {$callee_ty} passing return place of type {$caller_ty}"), + VaArgOutOfBounds => "more C-variadic arguments read than were passed".into(), + CVariadicMismatch { ..} => "calling a function where the caller and callee disagree on whether the function is C-variadic".into(), + CVariadicFixedCountMismatch { .. } => msg!("calling a C-variadic function with {$caller} fixed arguments, but the function expects {$callee}"), } } @@ -535,6 +793,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { | InvalidMeta(InvalidMetaKind::TooBig) | InvalidUninitBytes(None) | DeadLocal + | VaArgOutOfBounds | UninhabitedEnumVariantWritten(_) | UninhabitedEnumVariantRead(_) => {} @@ -555,7 +814,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { diag.arg("len", len); diag.arg("index", index); } - UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => { + UnterminatedCString(ptr) + | InvalidFunctionPointer(ptr) + | InvalidVaListPointer(ptr) + | InvalidVTablePointer(ptr) => { diag.arg("pointer", ptr); } InvalidVTableTrait { expected_dyn_type, vtable_dyn_type } => { @@ -609,6 +871,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) + | DerefVaListPointer(alloc) | DerefTypeIdPointer(alloc) => { diag.arg("allocation", alloc); } @@ -645,6 +908,14 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> { diag.arg("caller_ty", caller_ty); diag.arg("callee_ty", callee_ty); } + CVariadicMismatch { caller_is_c_variadic, callee_is_c_variadic } => { + diag.arg("caller_is_c_variadic", caller_is_c_variadic); + diag.arg("callee_is_c_variadic", callee_is_c_variadic); + } + CVariadicFixedCountMismatch { caller, callee } => { + diag.arg("caller", caller); + diag.arg("callee", callee); + } } } } @@ -653,94 +924,174 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { fn diagnostic_message(&self) -> DiagMessage { use rustc_middle::mir::interpret::ValidationErrorKind::*; - use crate::fluent_generated::*; match self.kind { PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => { - const_eval_validation_box_to_uninhabited + msg!("{$front_matter}: encountered a box pointing to uninhabited type {$ty}") } PtrToUninhabited { ptr_kind: PointerKind::Ref(_), .. } => { - const_eval_validation_ref_to_uninhabited + msg!("{$front_matter}: encountered a reference pointing to uninhabited type {$ty}") } - PointerAsInt { .. } => const_eval_validation_pointer_as_int, - PartialPointer => const_eval_validation_partial_pointer, - MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable, - NullFnPtr { .. } => const_eval_validation_null_fn_ptr, - NeverVal => const_eval_validation_never_val, - NonnullPtrMaybeNull { .. } => const_eval_validation_nonnull_ptr_out_of_range, - PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range, - OutOfRange { .. } => const_eval_validation_out_of_range, - UnsafeCellInImmutable => const_eval_validation_unsafe_cell, - UninhabitedVal { .. } => const_eval_validation_uninhabited_val, - InvalidEnumTag { .. } => const_eval_validation_invalid_enum_tag, - UninhabitedEnumVariant => const_eval_validation_uninhabited_enum_variant, - Uninit { .. } => const_eval_validation_uninit, - InvalidVTablePtr { .. } => const_eval_validation_invalid_vtable_ptr, - InvalidMetaWrongTrait { .. } => const_eval_validation_invalid_vtable_trait, + PointerAsInt { .. } => { + msg!("{$front_matter}: encountered a pointer, but {$expected}") + } + PartialPointer => { + msg!("{$front_matter}: encountered a partial pointer or a mix of pointers") + } + MutableRefToImmutable => { + msg!( + "{$front_matter}: encountered mutable reference or box pointing to read-only memory" + ) + } + NullFnPtr { .. } => { + msg!( + "{$front_matter}: encountered a {$maybe -> + [true] maybe-null + *[false] null + } function pointer" + ) + } + NeverVal => { + msg!("{$front_matter}: encountered a value of the never type `!`") + } + NonnullPtrMaybeNull { .. } => { + msg!( + "{$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero" + ) + } + PtrOutOfRange { .. } => { + msg!( + "{$front_matter}: encountered a pointer with unknown absolute address, but expected something that is definitely {$in_range}" + ) + } + OutOfRange { .. } => { + msg!("{$front_matter}: encountered {$value}, but expected something {$in_range}") + } + UnsafeCellInImmutable => { + msg!("{$front_matter}: encountered `UnsafeCell` in read-only memory") + } + UninhabitedVal { .. } => { + msg!("{$front_matter}: encountered a value of uninhabited type `{$ty}`") + } + InvalidEnumTag { .. } => { + msg!("{$front_matter}: encountered {$value}, but expected a valid enum tag") + } + UninhabitedEnumVariant => { + msg!("{$front_matter}: encountered an uninhabited enum variant") + } + Uninit { .. } => { + msg!("{$front_matter}: encountered uninitialized memory, but {$expected}") + } + InvalidVTablePtr { .. } => { + msg!("{$front_matter}: encountered {$value}, but expected a vtable pointer") + } + InvalidMetaWrongTrait { .. } => { + msg!( + "{$front_matter}: wrong trait in wide pointer vtable: expected `{$expected_dyn_type}`, but encountered `{$vtable_dyn_type}`" + ) + } InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => { - const_eval_validation_invalid_box_slice_meta + msg!( + "{$front_matter}: encountered invalid box metadata: slice is bigger than largest supported object" + ) } InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref(_) } => { - const_eval_validation_invalid_ref_slice_meta + msg!( + "{$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object" + ) } InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => { - const_eval_validation_invalid_box_meta + msg!( + "{$front_matter}: encountered invalid box metadata: total size is bigger than largest supported object" + ) } InvalidMetaTooLarge { ptr_kind: PointerKind::Ref(_) } => { - const_eval_validation_invalid_ref_meta + msg!( + "{$front_matter}: encountered invalid reference metadata: total size is bigger than largest supported object" + ) } UnalignedPtr { ptr_kind: PointerKind::Ref(_), .. } => { - const_eval_validation_unaligned_ref + msg!( + "{$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})" + ) + } + UnalignedPtr { ptr_kind: PointerKind::Box, .. } => { + msg!( + "{$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})" + ) } - UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box, - NullPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_null_box, - NullPtr { ptr_kind: PointerKind::Ref(_), .. } => const_eval_validation_null_ref, + NullPtr { ptr_kind: PointerKind::Box, .. } => { + msg!( + "{$front_matter}: encountered a {$maybe -> + [true] maybe-null + *[false] null + } box" + ) + } + NullPtr { ptr_kind: PointerKind::Ref(_), .. } => { + msg!( + "{$front_matter}: encountered a {$maybe -> + [true] maybe-null + *[false] null + } reference" + ) + } DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => { - const_eval_validation_dangling_box_no_provenance + msg!("{$front_matter}: encountered a dangling box ({$pointer} has no provenance)") } DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref(_), .. } => { - const_eval_validation_dangling_ref_no_provenance + msg!( + "{$front_matter}: encountered a dangling reference ({$pointer} has no provenance)" + ) } DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => { - const_eval_validation_dangling_box_out_of_bounds + msg!( + "{$front_matter}: encountered a dangling box (going beyond the bounds of its allocation)" + ) } DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref(_) } => { - const_eval_validation_dangling_ref_out_of_bounds + msg!( + "{$front_matter}: encountered a dangling reference (going beyond the bounds of its allocation)" + ) } DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => { - const_eval_validation_dangling_box_use_after_free + msg!("{$front_matter}: encountered a dangling box (use-after-free)") } DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(_) } => { - const_eval_validation_dangling_ref_use_after_free + msg!("{$front_matter}: encountered a dangling reference (use-after-free)") + } + InvalidBool { .. } => { + msg!("{$front_matter}: encountered {$value}, but expected a boolean") + } + InvalidChar { .. } => { + msg!( + "{$front_matter}: encountered {$value}, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)" + ) + } + InvalidFnPtr { .. } => { + msg!("{$front_matter}: encountered {$value}, but expected a function pointer") } - InvalidBool { .. } => const_eval_validation_invalid_bool, - InvalidChar { .. } => const_eval_validation_invalid_char, - InvalidFnPtr { .. } => const_eval_validation_invalid_fn_ptr, } } fn add_args(self, err: &mut Diag<'_, G>) { + use rustc_errors::msg; use rustc_middle::mir::interpret::ValidationErrorKind::*; - use crate::fluent_generated as fluent; - if let PointerAsInt { .. } | PartialPointer = self.kind { - err.help(fluent::const_eval_ptr_as_bytes_1); - err.help(fluent::const_eval_ptr_as_bytes_2); + err.help(msg!("this code performed an operation that depends on the underlying bytes representing a pointer")); + err.help(msg!("the absolute address of a pointer is not known at compile-time, so such operations are not supported")); } let message = if let Some(path) = self.path { err.dcx.eagerly_translate_to_string( - fluent::const_eval_validation_front_matter_invalid_value_with_path, + msg!("constructing invalid value at {$path}"), [("path".into(), DiagArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)), ) } else { - err.dcx.eagerly_translate_to_string( - fluent::const_eval_validation_front_matter_invalid_value, - [].into_iter(), - ) + err.dcx.eagerly_translate_to_string(msg!("constructing invalid value"), [].into_iter()) }; err.arg("front_matter", message); @@ -753,17 +1104,17 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { let WrappingRange { start: lo, end: hi } = r; assert!(hi <= max_hi); let msg = if lo > hi { - fluent::const_eval_range_wrapping + msg!("less or equal to {$hi}, or greater or equal to {$lo}") } else if lo == hi { - fluent::const_eval_range_singular + msg!("equal to {$lo}") } else if lo == 0 { assert!(hi < max_hi, "should not be printing if the range covers everything"); - fluent::const_eval_range_upper + msg!("less or equal to {$hi}") } else if hi == max_hi { assert!(lo > 0, "should not be printing if the range covers everything"); - fluent::const_eval_range_lower + msg!("greater or equal to {$lo}") } else { - fluent::const_eval_range + msg!("in the range {$lo}..={$hi}") }; let args = [ @@ -781,17 +1132,17 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { } PointerAsInt { expected } | Uninit { expected } => { let msg = match expected { - ExpectedKind::Reference => fluent::const_eval_validation_expected_ref, - ExpectedKind::Box => fluent::const_eval_validation_expected_box, - ExpectedKind::RawPtr => fluent::const_eval_validation_expected_raw_ptr, - ExpectedKind::InitScalar => fluent::const_eval_validation_expected_init_scalar, - ExpectedKind::Bool => fluent::const_eval_validation_expected_bool, - ExpectedKind::Char => fluent::const_eval_validation_expected_char, - ExpectedKind::Float => fluent::const_eval_validation_expected_float, - ExpectedKind::Int => fluent::const_eval_validation_expected_int, - ExpectedKind::FnPtr => fluent::const_eval_validation_expected_fn_ptr, - ExpectedKind::EnumTag => fluent::const_eval_validation_expected_enum_tag, - ExpectedKind::Str => fluent::const_eval_validation_expected_str, + ExpectedKind::Reference => msg!("expected a reference"), + ExpectedKind::Box => msg!("expected a box"), + ExpectedKind::RawPtr => msg!("expected a raw pointer"), + ExpectedKind::InitScalar => msg!("expected initialized scalar value"), + ExpectedKind::Bool => msg!("expected a boolean"), + ExpectedKind::Char => msg!("expected a unicode scalar value"), + ExpectedKind::Float => msg!("expected a floating point number"), + ExpectedKind::Int => msg!("expected an integer"), + ExpectedKind::FnPtr => msg!("expected a function pointer"), + ExpectedKind::EnumTag => msg!("expected a valid enum tag"), + ExpectedKind::Str => msg!("expected a string"), }; let msg = err.dcx.eagerly_translate_to_string(msg, [].into_iter()); err.arg("expected", msg); @@ -838,25 +1189,32 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { impl ReportErrorExt for UnsupportedOpInfo { fn diagnostic_message(&self) -> DiagMessage { - use crate::fluent_generated::*; match self { UnsupportedOpInfo::Unsupported(s) => s.clone().into(), - UnsupportedOpInfo::ExternTypeField => const_eval_extern_type_field, - UnsupportedOpInfo::UnsizedLocal => const_eval_unsized_local, - UnsupportedOpInfo::ReadPartialPointer(_) => const_eval_partial_pointer_read, - UnsupportedOpInfo::ReadPointerAsInt(_) => const_eval_read_pointer_as_int, - UnsupportedOpInfo::ThreadLocalStatic(_) => const_eval_thread_local_static, - UnsupportedOpInfo::ExternStatic(_) => const_eval_extern_static, + UnsupportedOpInfo::ExternTypeField => { + "`extern type` field does not have a known offset".into() + } + UnsupportedOpInfo::UnsizedLocal => "unsized locals are not supported".into(), + UnsupportedOpInfo::ReadPartialPointer(_) => { + msg!("unable to read parts of a pointer from memory at {$ptr}") + } + UnsupportedOpInfo::ReadPointerAsInt(_) => "unable to turn pointer into integer".into(), + UnsupportedOpInfo::ThreadLocalStatic(_) => { + msg!("cannot access thread local static `{$did}`") + } + UnsupportedOpInfo::ExternStatic(_) => { + msg!("cannot access extern static `{$did}`") + } } + .into() } fn add_args(self, diag: &mut Diag<'_, G>) { use UnsupportedOpInfo::*; - use crate::fluent_generated::*; if let ReadPointerAsInt(_) | ReadPartialPointer(_) = self { - diag.help(const_eval_ptr_as_bytes_1); - diag.help(const_eval_ptr_as_bytes_2); + diag.help("this code performed an operation that depends on the underlying bytes representing a pointer"); + diag.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported"); } match self { // `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to @@ -901,10 +1259,12 @@ impl<'tcx> ReportErrorExt for InterpErrorKind<'tcx> { impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { fn diagnostic_message(&self) -> DiagMessage { - use crate::fluent_generated::*; match self { - InvalidProgramInfo::TooGeneric => const_eval_too_generic, - InvalidProgramInfo::AlreadyReported(_) => const_eval_already_reported, + InvalidProgramInfo::TooGeneric => "encountered overly generic constant".into(), + InvalidProgramInfo::AlreadyReported(_) => { + "an error has already been reported elsewhere (this should not usually be printed)" + .into() + } InvalidProgramInfo::Layout(e) => e.diagnostic_message(), } } @@ -926,13 +1286,19 @@ impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> { impl ReportErrorExt for ResourceExhaustionInfo { fn diagnostic_message(&self) -> DiagMessage { - use crate::fluent_generated::*; match self { - ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached, - ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted, - ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full, - ResourceExhaustionInfo::Interrupted => const_eval_interrupted, + ResourceExhaustionInfo::StackFrameLimitReached => { + "reached the configured maximum number of stack frames" + } + ResourceExhaustionInfo::MemoryExhausted => { + "tried to allocate more memory than available to compiler" + } + ResourceExhaustionInfo::AddressSpaceFull => { + "there are no more free addresses in the address space" + } + ResourceExhaustionInfo::Interrupted => "compilation was interrupted", } + .into() } fn add_args(self, _: &mut Diag<'_, G>) {} } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 312ebe7ddd09..9220fde474e4 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -1,26 +1,29 @@ //! Manages calling a concrete function (with known MIR body) with argument passing, //! and returning the return value to the caller. -use std::assert_matches::assert_matches; + use std::borrow::Cow; use either::{Left, Right}; use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx}; +use rustc_data_structures::assert_matches; +use rustc_errors::msg; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::DefId; +use rustc_hir::find_attr; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef}; use rustc_middle::{bug, mir, span_bug}; -use rustc_span::sym; use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; use tracing::field::Empty; use tracing::{info, instrument, trace}; use super::{ CtfeProvenance, FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, - Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, StackPopInfo, interp_ok, - throw_ub, throw_ub_custom, throw_unsup_format, + Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, interp_ok, throw_ub, + throw_ub_custom, }; +use crate::enter_trace_span; use crate::interpret::EnteredTraceSpan; -use crate::{enter_trace_span, fluent_generated as fluent}; /// An argument passed to a function. #[derive(Clone, Debug)] @@ -40,25 +43,22 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> { FnArg::InPlace(mplace) => &mplace.layout, } } -} -impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the /// original memory occurs. - pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> { - match arg { + pub fn copy_fn_arg(&self) -> OpTy<'tcx, Prov> { + match self { FnArg::Copy(op) => op.clone(), FnArg::InPlace(mplace) => mplace.clone().into(), } } +} +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Make a copy of the given fn_args. Any `InPlace` are degenerated to copies, no protection of the /// original memory occurs. - pub fn copy_fn_args( - &self, - args: &[FnArg<'tcx, M::Provenance>], - ) -> Vec> { - args.iter().map(|fn_arg| self.copy_fn_arg(fn_arg)).collect() + pub fn copy_fn_args(args: &[FnArg<'tcx, M::Provenance>]) -> Vec> { + args.iter().map(|fn_arg| fn_arg.copy_fn_arg()).collect() } /// Helper function for argument untupling. @@ -89,6 +89,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let (_, field) = layout.non_1zst_field(self).unwrap(); self.unfold_transparent(field, may_unfold) } + ty::Pat(base, _) => self.layout_of(*base).expect( + "if the layout of a pattern type could be computed, so can the layout of its base", + ), // Not a transparent type, no further unfolding. _ => layout, } @@ -140,7 +143,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Check if the inner type is one of the NPO-guaranteed ones. // For that we first unpeel transparent *structs* (but not unions). let is_npo = |def: AdtDef<'tcx>| { - self.tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed) + find_attr!( + self.tcx.get_all_attrs(def.did()), + AttributeKind::RustcNonnullOptimizationGuaranteed + ) }; let inner = self.unfold_transparent(inner, /* may_unfold */ |def| { // Stop at NPO types so that we don't miss that attribute in the check below! @@ -283,7 +289,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { 'tcx: 'y, { assert_eq!(callee_ty, callee_abi.layout.ty); - if matches!(callee_abi.mode, PassMode::Ignore) { + if callee_abi.mode == PassMode::Ignore { // This one is skipped. Still must be made live though! if !already_live { self.storage_live(callee_arg.as_local().unwrap())?; @@ -292,7 +298,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // Find next caller arg. let Some((caller_arg, caller_abi)) = caller_args.next() else { - throw_ub_custom!(fluent::const_eval_not_enough_caller_args); + throw_ub_custom!(msg!("calling a function with fewer arguments than it requires")); }; assert_eq!(caller_arg.layout().layout, caller_abi.layout.layout); // Sadly we cannot assert that `caller_arg.layout().ty` and `caller_abi.layout.ty` are @@ -310,7 +316,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // We work with a copy of the argument for now; if this is in-place argument passing, we // will later protect the source it comes from. This means the callee cannot observe if we // did in-place of by-copy argument passing, except for pointer equality tests. - let caller_arg_copy = self.copy_fn_arg(caller_arg); + let caller_arg_copy = caller_arg.copy_fn_arg(); if !already_live { let local = callee_arg.as_local().unwrap(); let meta = caller_arg_copy.meta(); @@ -349,22 +355,42 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> InterpResult<'tcx> { let _trace = enter_trace_span!(M, step::init_stack_frame, %instance, tracing_separate_thread = Empty); - // Compute callee information. - // FIXME: for variadic support, do we have to somehow determine callee's extra_args? - let callee_fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?; - - if callee_fn_abi.c_variadic || caller_fn_abi.c_variadic { - throw_unsup_format!("calling a c-variadic function is not supported"); - } + // The first order of business is to figure out the callee signature. + // However, that requires the list of variadic arguments. + // We use the *caller* information to determine where to split the list of arguments, + // and then later check that the callee indeed has the same number of fixed arguments. + let extra_tys = if caller_fn_abi.c_variadic { + let fixed_count = usize::try_from(caller_fn_abi.fixed_count).unwrap(); + let extra_tys = args[fixed_count..].iter().map(|arg| arg.layout().ty); + self.tcx.mk_type_list_from_iter(extra_tys) + } else { + ty::List::empty() + }; + let callee_fn_abi = self.fn_abi_of_instance(instance, extra_tys)?; if caller_fn_abi.conv != callee_fn_abi.conv { throw_ub_custom!( - fluent::const_eval_incompatible_calling_conventions, + rustc_errors::msg!( + "calling a function with calling convention \"{$callee_conv}\" using calling convention \"{$caller_conv}\"" + ), callee_conv = format!("{}", callee_fn_abi.conv), caller_conv = format!("{}", caller_fn_abi.conv), ) } + if caller_fn_abi.c_variadic != callee_fn_abi.c_variadic { + throw_ub!(CVariadicMismatch { + caller_is_c_variadic: caller_fn_abi.c_variadic, + callee_is_c_variadic: callee_fn_abi.c_variadic, + }); + } + if caller_fn_abi.c_variadic && caller_fn_abi.fixed_count != callee_fn_abi.fixed_count { + throw_ub!(CVariadicFixedCountMismatch { + caller: caller_fn_abi.fixed_count, + callee: callee_fn_abi.fixed_count, + }); + } + // Check that all target features required by the callee (i.e., from // the attribute `#[target_feature(enable = ...)]`) are enabled at // compile time. @@ -437,6 +463,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `pass_argument` would be the loop body. It takes care to // not advance `caller_iter` for ignored arguments. let mut callee_args_abis = callee_fn_abi.args.iter().enumerate(); + // Determine whether there is a special VaList argument. This is always the + // last argument, and since arguments start at index 1 that's `arg_count`. + let va_list_arg = + callee_fn_abi.c_variadic.then(|| mir::Local::from_usize(body.arg_count)); for local in body.args_iter() { // Construct the destination place for this argument. At this point all // locals are still dead, so we cannot construct a `PlaceTy`. @@ -445,7 +475,31 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // type, but the result gets cached so this avoids calling the instantiation // query *again* the next time this local is accessed. let ty = self.layout_of_local(self.frame(), local, None)?.ty; - if Some(local) == body.spread_arg { + if Some(local) == va_list_arg { + // This is the last callee-side argument of a variadic function. + // This argument is a VaList holding the remaining caller-side arguments. + self.storage_live(local)?; + + let place = self.eval_place(dest)?; + let mplace = self.force_allocation(&place)?; + + // Consume the remaining arguments by putting them into the variable argument + // list. + let varargs = self.allocate_varargs(&mut caller_args, &mut callee_args_abis)?; + // When the frame is dropped, these variable arguments are deallocated. + self.frame_mut().va_list = varargs.clone(); + let key = self.va_list_ptr(varargs.into()); + + // Zero the VaList, so it is fully initialized. + self.write_bytes_ptr( + mplace.ptr(), + (0..mplace.layout.size.bytes()).map(|_| 0u8), + )?; + + // Store the "key" pointer in the right field. + let key_mplace = self.va_list_key_field(&mplace)?; + self.write_pointer(key, &key_mplace)?; + } else if Some(local) == body.spread_arg { // Make the local live once, then fill in the value field by field. self.storage_live(local)?; // Must be a tuple @@ -484,13 +538,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if instance.def.requires_caller_location(*self.tcx) { callee_args_abis.next().unwrap(); } - // Now we should have no more caller args or callee arg ABIs + // Now we should have no more caller args or callee arg ABIs. assert!( callee_args_abis.next().is_none(), "mismatch between callee ABI and callee body arguments" ); if caller_args.next().is_some() { - throw_ub_custom!(fluent::const_eval_too_many_caller_args); + throw_ub_custom!(msg!("calling a function with more arguments than it expected")); } // Don't forget to check the return type! if !self.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)? { @@ -559,7 +613,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if let Some(fallback) = M::call_intrinsic( self, instance, - &self.copy_fn_args(args), + &Self::copy_fn_args(args), destination, target, unwind, @@ -646,7 +700,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // An `InPlace` does nothing here, we keep the original receiver intact. We can't // really pass the argument in-place anyway, and we are constructing a new // `Immediate` receiver. - let mut receiver = self.copy_fn_arg(&args[0]); + let mut receiver = args[0].copy_fn_arg(); let receiver_place = loop { match receiver.layout.ty.kind() { ty::Ref(..) | ty::RawPtr(..) => { @@ -690,7 +744,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let vtable_entries = self.vtable_entries(receiver_trait.principal(), dyn_ty); let Some(ty::VtblEntry::Method(fn_inst)) = vtable_entries.get(idx).copied() else { // FIXME(fee1-dead) these could be variants of the UB info enum instead of this - throw_ub_custom!(fluent::const_eval_dyn_call_not_a_method); + throw_ub_custom!(msg!( + "`dyn` call trying to call something that is not a method" + )); }; trace!("Virtual call dispatches to {fn_inst:#?}"); // We can also do the lookup based on `def_id` and `dyn_ty`, and check that that @@ -765,41 +821,50 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { with_caller_location: bool, ) -> InterpResult<'tcx> { trace!("init_fn_tail_call: {:#?}", fn_val); - // This is the "canonical" implementation of tails calls, // a pop of the current stack frame, followed by a normal call // which pushes a new stack frame, with the return address from // the popped stack frame. // - // Note that we are using `pop_stack_frame_raw` and not `return_from_current_stack_frame`, - // as the latter "executes" the goto to the return block, but we don't want to, + // Note that we cannot use `return_from_current_stack_frame`, + // as that "executes" the goto to the return block, but we don't want to, // only the tail called function should return to the current return block. - let StackPopInfo { return_action, return_cont, return_place } = - self.pop_stack_frame_raw(false, |_this, _return_place| { - // This function's return value is just discarded, the tail-callee will fill in the return place instead. - interp_ok(()) - })?; - assert_eq!(return_action, ReturnAction::Normal); - - // Take the "stack pop cleanup" info, and use that to initiate the next call. - let ReturnContinuation::Goto { ret, unwind } = return_cont else { - bug!("can't tailcall as root"); + // The arguments need to all be copied since the current stack frame will be removed + // before the callee even starts executing. + // FIXME(explicit_tail_calls,#144855): does this match what codegen does? + let args = args.iter().map(|fn_arg| FnArg::Copy(fn_arg.copy_fn_arg())).collect::>(); + // Remove the frame from the stack. + let frame = self.pop_stack_frame_raw()?; + // Remember where this frame would have returned to. + let ReturnContinuation::Goto { ret, unwind } = frame.return_cont() else { + bug!("can't tailcall as root of the stack"); }; - + // There's no return value to deal with! Instead, we forward the old return place + // to the new function. // FIXME(explicit_tail_calls): // we should check if both caller&callee can/n't unwind, // see + // Now push the new stack frame. self.init_fn_call( fn_val, (caller_abi, caller_fn_abi), - args, + &*args, with_caller_location, - &return_place, + frame.return_place(), ret, unwind, - ) + )?; + + // Finally, clear the local variables. Has to be done after pushing to support + // non-scalar arguments. + // FIXME(explicit_tail_calls,#144855): revisit this once codegen supports indirect + // arguments, to ensure the semantics are compatible. + let return_action = self.cleanup_stack_frame(/* unwinding */ false, frame)?; + assert_eq!(return_action, ReturnAction::Normal); + + interp_ok(()) } pub(super) fn init_drop_in_place_call( @@ -887,21 +952,25 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } ); if unwinding && self.frame_idx() == 0 { - throw_ub_custom!(fluent::const_eval_unwind_past_top); + throw_ub_custom!(msg!("unwinding past the topmost frame of the stack")); } // Get out the return value. Must happen *before* the frame is popped as we have to get the // local's value out. let return_op = self.local_to_op(mir::RETURN_PLACE, None).expect("return place should always be live"); - // Do the actual pop + copy. - let stack_pop_info = self.pop_stack_frame_raw(unwinding, |this, return_place| { - this.copy_op_allow_transmute(&return_op, return_place)?; - trace!("return value: {:?}", this.dump_place(return_place)); - interp_ok(()) - })?; - - match stack_pop_info.return_action { + // Remove the frame from the stack. + let frame = self.pop_stack_frame_raw()?; + // Copy the return value and remember the return continuation. + if !unwinding { + self.copy_op_allow_transmute(&return_op, frame.return_place())?; + trace!("return value: {:?}", self.dump_place(frame.return_place())); + } + let return_cont = frame.return_cont(); + // Finish popping the stack frame. + let return_action = self.cleanup_stack_frame(unwinding, frame)?; + // Jump to the next block. + match return_action { ReturnAction::Normal => {} ReturnAction::NoJump => { // The hook already did everything. @@ -919,7 +988,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Normal return, figure out where to jump. if unwinding { // Follow the unwind edge. - match stack_pop_info.return_cont { + match return_cont { ReturnContinuation::Goto { unwind, .. } => { // This must be the very last thing that happens, since it can in fact push a new stack frame. self.unwind_to_block(unwind) @@ -930,7 +999,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } else { // Follow the normal return edge. - match stack_pop_info.return_cont { + match return_cont { ReturnContinuation::Goto { ret, .. } => self.return_to_block(ret), ReturnContinuation::Stop { .. } => { assert!( diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 3485a5c625ba..6ea83167157c 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,8 +1,8 @@ -use std::assert_matches::assert_matches; - use rustc_abi::{FieldIdx, Integer}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, FloatConvert}; +use rustc_data_structures::assert_matches; +use rustc_errors::msg; use rustc_middle::mir::CastKind; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::ty::adjustment::PointerCoercion; @@ -16,8 +16,8 @@ use super::{ FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy, err_inval, interp_ok, throw_ub, throw_ub_custom, }; +use crate::enter_trace_span; use crate::interpret::Writeable; -use crate::{enter_trace_span, fluent_generated as fluent}; impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn cast( @@ -139,7 +139,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { assert_eq!(cast_ty, dest.layout.ty); // we otherwise ignore `cast_ty` enirely... if src.layout.size != dest.layout.size { throw_ub_custom!( - fluent::const_eval_invalid_transmute, + msg!( + "transmuting from {$src_bytes}-byte type to {$dest_bytes}-byte type: `{$src}` -> `{$dest}`" + ), src_bytes = src.layout.size.bytes(), dest_bytes = dest.layout.size.bytes(), src = src.layout.ty, diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d23369caffa4..c2f772d56075 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -1,8 +1,7 @@ -use std::assert_matches::debug_assert_matches; - use either::{Left, Right}; use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout}; -use rustc_errors::DiagCtxtHandle; +use rustc_data_structures::debug_assert_matches; +use rustc_errors::{DiagCtxtHandle, msg}; use rustc_hir::def_id::DefId; use rustc_hir::limit::Limit; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; @@ -24,7 +23,7 @@ use super::{ MemPlaceMeta, Memory, OpTy, Place, PlaceTy, PointerArithmetic, Projectable, Provenance, err_inval, interp_ok, throw_inval, throw_ub, throw_ub_custom, }; -use crate::{ReportErrorExt, enter_trace_span, fluent_generated as fluent, util}; +use crate::{ReportErrorExt, enter_trace_span, util}; pub struct InterpCx<'tcx, M: Machine<'tcx>> { /// Stores the `Machine` instance. @@ -233,7 +232,6 @@ pub fn format_interp_error<'tcx>(dcx: DiagCtxtHandle<'_>, e: InterpErrorInfo<'tc backtrace.print_backtrace(); // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the // label and arguments from the InterpError. - #[allow(rustc::untranslatable_diagnostic)] let mut diag = dcx.struct_allow(""); let msg = e.diagnostic_message(); e.add_args(&mut diag); @@ -557,7 +555,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { mir::UnwindAction::Cleanup(block) => Left(mir::Location { block, statement_index: 0 }), mir::UnwindAction::Continue => Right(self.frame_mut().body.span), mir::UnwindAction::Unreachable => { - throw_ub_custom!(fluent::const_eval_unreachable_unwind); + throw_ub_custom!(msg!( + "unwinding past a stack frame that does not allow unwinding" + )); } mir::UnwindAction::Terminate(reason) => { self.frame_mut().loc = Right(self.frame_mut().body.span); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index a7a3bbebed5f..e0c75da87a4b 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -4,26 +4,29 @@ mod simd; -use std::assert_matches::assert_matches; - -use rustc_abi::{FieldIdx, HasDataLayout, Size, VariantIdx}; +use rustc_abi::{FIRST_VARIANT, FieldIdx, HasDataLayout, Size, VariantIdx}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; +use rustc_data_structures::assert_matches; +use rustc_errors::msg; +use rustc_hir::def_id::CRATE_DEF_ID; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{FloatTy, Ty, TyCtxt}; +use rustc_middle::ty::{FloatTy, PolyExistentialPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug, ty}; use rustc_span::{Symbol, sym}; +use rustc_trait_selection::traits::{Obligation, ObligationCause, ObligationCtxt}; use tracing::trace; use super::memory::MemoryKind; use super::util::ensure_monomorphic_enough; use super::{ AllocId, CheckInAllocMsg, ImmTy, InterpCx, InterpResult, Machine, OpTy, PlaceTy, Pointer, - PointerArithmetic, Provenance, Scalar, err_ub_custom, err_unsup_format, interp_ok, throw_inval, - throw_ub_custom, throw_ub_format, + PointerArithmetic, Projectable, Provenance, Scalar, err_ub_custom, err_unsup_format, interp_ok, + throw_inval, throw_ub, throw_ub_custom, throw_ub_format, throw_unsup_format, }; -use crate::fluent_generated as fluent; +use crate::interpret::Writeable; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum MulAddType { @@ -65,11 +68,16 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (AllocId } impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Generates a value of `TypeId` for `ty` in-place. - fn write_type_id( + pub(crate) fn write_type_id( &mut self, ty: Ty<'tcx>, - dest: &PlaceTy<'tcx, M::Provenance>, + dest: &impl Writeable<'tcx, M::Provenance>, ) -> InterpResult<'tcx, ()> { + debug_assert!( + !ty.has_erasable_regions(), + "type {ty:?} has regions that need erasing before writing a TypeId", + ); + let tcx = self.tcx; let type_id_hash = tcx.type_id_hash(ty).as_u128(); let op = self.const_val_to_op( @@ -219,6 +227,44 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(Scalar::from_target_usize(offset, self), dest)?; } + sym::vtable_for => { + let tp_ty = instance.args.type_at(0); + let result_ty = instance.args.type_at(1); + + ensure_monomorphic_enough(tcx, tp_ty)?; + ensure_monomorphic_enough(tcx, result_ty)?; + let ty::Dynamic(preds, _) = result_ty.kind() else { + span_bug!( + self.find_closest_untracked_caller_location(), + "Invalid type provided to vtable_for::. U must be dyn Trait, got {result_ty}." + ); + }; + + let (infcx, param_env) = + self.tcx.infer_ctxt().build_with_typing_env(self.typing_env); + + let ocx = ObligationCtxt::new(&infcx); + ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| { + let pred = pred.with_self_ty(tcx, tp_ty); + // Lifetimes can only be 'static because of the bound on T + let pred = ty::fold_regions(tcx, pred, |r, _| { + if r == tcx.lifetimes.re_erased { tcx.lifetimes.re_static } else { r } + }); + Obligation::new(tcx, ObligationCause::dummy(), param_env, pred) + })); + let type_impls_trait = ocx.evaluate_obligations_error_on_ambiguity().is_empty(); + // Since `assumed_wf_tys=[]` the choice of LocalDefId is irrelevant, so using the "default" + let regions_are_valid = ocx.resolve_regions(CRATE_DEF_ID, param_env, []).is_empty(); + + if regions_are_valid && type_impls_trait { + let vtable_ptr = self.get_vtable_ptr(tp_ty, preds)?; + // Writing a non-null pointer into an `Option` will automatically make it `Some`. + self.write_pointer(vtable_ptr, dest)?; + } else { + // Write `None` + self.write_discriminant(FIRST_VARIANT, dest)?; + } + } sym::variant_count => { let tp_ty = instance.args.type_at(0); let ty = match tp_ty.kind() { @@ -397,7 +443,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { _ => { // Not into the same allocation -- this is UB. throw_ub_custom!( - fluent::const_eval_offset_from_different_allocations, + msg!( + "`{$name}` called on two different pointers that are not both derived from the same allocation" + ), name = intrinsic_name, ); } @@ -418,7 +466,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // a < b if intrinsic_name == sym::ptr_offset_from_unsigned { throw_ub_custom!( - fluent::const_eval_offset_from_unsigned_overflow, + msg!( + "`ptr_offset_from_unsigned` called when first pointer has smaller {$is_addr -> + [true] address + *[false] offset + } than second: {$a_offset} < {$b_offset}" + ), a_offset = a_offset, b_offset = b_offset, is_addr = is_addr, @@ -430,7 +483,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let dist = val.to_target_isize(self)?; if dist >= 0 || i128::from(dist) == self.pointer_size().signed_int_min() { throw_ub_custom!( - fluent::const_eval_offset_from_underflow, + msg!( + "`{$name}` called when first pointer is too far before second" + ), name = intrinsic_name, ); } @@ -442,7 +497,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // because they were more than isize::MAX apart. if dist < 0 { throw_ub_custom!( - fluent::const_eval_offset_from_overflow, + msg!( + "`{$name}` called when first pointer is too far ahead of second" + ), name = intrinsic_name, ); } @@ -461,12 +518,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { && a_alloc_id == b_alloc_id { err_ub_custom!( - fluent::const_eval_offset_from_out_of_bounds, + msg!("`{$name}` called on two different pointers where the memory range between them is not in-bounds of an allocation"), name = intrinsic_name, ) } else { err_ub_custom!( - fluent::const_eval_offset_from_different_allocations, + msg!("`{$name}` called on two different pointers that are not both derived from the same allocation"), name = intrinsic_name, ) } @@ -481,7 +538,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .map_err_kind(|_| { // Make the error more specific. err_ub_custom!( - fluent::const_eval_offset_from_different_allocations, + msg!("`{$name}` called on two different pointers that are not both derived from the same allocation"), name = intrinsic_name, ) })?; @@ -693,6 +750,57 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.float_muladd_intrinsic::(args, dest, MulAddType::Nondeterministic)? } + sym::va_copy => { + let va_list = self.deref_pointer(&args[0])?; + let key_mplace = self.va_list_key_field(&va_list)?; + let key = self.read_pointer(&key_mplace)?; + + let varargs = self.get_ptr_va_list(key)?; + let copy_key = self.va_list_ptr(varargs.clone()); + + let copy_key_mplace = self.va_list_key_field(dest)?; + self.write_pointer(copy_key, ©_key_mplace)?; + } + + sym::va_end => { + let va_list = self.deref_pointer(&args[0])?; + let key_mplace = self.va_list_key_field(&va_list)?; + let key = self.read_pointer(&key_mplace)?; + + self.deallocate_va_list(key)?; + } + + sym::va_arg => { + let va_list = self.deref_pointer(&args[0])?; + let key_mplace = self.va_list_key_field(&va_list)?; + let key = self.read_pointer(&key_mplace)?; + + // Invalidate the old list and get its content. We'll recreate the + // new list (one element shorter) below. + let mut varargs = self.deallocate_va_list(key)?; + + let Some(arg_mplace) = varargs.pop_front() else { + throw_ub!(VaArgOutOfBounds); + }; + + // NOTE: In C some type conversions are allowed (e.g. casting between signed and + // unsigned integers). For now we require c-variadic arguments to be read with the + // exact type they were passed as. + if arg_mplace.layout.ty != dest.layout.ty { + throw_unsup_format!( + "va_arg type mismatch: requested `{}`, but next argument is `{}`", + dest.layout.ty, + arg_mplace.layout.ty + ); + } + // Copy the argument. + self.copy_op(&arg_mplace, dest)?; + + // Update the VaList pointer. + let new_key = self.va_list_ptr(varargs); + self.write_pointer(new_key, &key_mplace)?; + } + // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), } @@ -711,7 +819,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let op = self.eval_operand(op, None)?; let cond = self.read_scalar(&op)?.to_bool()?; if !cond { - throw_ub_custom!(fluent::const_eval_assume_false); + throw_ub_custom!(msg!("`assume` called with `false`")); } interp_ok(()) } @@ -741,7 +849,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let bits_out = match name { sym::ctpop => u128::from(bits.count_ones()), sym::ctlz_nonzero | sym::cttz_nonzero if bits == 0 => { - throw_ub_custom!(fluent::const_eval_call_nonzero_intrinsic, name = name,); + throw_ub_custom!(msg!("`{$name}` called on 0"), name = name,); } sym::ctlz | sym::ctlz_nonzero => u128::from(bits.leading_zeros()) - extra, sym::cttz | sym::cttz_nonzero => u128::from((bits << extra).trailing_zeros()) - extra, @@ -774,7 +882,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // sign does not matter for 0 test, so `to_bits` is fine if rem.to_scalar().to_bits(a.layout.size)? != 0 { throw_ub_custom!( - fluent::const_eval_exact_div_has_remainder, + msg!("exact_div: {$a} cannot be divided by {$b} without remainder"), a = format!("{a}"), b = format!("{b}") ) @@ -815,7 +923,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } else { // unsigned - if matches!(mir_op, BinOp::Add) { + if mir_op == BinOp::Add { // max unsigned Scalar::from_uint(size.unsigned_int_max(), size) } else { @@ -859,7 +967,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let size = self.compute_size_in_bytes(size, count).ok_or_else(|| { err_ub_custom!( - fluent::const_eval_size_overflow, + msg!("overflow computing total size of `{$name}`"), name = if nonoverlapping { "copy_nonoverlapping" } else { "copy" } ) })?; @@ -922,9 +1030,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `checked_mul` enforces a too small bound (the correct one would probably be target_isize_max), // but no actual allocation can be big enough for the difference to be noticeable. - let len = self - .compute_size_in_bytes(layout.size, count) - .ok_or_else(|| err_ub_custom!(fluent::const_eval_size_overflow, name = name))?; + let len = self.compute_size_in_bytes(layout.size, count).ok_or_else(|| { + err_ub_custom!(msg!("overflow computing total size of `{$name}`"), name = name) + })?; let bytes = std::iter::repeat_n(byte, len.bytes_usize()); self.write_bytes_ptr(dst, bytes) @@ -1173,4 +1281,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(Some(ImmTy::from_scalar(val, cast_to))) } } + + /// Get the MPlace of the key from the place storing the VaList. + pub(super) fn va_list_key_field>( + &self, + va_list: &P, + ) -> InterpResult<'tcx, P> { + // The struct wrapped by VaList. + let va_list_inner = self.project_field(va_list, FieldIdx::ZERO)?; + + // Find the first pointer field in this struct. The exact index is target-specific. + let ty::Adt(adt, substs) = va_list_inner.layout().ty.kind() else { + bug!("invalid VaListImpl layout"); + }; + + for (i, field) in adt.non_enum_variant().fields.iter().enumerate() { + if field.ty(*self.tcx, substs).is_raw_ptr() { + return self.project_field(&va_list_inner, FieldIdx::from_usize(i)); + } + } + + bug!("no VaListImpl field is a pointer"); + } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs index 20de47683122..303183fd924d 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -2,6 +2,7 @@ use either::Either; use rustc_abi::{BackendRepr, Endian}; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, Round}; +use rustc_data_structures::assert_matches; use rustc_middle::mir::interpret::{InterpErrorKind, Pointer, UndefinedBehaviorInfo}; use rustc_middle::ty::{FloatTy, ScalarInt, SimdAlign}; use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty}; @@ -10,7 +11,7 @@ use tracing::trace; use super::{ ImmTy, InterpCx, InterpResult, Machine, MinMax, MulAddType, OpTy, PlaceTy, Provenance, Scalar, - Size, TyAndLayout, assert_matches, interp_ok, throw_ub_format, + Size, TyAndLayout, interp_ok, throw_ub_format, }; use crate::interpret::Writeable; @@ -29,7 +30,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let dest = dest.force_mplace(self)?; match intrinsic_name { - sym::simd_insert => { + sym::simd_insert | sym::simd_insert_dyn => { let index = u64::from(self.read_scalar(&args[1])?.to_u32()?); let elem = &args[2]; let (input, input_len) = self.project_to_simd(&args[0])?; @@ -38,7 +39,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Bounds are not checked by typeck so we have to do it ourselves. if index >= input_len { throw_ub_format!( - "`simd_insert` index {index} is out-of-bounds of vector with length {input_len}" + "`{intrinsic_name}` index {index} is out-of-bounds of vector with length {input_len}" ); } @@ -49,17 +50,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.copy_op(&value, &place)?; } } - sym::simd_extract => { + sym::simd_extract | sym::simd_extract_dyn => { let index = u64::from(self.read_scalar(&args[1])?.to_u32()?); let (input, input_len) = self.project_to_simd(&args[0])?; // Bounds are not checked by typeck so we have to do it ourselves. if index >= input_len { throw_ub_format!( - "`simd_extract` index {index} is out-of-bounds of vector with length {input_len}" + "`{intrinsic_name}` index {index} is out-of-bounds of vector with length {input_len}" ); } self.copy_op(&self.project_index(&input, index)?, &dest)?; } + sym::simd_splat => { + let elem = &args[0]; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + for i in 0..dest_len { + let place = self.project_index(&dest, i)?; + self.copy_op(elem, &place)?; + } + } sym::simd_neg | sym::simd_fabs | sym::simd_ceil @@ -545,7 +555,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let (right, right_len) = self.project_to_simd(&args[1])?; let (dest, dest_len) = self.project_to_simd(&dest)?; - let index = generic_args[2].expect_const().to_value().valtree.unwrap_branch(); + let index = generic_args[2].expect_const().to_branch(); let index_len = index.len(); assert_eq!(left_len, right_len); @@ -553,7 +563,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { for i in 0..dest_len { let src_index: u64 = - index[usize::try_from(i).unwrap()].unwrap_leaf().to_u32().into(); + index[usize::try_from(i).unwrap()].to_leaf().to_u32().into(); let dest = self.project_index(&dest, i)?; let val = if src_index < left_len { @@ -657,9 +667,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.check_simd_ptr_alignment( ptr, dest_layout, - generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(), + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(), )?; for i in 0..dest_len { @@ -689,9 +697,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.check_simd_ptr_alignment( ptr, args[2].layout, - generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] - .unwrap_leaf() - .to_simd_alignment(), + generic_args[3].expect_const().to_branch()[0].to_leaf().to_simd_alignment(), )?; for i in 0..vals_len { diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 753b2dd3b8ea..62ca47d23b4c 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -298,7 +298,7 @@ pub trait Machine<'tcx>: Sized { interp_ok(()) } - /// Determines the result of a `NullaryOp::RuntimeChecks` invocation. + /// Determines the result of a `Operand::RuntimeChecks` invocation. fn runtime_checks( _ecx: &InterpCx<'tcx, Self>, r: mir::RuntimeChecks, @@ -680,16 +680,6 @@ pub macro compile_time_machine(<$tcx: lifetime>) { true } - #[inline(always)] - fn runtime_checks( - _ecx: &InterpCx<$tcx, Self>, - _r: mir::RuntimeChecks, - ) -> InterpResult<$tcx, bool> { - // We can't look at `tcx.sess` here as that can differ across crates, which can lead to - // unsound differences in evaluating the same constant at different instantiation sites. - interp_ok(true) - } - #[inline(always)] fn adjust_global_allocation<'b>( _ecx: &InterpCx<$tcx, Self>, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index bac3a9da48d9..7b67d3acd555 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -6,7 +6,6 @@ //! integer. It is crucial that these operations call `check_align` *before* //! short-circuiting the empty case! -use std::assert_matches::assert_matches; use std::borrow::{Borrow, Cow}; use std::cell::Cell; use std::collections::VecDeque; @@ -14,7 +13,9 @@ use std::{fmt, ptr}; use rustc_abi::{Align, HasDataLayout, Size}; use rustc_ast::Mutability; +use rustc_data_structures::assert_matches; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; +use rustc_errors::msg; use rustc_middle::mir::display_allocation; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_middle::{bug, throw_ub_format}; @@ -22,12 +23,11 @@ use tracing::{debug, instrument, trace}; use super::{ AllocBytes, AllocId, AllocInit, AllocMap, AllocRange, Allocation, CheckAlignMsg, - CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, - Misalignment, Pointer, PointerArithmetic, Provenance, Scalar, alloc_range, err_ub, + CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, MPlaceTy, Machine, + MayLeak, Misalignment, Pointer, PointerArithmetic, Provenance, Scalar, alloc_range, err_ub, err_ub_custom, interp_ok, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format, }; use crate::const_eval::ConstEvalErrKind; -use crate::fluent_generated as fluent; #[derive(Debug, PartialEq, Copy, Clone)] pub enum MemoryKind { @@ -67,6 +67,8 @@ pub enum AllocKind { LiveData, /// A function allocation (that fn ptrs point to). Function, + /// A variable argument list allocation (used by c-variadic functions). + VaList, /// A vtable allocation. VTable, /// A TypeId allocation. @@ -126,6 +128,9 @@ pub struct Memory<'tcx, M: Machine<'tcx>> { /// Map for "extra" function pointers. extra_fn_ptr_map: FxIndexMap, + /// Map storing variable argument lists. + va_list_map: FxIndexMap>>, + /// To be able to compare pointers with null, and to check alignment for accesses /// to ZSTs (where pointers may dangle), we keep track of the size even for allocations /// that do not exist any more. @@ -161,6 +166,7 @@ impl<'tcx, M: Machine<'tcx>> Memory<'tcx, M> { Memory { alloc_map: M::MemoryMap::default(), extra_fn_ptr_map: FxIndexMap::default(), + va_list_map: FxIndexMap::default(), dead_alloc_map: FxIndexMap::default(), validation_in_progress: Cell::new(false), } @@ -199,9 +205,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return M::extern_static_pointer(self, def_id); } None => { + let is_fn_ptr = self.memory.extra_fn_ptr_map.contains_key(&alloc_id); + let is_va_list = self.memory.va_list_map.contains_key(&alloc_id); assert!( - self.memory.extra_fn_ptr_map.contains_key(&alloc_id), - "{alloc_id:?} is neither global nor a function pointer" + is_fn_ptr || is_va_list, + "{alloc_id:?} is neither global, va_list nor a function pointer" ); } _ => {} @@ -229,6 +237,19 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.global_root_pointer(Pointer::from(id)).unwrap() } + /// Insert a new variable argument list in the global map of variable argument lists. + pub fn va_list_ptr( + &mut self, + varargs: VecDeque>, + ) -> Pointer { + let id = self.tcx.reserve_alloc_id(); + let old = self.memory.va_list_map.insert(id, varargs); + assert!(old.is_none()); + // Variable argument lists are global allocations, so make sure we get the right root + // pointer. We know this is not an `extern static` so this cannot fail. + self.global_root_pointer(Pointer::from(id)).unwrap() + } + pub fn allocate_ptr( &mut self, size: Size, @@ -291,7 +312,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let (alloc_id, offset, _prov) = self.ptr_get_alloc_id(ptr, 0)?; if offset.bytes() != 0 { throw_ub_custom!( - fluent::const_eval_realloc_or_alloc_with_offset, + msg!( + "{$kind -> + [dealloc] deallocating + [realloc] reallocating + *[other] {\"\"} + } {$ptr} which does not point to the beginning of an object" + ), ptr = format!("{ptr:?}"), kind = "realloc" ); @@ -327,7 +354,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return Err(ConstEvalErrKind::ConstMakeGlobalWithOffset(ptr)).into(); } - if matches!(self.tcx.try_get_global_alloc(alloc_id), Some(_)) { + if self.tcx.try_get_global_alloc(alloc_id).is_some() { // This points to something outside the current interpreter. return Err(ConstEvalErrKind::ConstMakeGlobalPtrIsNonHeap(ptr)).into(); } @@ -371,7 +398,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if offset.bytes() != 0 { throw_ub_custom!( - fluent::const_eval_realloc_or_alloc_with_offset, + msg!( + "{$kind -> + [dealloc] deallocating + [realloc] reallocating + *[other] {\"\"} + } {$ptr} which does not point to the beginning of an object" + ), ptr = format!("{ptr:?}"), kind = "dealloc", ); @@ -382,28 +415,56 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return Err(match self.tcx.try_get_global_alloc(alloc_id) { Some(GlobalAlloc::Function { .. }) => { err_ub_custom!( - fluent::const_eval_invalid_dealloc, + msg!( + "deallocating {$alloc_id}, which is {$kind -> + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" + ), alloc_id = alloc_id, kind = "fn", ) } Some(GlobalAlloc::VTable(..)) => { err_ub_custom!( - fluent::const_eval_invalid_dealloc, + msg!( + "deallocating {$alloc_id}, which is {$kind -> + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" + ), alloc_id = alloc_id, kind = "vtable", ) } Some(GlobalAlloc::TypeId { .. }) => { err_ub_custom!( - fluent::const_eval_invalid_dealloc, + msg!( + "deallocating {$alloc_id}, which is {$kind -> + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" + ), alloc_id = alloc_id, kind = "typeid", ) } Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => { err_ub_custom!( - fluent::const_eval_invalid_dealloc, + msg!( + "deallocating {$alloc_id}, which is {$kind -> + [fn] a function + [vtable] a vtable + [static_mem] static memory + *[other] {\"\"} + }" + ), alloc_id = alloc_id, kind = "static_mem" ) @@ -414,11 +475,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }; if alloc.mutability.is_not() { - throw_ub_custom!(fluent::const_eval_dealloc_immutable, alloc = alloc_id,); + throw_ub_custom!(msg!("deallocating immutable allocation {$alloc}"), alloc = alloc_id,); } if alloc_kind != kind { throw_ub_custom!( - fluent::const_eval_dealloc_kind_mismatch, + msg!( + "deallocating {$alloc}, which is {$alloc_kind} memory, using {$kind} deallocation operation" + ), alloc = alloc_id, alloc_kind = format!("{alloc_kind}"), kind = format!("{kind}"), @@ -427,7 +490,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if let Some((size, align)) = old_size_and_align { if size != alloc.size() || align != alloc.align { throw_ub_custom!( - fluent::const_eval_dealloc_incorrect_layout, + msg!( + "incorrect layout on deallocation: {$alloc} has size {$size} and alignment {$align}, but gave size {$size_found} and alignment {$align_found}" + ), alloc = alloc_id, size = alloc.size().bytes(), align = alloc.align.bytes(), @@ -912,6 +977,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { pub fn is_alloc_live(&self, id: AllocId) -> bool { self.memory.alloc_map.contains_key_ref(&id) || self.memory.extra_fn_ptr_map.contains_key(&id) + || self.memory.va_list_map.contains_key(&id) // We check `tcx` last as that has to acquire a lock in `many-seeds` mode. // This also matches the order in `get_alloc_info`. || self.tcx.try_get_global_alloc(id).is_some() @@ -951,6 +1017,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return AllocInfo::new(Size::ZERO, align, AllocKind::Function, Mutability::Not); } + // # Variable argument lists + if self.memory.va_list_map.contains_key(&id) { + return AllocInfo::new(Size::ZERO, Align::ONE, AllocKind::VaList, Mutability::Not); + } + // # Global allocations if let Some(global_alloc) = self.tcx.try_get_global_alloc(id) { // NOTE: `static` alignment from attributes has already been applied to the allocation. @@ -981,7 +1052,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, (Size, Align)> { let info = self.get_alloc_info(id); - if matches!(info.kind, AllocKind::Dead) { + if info.kind == AllocKind::Dead { throw_ub!(PointerUseAfterFree(id, msg)) } interp_ok((info.size, info.align)) @@ -1025,6 +1096,43 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .into() } + pub fn get_ptr_va_list( + &self, + ptr: Pointer>, + ) -> InterpResult<'tcx, &VecDeque>> { + trace!("get_ptr_va_list({:?})", ptr); + let (alloc_id, offset, _prov) = self.ptr_get_alloc_id(ptr, 0)?; + if offset.bytes() != 0 { + throw_ub!(InvalidVaListPointer(Pointer::new(alloc_id, offset))) + } + + let Some(va_list) = self.memory.va_list_map.get(&alloc_id) else { + throw_ub!(InvalidVaListPointer(Pointer::new(alloc_id, offset))) + }; + + interp_ok(va_list) + } + + /// Removes this VaList from the global map of variable argument lists. This does not deallocate + /// the VaList elements, that happens when the Frame is popped. + pub fn deallocate_va_list( + &mut self, + ptr: Pointer>, + ) -> InterpResult<'tcx, VecDeque>> { + trace!("deallocate_va_list({:?})", ptr); + let (alloc_id, offset, _prov) = self.ptr_get_alloc_id(ptr, 0)?; + if offset.bytes() != 0 { + throw_ub!(InvalidVaListPointer(Pointer::new(alloc_id, offset))) + } + + let Some(va_list) = self.memory.va_list_map.swap_remove(&alloc_id) else { + throw_ub!(InvalidVaListPointer(Pointer::new(alloc_id, offset))) + }; + + self.memory.dead_alloc_map.insert(alloc_id, (Size::ZERO, Align::ONE)); + interp_ok(va_list) + } + /// Get the dynamic type of the given vtable pointer. /// If `expected_trait` is `Some`, it must be a vtable for the given trait. pub fn get_ptr_vtable_ty( @@ -1072,7 +1180,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Recurse, if there is data here. // Do this *before* invoking the callback, as the callback might mutate the // allocation and e.g. replace all provenance by wildcards! - if matches!(info.kind, AllocKind::LiveData) { + if info.kind == AllocKind::LiveData { let alloc = self.get_alloc_raw(id)?; for prov in alloc.provenance().provenances() { if let Some(id) = prov.get_alloc_id() { @@ -1546,7 +1654,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if (src_offset <= dest_offset && src_offset + size > dest_offset) || (dest_offset <= src_offset && dest_offset + size > src_offset) { - throw_ub_custom!(fluent::const_eval_copy_nonoverlapping_overlapping); + throw_ub_custom!(msg!( + "`copy_nonoverlapping` called on overlapping ranges" + )); } } } @@ -1605,7 +1715,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { match self.ptr_try_get_alloc_id(ptr, 0) { Ok((alloc_id, offset, _)) => { let info = self.get_alloc_info(alloc_id); - if matches!(info.kind, AllocKind::TypeId) { + if info.kind == AllocKind::TypeId { // We *could* actually precisely answer this question since here, // the offset *is* the integer value. But the entire point of making // this a pointer is not to leak the integer value, so we say everything diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs index 2f365ec77b33..c8ffc0ed208a 100644 --- a/compiler/rustc_const_eval/src/interpret/mod.rs +++ b/compiler/rustc_const_eval/src/interpret/mod.rs @@ -36,7 +36,7 @@ pub use self::operand::{ImmTy, Immediate, OpTy}; pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable}; use self::place::{MemPlace, Place}; pub use self::projection::{OffsetMode, Projectable}; -pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo}; +pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation}; pub use self::util::EnteredTraceSpan; pub(crate) use self::util::create_static_alloc; pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking}; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index d3d119c8fc9c..e8e77de8eb3e 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -1,11 +1,10 @@ //! Functions concerning immediate values and operands, and reading from operands. //! All high-level functions to read from memory work on operands as sources. -use std::assert_matches::assert_matches; - use either::{Either, Left, Right}; use rustc_abi as abi; use rustc_abi::{BackendRepr, HasDataLayout, Size}; +use rustc_data_structures::assert_matches; use rustc_hir::def::Namespace; use rustc_middle::mir::interpret::ScalarSizeMismatch; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, TyAndLayout}; @@ -845,6 +844,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // FIXME: do some more logic on `move` to invalidate the old location &Copy(place) | &Move(place) => self.eval_place_to_op(place, layout)?, + &RuntimeChecks(checks) => { + let val = M::runtime_checks(self, checks)?; + ImmTy::from_bool(val, self.tcx()).into() + } + Constant(constant) => { let c = self.instantiate_from_current_frame_and_normalize_erasing_regions( constant.const_, diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 8548b774ddb4..ca8c096d3ab4 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -1,7 +1,6 @@ use either::Either; use rustc_abi::Size; use rustc_apfloat::{Float, FloatConvert}; -use rustc_middle::mir::NullOp; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, FloatTy, ScalarInt}; @@ -505,11 +504,4 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } } - - pub fn nullary_op(&self, null_op: NullOp) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> { - use rustc_middle::mir::NullOp::*; - interp_ok(match null_op { - RuntimeChecks(r) => ImmTy::from_bool(M::runtime_checks(self, r)?, *self.tcx), - }) - } } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index a409c7fad417..fb07d5f0d0d6 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -2,12 +2,11 @@ //! into a place. //! All high-level functions to write to memory work on places as destinations. -use std::assert_matches::assert_matches; - use either::{Either, Left, Right}; use rustc_abi::{BackendRepr, HasDataLayout, Size}; -use rustc_middle::ty::Ty; +use rustc_data_structures::assert_matches; use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::ty::{self, Ty}; use rustc_middle::{bug, mir, span_bug}; use tracing::field::Empty; use tracing::{instrument, trace}; @@ -885,10 +884,38 @@ where dest.layout().ty, ); } + // If the source has padding, we want to always do a mem-to-mem copy to ensure consistent + // padding in the target independent of layout choices. + let src_has_padding = match src.layout().backend_repr { + BackendRepr::Scalar(_) => false, + BackendRepr::ScalarPair(left, right) + if matches!(src.layout().ty.kind(), ty::Ref(..) | ty::RawPtr(..)) => + { + // Wide pointers never have padding, so we can avoid calling `size()`. + debug_assert_eq!(left.size(self) + right.size(self), src.layout().size); + false + } + BackendRepr::ScalarPair(left, right) => { + let left_size = left.size(self); + let right_size = right.size(self); + // We have padding if the sizes don't add up to the total. + left_size + right_size != src.layout().size + } + // Everything else can only exist in memory anyway, so it doesn't matter. + BackendRepr::SimdVector { .. } + | BackendRepr::ScalableVector { .. } + | BackendRepr::Memory { .. } => true, + }; - // Let us see if the layout is simple so we take a shortcut, - // avoid force_allocation. - let src = match self.read_immediate_raw(src)? { + let src_val = if src_has_padding { + // Do our best to get an mplace. If there's no mplace, then this is stored as an + // "optimized" local, so its padding is definitely uninitialized and we are fine. + src.to_op(self)?.as_mplace_or_imm() + } else { + // Do our best to get an immediate, to avoid having to force_allocate the destination. + self.read_immediate_raw(src)? + }; + let src = match src_val { Right(src_val) => { assert!(!src.layout().is_unsized()); assert!(!dest.layout().is_unsized()); diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 027e634ef7f7..db72c02e308c 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -97,7 +97,7 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { } /// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for - /// reading from this thing. + /// reading from this thing. This will never actually do a read from memory! fn to_op>( &self, ecx: &InterpCx<'tcx, M>, diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 1c1c59da9d88..a55bea60cd6e 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -12,13 +12,14 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; use rustc_mir_dataflow::impls::always_storage_live_locals; use rustc_span::Span; +use rustc_target::callconv::ArgAbi; use tracing::field::Empty; use tracing::{info_span, instrument, trace}; use super::{ - AllocId, CtfeProvenance, Immediate, InterpCx, InterpResult, Machine, MemPlace, MemPlaceMeta, - MemoryKind, Operand, PlaceTy, Pointer, Provenance, ReturnAction, Scalar, from_known_layout, - interp_ok, throw_ub, throw_unsup, + AllocId, CtfeProvenance, FnArg, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, + MemPlaceMeta, MemoryKind, Operand, PlaceTy, Pointer, Provenance, ReturnAction, Scalar, + from_known_layout, interp_ok, throw_ub, throw_unsup, }; use crate::{enter_trace_span, errors}; @@ -80,7 +81,7 @@ pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> { /// and its layout in the caller. This place is to be interpreted relative to the /// *caller's* stack frame. We use a `PlaceTy` instead of an `MPlaceTy` since this /// avoids having to move *all* return places into Miri's memory. - pub return_place: PlaceTy<'tcx, Prov>, + return_place: PlaceTy<'tcx, Prov>, /// The list of locals for this stack frame, stored in order as /// `[return_ptr, arguments..., variables..., temporaries...]`. @@ -91,6 +92,10 @@ pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> { /// Do *not* access this directly; always go through the machine hook! pub locals: IndexVec>, + /// The complete variable argument list of this frame. Its elements must be dropped when the + /// frame is popped. + pub(super) va_list: Vec>, + /// The span of the `tracing` crate is stored here. /// When the guard is dropped, the span is exited. This gives us /// a full stack trace on all tracing statements. @@ -122,19 +127,6 @@ pub enum ReturnContinuation { Stop { cleanup: bool }, } -/// Return type of [`InterpCx::pop_stack_frame_raw`]. -pub struct StackPopInfo<'tcx, Prov: Provenance> { - /// Additional information about the action to be performed when returning from the popped - /// stack frame. - pub return_action: ReturnAction, - - /// [`return_cont`](Frame::return_cont) of the popped stack frame. - pub return_cont: ReturnContinuation, - - /// [`return_place`](Frame::return_place) of the popped stack frame. - pub return_place: PlaceTy<'tcx, Prov>, -} - /// State of a local variable including a memoized layout #[derive(Clone)] pub struct LocalState<'tcx, Prov: Provenance = CtfeProvenance> { @@ -259,6 +251,7 @@ impl<'tcx, Prov: Provenance> Frame<'tcx, Prov> { return_cont: self.return_cont, return_place: self.return_place, locals: self.locals, + va_list: self.va_list, loc: self.loc, extra, tracing_span: self.tracing_span, @@ -286,6 +279,14 @@ impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> { self.instance } + pub fn return_place(&self) -> &PlaceTy<'tcx, Prov> { + &self.return_place + } + + pub fn return_cont(&self) -> ReturnContinuation { + self.return_cont + } + /// Return the `SourceInfo` of the current instruction. pub fn current_source_info(&self) -> Option<&mir::SourceInfo> { self.loc.left().map(|loc| self.body.source_info(loc)) @@ -377,6 +378,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return_cont, return_place: return_place.clone(), locals, + va_list: vec![], instance, tracing_span: SpanGuard::new(), extra: (), @@ -410,35 +412,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } - /// Low-level helper that pops a stack frame from the stack and returns some information about - /// it. - /// - /// This also deallocates locals, if necessary. - /// `copy_ret_val` gets called after the frame has been taken from the stack but before the locals have been deallocated. - /// - /// [`M::before_stack_pop`] and [`M::after_stack_pop`] are called by this function - /// automatically. - /// - /// The high-level version of this is `return_from_current_stack_frame`. - /// - /// [`M::before_stack_pop`]: Machine::before_stack_pop - /// [`M::after_stack_pop`]: Machine::after_stack_pop + /// Low-level helper that pops a stack frame from the stack without any cleanup. + /// This invokes `before_stack_pop`. + /// After calling this function, you need to deal with the return value, and then + /// invoke `cleanup_stack_frame`. pub(super) fn pop_stack_frame_raw( &mut self, - unwinding: bool, - copy_ret_val: impl FnOnce(&mut Self, &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx>, - ) -> InterpResult<'tcx, StackPopInfo<'tcx, M::Provenance>> { + ) -> InterpResult<'tcx, Frame<'tcx, M::Provenance, M::FrameExtra>> { M::before_stack_pop(self)?; let frame = self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); + interp_ok(frame) + } - // Copy return value (unless we are unwinding). - if !unwinding { - copy_ret_val(self, &frame.return_place)?; - } - + /// Deallocate local variables in the stack frame, and invoke `after_stack_pop`. + pub(super) fn cleanup_stack_frame( + &mut self, + unwinding: bool, + frame: Frame<'tcx, M::Provenance, M::FrameExtra>, + ) -> InterpResult<'tcx, ReturnAction> { let return_cont = frame.return_cont; - let return_place = frame.return_place.clone(); // Cleanup: deallocate locals. // Usually we want to clean up (deallocate locals), but in a few rare cases we don't. @@ -448,22 +441,22 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ReturnContinuation::Stop { cleanup, .. } => cleanup, }; - let return_action = if cleanup { - // We need to take the locals out, since we need to mutate while iterating. + if cleanup { for local in &frame.locals { self.deallocate_local(local.value)?; } + // Deallocate any c-variadic arguments. + self.deallocate_varargs(&frame.va_list)?; + // Call the machine hook, which determines the next steps. let return_action = M::after_stack_pop(self, frame, unwinding)?; assert_ne!(return_action, ReturnAction::NoCleanup); - return_action + interp_ok(return_action) } else { // We also skip the machine hook when there's no cleanup. This not a real "pop" anyway. - ReturnAction::NoCleanup - }; - - interp_ok(StackPopInfo { return_action, return_cont, return_place }) + interp_ok(ReturnAction::NoCleanup) + } } /// In the current stack frame, mark all locals as live that are not arguments and don't have @@ -626,6 +619,58 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } +impl<'a, 'tcx: 'a, M: Machine<'tcx>> InterpCx<'tcx, M> { + /// Consume the arguments provided by the iterator and store them as a list + /// of variadic arguments. Return a list of the places that hold those arguments. + pub(crate) fn allocate_varargs( + &mut self, + caller_args: &mut I, + callee_abis: &mut J, + ) -> InterpResult<'tcx, Vec>> + where + I: Iterator, &'a ArgAbi<'tcx, Ty<'tcx>>)>, + J: Iterator>)>, + { + // Consume the remaining arguments and store them in fresh allocations. + let mut varargs = Vec::new(); + for (fn_arg, caller_abi) in caller_args { + // The callee ABI is entirely computed based on which arguments the caller has + // provided so it should not be possible to get a mismatch here. + let (_idx, callee_abi) = callee_abis.next().unwrap(); + assert!(self.check_argument_compat(caller_abi, callee_abi)?); + // FIXME: do we have to worry about in-place argument passing? + let op = fn_arg.copy_fn_arg(); + let mplace = self.allocate(op.layout, MemoryKind::Stack)?; + self.copy_op(&op, &mplace)?; + + varargs.push(mplace); + } + assert!(callee_abis.next().is_none()); + + interp_ok(varargs) + } + + /// Deallocate the variadic arguments in the list (that must have been created with `allocate_varargs`). + fn deallocate_varargs( + &mut self, + varargs: &[MPlaceTy<'tcx, M::Provenance>], + ) -> InterpResult<'tcx> { + for vararg in varargs { + let ptr = vararg.ptr(); + + trace!( + "deallocating vararg {:?}: {:?}", + vararg, + // Locals always have a `alloc_id` (they are never the result of a int2ptr). + self.dump_alloc(ptr.provenance.unwrap().get_alloc_id().unwrap()) + ); + self.deallocate_ptr(ptr, None, MemoryKind::Stack)?; + } + + interp_ok(()) + } +} + impl<'tcx, Prov: Provenance> LocalState<'tcx, Prov> { pub(super) fn print( &self, diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 88a116094758..0dd17f109be3 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -203,11 +203,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_immediate(*result, &dest)?; } - NullaryOp(null_op) => { - let val = self.nullary_op(null_op)?; - self.write_immediate(*val, &dest)?; - } - Aggregate(box ref kind, ref operands) => { self.write_aggregate(kind, operands, &dest)?; } @@ -223,7 +218,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // A fresh reference was created, make sure it gets retagged. let val = M::retag_ptr_value( self, - if borrow_kind.allows_two_phase_borrow() { + if borrow_kind.is_two_phase_borrow() { mir::RetagKind::TwoPhase } else { mir::RetagKind::Default @@ -254,12 +249,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_immediate(*val, &dest)?; } - ShallowInitBox(ref operand, _) => { - let src = self.eval_operand(operand, None)?; - let v = self.read_immediate(&src)?; - self.write_immediate(*v, &dest)?; - } - Cast(cast_kind, ref operand, cast_ty) => { let src = self.eval_operand(operand, None)?; let cast_ty = @@ -392,7 +381,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { move_definitely_disjoint: bool, ) -> InterpResult<'tcx, FnArg<'tcx, M::Provenance>> { interp_ok(match op { - mir::Operand::Copy(_) | mir::Operand::Constant(_) => { + mir::Operand::Copy(_) | mir::Operand::Constant(_) | mir::Operand::RuntimeChecks(_) => { // Make a regular copy. let op = self.eval_operand(op, None)?; FnArg::Copy(op) @@ -561,8 +550,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if fn_abi.can_unwind { unwind } else { mir::UnwindAction::Unreachable }, )?; // Sanity-check that `eval_fn_call` either pushed a new frame or - // did a jump to another block. - if self.frame_idx() == old_stack && self.frame().loc == old_loc { + // did a jump to another block. We disable the sanity check for functions that + // can't return, since Miri sometimes does have to keep the location the same + // for those (which is fine since execution will continue on a different thread). + if target.is_some() && self.frame_idx() == old_stack && self.frame().loc == old_loc + { span_bug!(terminator.source_info.span, "evaluating this call made no progress"); } } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 34296b6d8de3..6fc8d5ef8f96 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -647,13 +647,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { } } else { // This is not CTFE, so it's Miri with recursive checking. - // FIXME: we do *not* check behind boxes, since creating a new box first creates it uninitialized - // and then puts the value in there, so briefly we have a box with uninit contents. - // FIXME: should we also skip `UnsafeCell` behind shared references? Currently that is not + // FIXME: should we also `UnsafeCell` behind shared references? Currently that is not // needed since validation reads bypass Stacked Borrows and data race checks. - if matches!(ptr_kind, PointerKind::Box) { - return interp_ok(()); - } } let path = &self.path; ref_tracking.track(place, || { @@ -1315,7 +1310,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, self.visit_scalar(b, b_layout)?; } } - BackendRepr::SimdVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { // No checks here, we assume layout computation gets this right. // (This is harder to check since Miri does not represent these as `Immediate`. We // also cannot use field projections since this might be a newtype around a vector.) diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index b5de10c7dcd1..a8d472bc2ea2 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -4,7 +4,6 @@ use std::num::NonZero; use rustc_abi::{FieldIdx, FieldsShape, VariantIdx, Variants}; -use rustc_index::IndexVec; use rustc_middle::mir::interpret::InterpResult; use rustc_middle::ty::{self, Ty}; use tracing::trace; @@ -24,18 +23,6 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { self.ecx().read_discriminant(&v.to_op(self.ecx())?) } - /// This function provides the chance to reorder the order in which fields are visited for - /// `FieldsShape::Aggregate`. - /// - /// The default means we iterate in source declaration order; alternatively this can do some - /// work with `memory_index` to iterate in memory order. - #[inline(always)] - fn aggregate_field_iter( - memory_index: &IndexVec, - ) -> impl Iterator + 'static { - memory_index.indices() - } - // Recursive actions, ready to be overloaded. /// Visits the given value, dispatching as appropriate to more specialized visitors. #[inline(always)] @@ -168,8 +155,8 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { &FieldsShape::Union(fields) => { self.visit_union(v, fields)?; } - FieldsShape::Arbitrary { memory_index, .. } => { - for idx in Self::aggregate_field_iter(memory_index) { + FieldsShape::Arbitrary { in_memory_order, .. } => { + for idx in in_memory_order.iter().copied() { let field = self.ecx().project_field(v, idx)?; self.visit_field(v, idx.as_usize(), &field)?; } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 2fce4b8c0566..ead1ee9bf85e 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,7 +1,6 @@ // tidy-alphabetical-start -#![allow(rustc::diagnostic_outside_of_impl)] +#![cfg_attr(bootstrap, feature(assert_matches))] #![feature(array_try_map)] -#![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] @@ -27,23 +26,21 @@ use rustc_middle::util::Providers; pub use self::errors::ReportErrorExt; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { - const_eval::provide(providers); - providers.tag_for_variant = const_eval::tag_for_variant_provider; - providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; - providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; - providers.eval_static_initializer = const_eval::eval_static_initializer_provider; + const_eval::provide(&mut providers.queries); + providers.queries.tag_for_variant = const_eval::tag_for_variant_provider; + providers.queries.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; + providers.queries.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; + providers.queries.eval_static_initializer = const_eval::eval_static_initializer_provider; providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider; - providers.eval_to_valtree = |tcx, ty::PseudoCanonicalInput { typing_env, value }| { + providers.queries.eval_to_valtree = |tcx, ty::PseudoCanonicalInput { typing_env, value }| { const_eval::eval_to_valtree(tcx, typing_env, value) }; providers.hooks.try_destructure_mir_constant_for_user_output = const_eval::try_destructure_mir_constant_for_user_output; - providers.valtree_to_const_val = + providers.queries.valtree_to_const_val = |tcx, cv| const_eval::valtree_to_const_value(tcx, ty::TypingEnv::fully_monomorphized(), cv); - providers.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| { + providers.queries.check_validity_requirement = |tcx, (init_kind, param_env_and_ty)| { util::check_validity_requirement(tcx, init_kind, param_env_and_ty) }; providers.hooks.validate_scalar_in_layout = diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 34bd8423e8e1..939f9151680b 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -119,7 +119,9 @@ fn check_validity_requirement_lax<'tcx>( } BackendRepr::SimdVector { element: s, count } => count == 0 || scalar_allows_raw_init(s), BackendRepr::Memory { .. } => true, // Fields are checked below. + BackendRepr::ScalableVector { element, .. } => scalar_allows_raw_init(element), }; + if !valid { // This is definitely not okay. return Ok(false); diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index c8296e05f6bd..0332ff681082 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -9,8 +9,8 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" either = "1.0" elsa = "1.11.0" -ena = "0.14.3" -indexmap = "2.4.0" +ena = "0.14.4" +indexmap = "2.12.1" jobserver_crate = { version = "0.1.28", package = "jobserver" } measureme = "12.0.1" parking_lot = "0.12" @@ -31,7 +31,7 @@ tracing = "0.1" # tidy-alphabetical-end [dependencies.hashbrown] -version = "0.15.2" +version = "0.16.1" default-features = false features = ["nightly"] # for may_dangle diff --git a/compiler/rustc_data_structures/src/fx.rs b/compiler/rustc_data_structures/src/fx.rs index f0db9623b674..cad775cc9864 100644 --- a/compiler/rustc_data_structures/src/fx.rs +++ b/compiler/rustc_data_structures/src/fx.rs @@ -1,11 +1,9 @@ -use std::hash::BuildHasherDefault; - -pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +pub use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet, FxHasher}; pub type StdEntry<'a, K, V> = std::collections::hash_map::Entry<'a, K, V>; -pub type FxIndexMap = indexmap::IndexMap>; -pub type FxIndexSet = indexmap::IndexSet>; +pub type FxIndexMap = indexmap::IndexMap; +pub type FxIndexSet = indexmap::IndexSet; pub type IndexEntry<'a, K, V> = indexmap::map::Entry<'a, K, V>; pub type IndexOccupiedEntry<'a, K, V> = indexmap::map::OccupiedEntry<'a, K, V>; @@ -28,3 +26,18 @@ macro_rules! define_stable_id_collections { pub type $entry_name<'a, T> = $crate::fx::IndexEntry<'a, $key, T>; }; } + +pub mod default { + use super::{FxBuildHasher, FxHashMap, FxHashSet}; + + // FIXME: These two functions will become unnecessary after + // lands and we start using the corresponding + // `rustc-hash` version. After that we can use `Default::default()` instead. + pub const fn fx_hash_map() -> FxHashMap { + FxHashMap::with_hasher(FxBuildHasher) + } + + pub const fn fx_hash_set() -> FxHashSet { + FxHashSet::with_hasher(FxBuildHasher) + } +} diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 1882e6e835a4..954e4116fb55 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -8,7 +8,6 @@ //! Typical examples would include: minimum element in SCC, maximum element //! reachable from it, etc. -use std::assert_matches::debug_assert_matches; use std::fmt::Debug; use std::marker::PhantomData; use std::ops::Range; @@ -16,6 +15,7 @@ use std::ops::Range; use rustc_index::{Idx, IndexSlice, IndexVec}; use tracing::{debug, instrument, trace}; +use crate::debug_assert_matches; use crate::fx::FxHashSet; use crate::graph::vec_graph::VecGraph; use crate::graph::{DirectedGraph, NumEdges, Successors}; @@ -27,26 +27,18 @@ mod tests; /// the max/min element of the SCC, or all of the above. /// /// Concretely, the both merge operations must commute, e.g. where `merge` -/// is `merge_scc` and `merge_reached`: `a.merge(b) == b.merge(a)` +/// is `update_scc` and `update_reached`: `a.merge(b) == b.merge(a)` /// /// In general, what you want is probably always min/max according /// to some ordering, potentially with side constraints (min x such /// that P holds). pub trait Annotation: Debug + Copy { /// Merge two existing annotations into one during - /// path compression.o - fn merge_scc(self, other: Self) -> Self; + /// path compression. + fn update_scc(&mut self, other: &Self); /// Merge a successor into this annotation. - fn merge_reached(self, other: Self) -> Self; - - fn update_scc(&mut self, other: Self) { - *self = self.merge_scc(other) - } - - fn update_reachable(&mut self, other: Self) { - *self = self.merge_reached(other) - } + fn update_reachable(&mut self, other: &Self); } /// An accumulator for annotations. @@ -70,12 +62,8 @@ impl Annotations for NoAnnotations { /// The empty annotation, which does nothing. impl Annotation for () { - fn merge_reached(self, _other: Self) -> Self { - () - } - fn merge_scc(self, _other: Self) -> Self { - () - } + fn update_reachable(&mut self, _other: &Self) {} + fn update_scc(&mut self, _other: &Self) {} } /// Strongly connected components (SCC) of a graph. The type `N` is @@ -614,7 +602,7 @@ where *min_depth = successor_min_depth; *min_cycle_root = successor_node; } - current_component_annotation.update_scc(successor_annotation); + current_component_annotation.update_scc(&successor_annotation); } // The starting node `node` is succeeded by a fully identified SCC // which is now added to the set under `scc_index`. @@ -629,7 +617,7 @@ where // the `successors_stack` for later. trace!(?node, ?successor_scc_index); successors_stack.push(successor_scc_index); - current_component_annotation.update_reachable(successor_annotation); + current_component_annotation.update_reachable(&successor_annotation); } // `node` has no more (direct) successors; search recursively. None => { diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs index 8f04baf51f35..4626861c3e00 100644 --- a/compiler/rustc_data_structures/src/graph/scc/tests.rs +++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs @@ -32,12 +32,12 @@ impl Maxes { } impl Annotation for MaxReached { - fn merge_scc(self, other: Self) -> Self { - Self(std::cmp::max(other.0, self.0)) + fn update_scc(&mut self, other: &Self) { + self.0 = self.0.max(other.0); } - fn merge_reached(self, other: Self) -> Self { - Self(std::cmp::max(other.0, self.0)) + fn update_reachable(&mut self, other: &Self) { + self.0 = self.0.max(other.0); } } @@ -75,13 +75,12 @@ impl Annotations for MinMaxes { } impl Annotation for MinMaxIn { - fn merge_scc(self, other: Self) -> Self { - Self { min: std::cmp::min(self.min, other.min), max: std::cmp::max(self.max, other.max) } + fn update_scc(&mut self, other: &Self) { + self.min = self.min.min(other.min); + self.max = self.max.max(other.max); } - fn merge_reached(self, _other: Self) -> Self { - self - } + fn update_reachable(&mut self, _other: &Self) {} } #[test] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index b4031973fbc2..594d6d294d75 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -10,15 +10,17 @@ #![allow(internal_features)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] +#![cfg_attr(bootstrap, feature(assert_matches))] +#![cfg_attr(bootstrap, feature(cold_path))] +#![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] #![feature(allocator_api)] -#![feature(array_windows)] #![feature(ascii_char)] #![feature(ascii_char_variants)] -#![feature(assert_matches)] #![feature(auto_traits)] #![feature(cfg_select)] -#![feature(core_intrinsics)] +#![feature(const_default)] +#![feature(const_trait_impl)] #![feature(dropck_eyepatch)] #![feature(extend_one)] #![feature(file_buffered)] @@ -29,17 +31,28 @@ #![feature(ptr_alignment_type)] #![feature(rustc_attrs)] #![feature(sized_hierarchy)] -#![feature(test)] #![feature(thread_id_value)] #![feature(trusted_len)] #![feature(type_alias_impl_trait)] #![feature(unwrap_infallible)] // tidy-alphabetical-end +// Temporarily re-export `assert_matches!`, so that the rest of the compiler doesn't +// have to worry about it being moved to a different module in std during stabilization. +// FIXME(#151359): Remove this when `feature(assert_matches)` is stable in stage0. +// (This doesn't necessarily need to be fixed during the beta bump itself.) +#[cfg(bootstrap)] +pub use std::assert_matches::{assert_matches, debug_assert_matches}; use std::fmt; +#[cfg(not(bootstrap))] +pub use std::{assert_matches, debug_assert_matches}; pub use atomic_ref::AtomicRef; pub use ena::{snapshot_vec, undo_log, unify}; +// Re-export `hashbrown::hash_table`, because it's part of our API +// (via `ShardedHashMap`), and because it lets other compiler crates use the +// lower-level `HashTable` API without a tricky `hashbrown` dependency. +pub use hashbrown::hash_table; pub use rustc_index::static_assert_size; // Re-export some data-structure crates which are part of our public API. pub use {either, indexmap, smallvec, thin_vec}; diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs index 0ef3bb319ff8..72d5f004194a 100644 --- a/compiler/rustc_data_structures/src/marker.rs +++ b/compiler/rustc_data_structures/src/marker.rs @@ -75,6 +75,7 @@ impl_dyn_send!( [std::sync::Mutex where T: ?Sized+ DynSend] [std::sync::mpsc::Sender where T: DynSend] [std::sync::Arc where T: ?Sized + DynSync + DynSend] + [std::sync::Weak where T: ?Sized + DynSync + DynSend] [std::sync::LazyLock where T: DynSend, F: DynSend] [std::collections::HashSet where K: DynSend, S: DynSend] [std::collections::HashMap where K: DynSend, V: DynSend, S: DynSend] @@ -157,6 +158,7 @@ impl_dyn_sync!( [std::sync::OnceLock where T: DynSend + DynSync] [std::sync::Mutex where T: ?Sized + DynSend] [std::sync::Arc where T: ?Sized + DynSync + DynSend] + [std::sync::Weak where T: ?Sized + DynSync + DynSend] [std::sync::LazyLock where T: DynSend + DynSync, F: DynSend] [std::collections::HashSet where K: DynSync, S: DynSync] [std::collections::HashMap where K: DynSync, V: DynSync, S: DynSync] diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 4a9551a60cf9..cab57edb8946 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -85,12 +85,11 @@ use std::borrow::Borrow; use std::collections::hash_map::Entry; use std::error::Error; use std::fmt::Display; -use std::intrinsics::unlikely; use std::path::Path; use std::sync::Arc; use std::sync::atomic::Ordering; use std::time::{Duration, Instant}; -use std::{fs, process}; +use std::{fs, hint, process}; pub use measureme::EventId; use measureme::{EventIdBuilder, Profiler, SerializableString, StringId}; @@ -427,7 +426,8 @@ impl SelfProfilerRef { .unwrap() .increment_query_cache_hit_counters(QueryInvocationId(query_invocation_id.0)); } - if unlikely(profiler_ref.event_filter_mask.contains(EventFilter::QUERY_CACHE_HITS)) { + if profiler_ref.event_filter_mask.contains(EventFilter::QUERY_CACHE_HITS) { + hint::cold_path(); profiler_ref.instant_query_event( |profiler| profiler.query_cache_hit_event_kind, query_invocation_id, @@ -437,7 +437,8 @@ impl SelfProfilerRef { // We check both kinds of query cache hit events at once, to reduce overhead in the // common case (with self-profile disabled). - if unlikely(self.event_filter_mask.intersects(EventFilter::QUERY_CACHE_HIT_COMBINED)) { + if self.event_filter_mask.intersects(EventFilter::QUERY_CACHE_HIT_COMBINED) { + hint::cold_path(); cold_call(self, query_invocation_id); } } @@ -995,12 +996,14 @@ cfg_select! { } unix => { pub fn get_resident_set_size() -> Option { + use libc::{sysconf, _SC_PAGESIZE}; let field = 1; let contents = fs::read("/proc/self/statm").ok()?; let contents = String::from_utf8(contents).ok()?; let s = contents.split_whitespace().nth(field)?; let npages = s.parse::().ok()?; - Some(npages * 4096) + // SAFETY: `sysconf(_SC_PAGESIZE)` has no side effects and is safe to call. + Some(npages * unsafe { sysconf(_SC_PAGESIZE) } as usize) } } _ => { diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 5de9413cf15d..e10ccccad5bb 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -3,7 +3,7 @@ use std::hash::{Hash, Hasher}; use std::{iter, mem}; use either::Either; -use hashbrown::hash_table::{Entry, HashTable}; +use hashbrown::hash_table::{self, Entry, HashTable}; use crate::fx::FxHasher; use crate::sync::{CacheAligned, Lock, LockGuard, Mode, is_dyn_thread_safe}; @@ -140,7 +140,7 @@ pub fn shards() -> usize { 1 } -pub type ShardedHashMap = Sharded>; +pub type ShardedHashMap = Sharded>; impl ShardedHashMap { pub fn with_capacity(cap: usize) -> Self { diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 3a64c924cc22..9fb4d4352c2f 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -607,7 +607,7 @@ where /// result (for example, using a `Fingerprint` produced while /// hashing `Span`s when a `Fingerprint` without `Span`s is /// being requested) -#[derive(Clone, Hash, Eq, PartialEq, Debug)] +#[derive(Clone, Copy, Hash, Eq, PartialEq, Debug)] pub struct HashingControls { pub hash_spans: bool, } diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 3881f3c2aa84..31768fe189ae 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -41,7 +41,8 @@ pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard}; pub use self::lock::{Lock, LockGuard, Mode}; pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; pub use self::parallel::{ - broadcast, join, par_for_each_in, par_map, parallel_guard, scope, spawn, try_par_for_each_in, + broadcast, par_fns, par_for_each_in, par_join, par_map, parallel_guard, spawn, + try_par_for_each_in, }; pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec}; pub use self::worker_local::{Registry, WorkerLocal}; diff --git a/compiler/rustc_data_structures/src/sync/freeze.rs b/compiler/rustc_data_structures/src/sync/freeze.rs index 6338afb92c34..fb2dcb25556a 100644 --- a/compiler/rustc_data_structures/src/sync/freeze.rs +++ b/compiler/rustc_data_structures/src/sync/freeze.rs @@ -1,5 +1,5 @@ use std::cell::UnsafeCell; -use std::intrinsics::likely; +use std::hint; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::ptr::NonNull; @@ -60,10 +60,11 @@ impl FreezeLock { /// Get the inner value if frozen. #[inline] pub fn get(&self) -> Option<&T> { - if likely(self.frozen.load(Ordering::Acquire)) { + if self.frozen.load(Ordering::Acquire) { // SAFETY: This is frozen so the data cannot be modified. unsafe { Some(&*self.data.get()) } } else { + hint::cold_path(); None } } diff --git a/compiler/rustc_data_structures/src/sync/lock.rs b/compiler/rustc_data_structures/src/sync/lock.rs index a8161c515115..f183af0c0dab 100644 --- a/compiler/rustc_data_structures/src/sync/lock.rs +++ b/compiler/rustc_data_structures/src/sync/lock.rs @@ -1,7 +1,7 @@ //! This module implements a lock which only uses synchronization if `might_be_dyn_thread_safe` is true. //! It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync` traits. -use std::fmt; +use std::{fmt, hint}; #[derive(Clone, Copy, PartialEq)] pub enum Mode { @@ -10,7 +10,6 @@ pub enum Mode { } use std::cell::{Cell, UnsafeCell}; -use std::intrinsics::unlikely; use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::ops::{Deref, DerefMut}; @@ -92,7 +91,8 @@ pub struct Lock { impl Lock { #[inline(always)] pub fn new(inner: T) -> Self { - let (mode, mode_union) = if unlikely(mode::might_be_dyn_thread_safe()) { + let (mode, mode_union) = if mode::might_be_dyn_thread_safe() { + hint::cold_path(); // Create the lock with synchronization enabled using the `RawMutex` type. (Mode::Sync, ModeUnion { sync: ManuallyDrop::new(RawMutex::INIT) }) } else { @@ -150,7 +150,8 @@ impl Lock { unsafe { match mode { Mode::NoSync => { - if unlikely(self.mode_union.no_sync.replace(LOCKED) == LOCKED) { + if self.mode_union.no_sync.replace(LOCKED) == LOCKED { + hint::cold_path(); lock_held() } } diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index b515c0bee8a6..2ab4a7f75b6b 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -56,41 +56,6 @@ where (a.unwrap(), b.unwrap()) } -/// Runs a list of blocks in parallel. The first block is executed immediately on -/// the current thread. Use that for the longest running block. -#[macro_export] -macro_rules! parallel { - (impl $fblock:block [$($c:expr,)*] [$block:expr $(, $rest:expr)*]) => { - parallel!(impl $fblock [$block, $($c,)*] [$($rest),*]) - }; - (impl $fblock:block [$($blocks:expr,)*] []) => { - $crate::sync::parallel_guard(|guard| { - $crate::sync::scope(|s| { - $( - let block = $crate::sync::FromDyn::from(|| $blocks); - s.spawn(move |_| { - guard.run(move || block.into_inner()()); - }); - )* - guard.run(|| $fblock); - }); - }); - }; - ($fblock:block, $($blocks:block),*) => { - if $crate::sync::is_dyn_thread_safe() { - // Reverse the order of the later blocks since Rayon executes them in reverse order - // when using a single thread. This ensures the execution order matches that - // of a single threaded rustc. - parallel!(impl $fblock [] [$($blocks),*]); - } else { - $crate::sync::parallel_guard(|guard| { - guard.run(|| $fblock); - $(guard.run(|| $blocks);)* - }); - } - }; - } - pub fn spawn(func: impl FnOnce() + DynSend + 'static) { if mode::is_dyn_thread_safe() { let func = FromDyn::from(func); @@ -102,18 +67,43 @@ pub fn spawn(func: impl FnOnce() + DynSend + 'static) { } } -// This function only works when `mode::is_dyn_thread_safe()`. -pub fn scope<'scope, OP, R>(op: OP) -> R -where - OP: FnOnce(&rustc_thread_pool::Scope<'scope>) -> R + DynSend, - R: DynSend, -{ - let op = FromDyn::from(op); - rustc_thread_pool::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner() +/// Runs the functions in parallel. +/// +/// The first function is executed immediately on the current thread. +/// Use that for the longest running function for better scheduling. +pub fn par_fns(funcs: &mut [&mut (dyn FnMut() + DynSend)]) { + parallel_guard(|guard: &ParallelGuard| { + if mode::is_dyn_thread_safe() { + let funcs = FromDyn::from(funcs); + rustc_thread_pool::scope(|s| { + let Some((first, rest)) = funcs.into_inner().split_at_mut_checked(1) else { + return; + }; + + // Reverse the order of the later functions since Rayon executes them in reverse + // order when using a single thread. This ensures the execution order matches + // that of a single threaded rustc. + for f in rest.iter_mut().rev() { + let f = FromDyn::from(f); + s.spawn(|_| { + guard.run(|| (f.into_inner())()); + }); + } + + // Run the first function without spawning to + // ensure it executes immediately on this thread. + guard.run(|| first[0]()); + }); + } else { + for f in funcs { + guard.run(|| f()); + } + } + }); } #[inline] -pub fn join(oper_a: A, oper_b: B) -> (RA, RB) +pub fn par_join(oper_a: A, oper_b: B) -> (RA, RB) where A: FnOnce() -> RA + DynSend, B: FnOnce() -> RB + DynSend, @@ -138,34 +128,21 @@ fn par_slice( guard: &ParallelGuard, for_each: impl Fn(&mut I) + DynSync + DynSend, ) { - struct State<'a, F> { - for_each: FromDyn, - guard: &'a ParallelGuard, - group: usize, - } - - fn par_rec( - items: &mut [I], - state: &State<'_, F>, - ) { - if items.len() <= state.group { - for item in items { - state.guard.run(|| (state.for_each)(item)); - } - } else { - let (left, right) = items.split_at_mut(items.len() / 2); - let mut left = state.for_each.derive(left); - let mut right = state.for_each.derive(right); - rustc_thread_pool::join(move || par_rec(*left, state), move || par_rec(*right, state)); + let for_each = FromDyn::from(for_each); + let mut items = for_each.derive(items); + rustc_thread_pool::scope(|s| { + let proof = items.derive(()); + let group_size = std::cmp::max(items.len() / 128, 1); + for group in items.chunks_mut(group_size) { + let group = proof.derive(group); + s.spawn(|_| { + let mut group = group; + for i in group.iter_mut() { + guard.run(|| for_each(i)); + } + }); } - } - - let state = State { - for_each: FromDyn::from(for_each), - guard, - group: std::cmp::max(items.len() / 128, 1), - }; - par_rec(items, &state) + }); } pub fn par_for_each_in>( diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index 3d44fb1fd48d..eb29ef3b4d0a 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -8,10 +8,10 @@ use std::hash::Hash; use std::iter::{Product, Sum}; use std::ops::Index; -use rustc_hash::{FxHashMap, FxHashSet}; use rustc_macros::{Decodable_NoContext, Encodable_NoContext}; use crate::fingerprint::Fingerprint; +use crate::fx::{FxBuildHasher, FxHashMap, FxHashSet}; use crate::stable_hasher::{HashStable, StableCompare, StableHasher, ToStableHashKey}; /// `UnordItems` is the order-less version of `Iterator`. It only contains methods @@ -241,10 +241,10 @@ pub struct UnordSet { impl UnordCollection for UnordSet {} -impl Default for UnordSet { +impl const Default for UnordSet { #[inline] fn default() -> Self { - Self { inner: FxHashSet::default() } + Self { inner: FxHashSet::with_hasher(FxBuildHasher) } } } @@ -438,10 +438,10 @@ pub struct UnordMap { impl UnordCollection for UnordMap {} -impl Default for UnordMap { +impl const Default for UnordMap { #[inline] fn default() -> Self { - Self { inner: FxHashMap::default() } + Self { inner: FxHashMap::with_hasher(FxBuildHasher) } } } diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs index 599970663db8..f9f5871c8d61 100644 --- a/compiler/rustc_data_structures/src/vec_cache.rs +++ b/compiler/rustc_data_structures/src/vec_cache.rs @@ -29,8 +29,6 @@ struct Slot { struct SlotIndex { // the index of the bucket in VecCache (0 to 20) bucket_idx: usize, - // number of entries in that bucket - entries: usize, // the index of the slot within the bucket index_in_bucket: usize, } @@ -39,12 +37,12 @@ struct SlotIndex { // compile-time. Visiting all powers of two is enough to hit all the buckets. // // We confirm counts are accurate in the slot_index_exhaustive test. -const ENTRIES_BY_BUCKET: [usize; 21] = { - let mut entries = [0; 21]; +const ENTRIES_BY_BUCKET: [usize; BUCKETS] = { + let mut entries = [0; BUCKETS]; let mut key = 0; loop { let si = SlotIndex::from_index(key); - entries[si.bucket_idx] = si.entries; + entries[si.bucket_idx] = si.entries(); if key == 0 { key = 1; } else if key == (1 << 31) { @@ -56,7 +54,14 @@ const ENTRIES_BY_BUCKET: [usize; 21] = { entries }; +const BUCKETS: usize = 21; + impl SlotIndex { + /// The total possible number of entries in the bucket + const fn entries(&self) -> usize { + if self.bucket_idx == 0 { 1 << 12 } else { 1 << (self.bucket_idx + 11) } + } + // This unpacks a flat u32 index into identifying which bucket it belongs to and the offset // within that bucket. As noted in the VecCache docs, buckets double in size with each index. // Typically that would mean 31 buckets (2^0 + 2^1 ... + 2^31 = u32::MAX - 1), but to reduce @@ -70,18 +75,13 @@ impl SlotIndex { const fn from_index(idx: u32) -> Self { const FIRST_BUCKET_SHIFT: usize = 12; if idx < (1 << FIRST_BUCKET_SHIFT) { - return SlotIndex { - bucket_idx: 0, - entries: 1 << FIRST_BUCKET_SHIFT, - index_in_bucket: idx as usize, - }; + return SlotIndex { bucket_idx: 0, index_in_bucket: idx as usize }; } // We already ruled out idx 0, so this `ilog2` never panics (and the check optimizes away) let bucket = idx.ilog2() as usize; let entries = 1 << bucket; SlotIndex { bucket_idx: bucket - FIRST_BUCKET_SHIFT + 1, - entries, index_in_bucket: idx as usize - entries, } } @@ -98,7 +98,7 @@ impl SlotIndex { if ptr.is_null() { return None; } - assert!(self.index_in_bucket < self.entries); + debug_assert!(self.index_in_bucket < self.entries()); // SAFETY: `bucket` was allocated (so <= isize in total bytes) to hold `entries`, so this // must be inbounds. let slot = unsafe { ptr.add(self.index_in_bucket) }; @@ -126,11 +126,12 @@ impl SlotIndex { fn bucket_ptr(&self, bucket: &AtomicPtr>) -> *mut Slot { let ptr = bucket.load(Ordering::Acquire); - if ptr.is_null() { self.initialize_bucket(bucket) } else { ptr } + if ptr.is_null() { Self::initialize_bucket(bucket, self.bucket_idx) } else { ptr } } #[cold] - fn initialize_bucket(&self, bucket: &AtomicPtr>) -> *mut Slot { + #[inline(never)] + fn initialize_bucket(bucket: &AtomicPtr>, bucket_idx: usize) -> *mut Slot { static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); // If we are initializing the bucket, then acquire a global lock. @@ -144,8 +145,8 @@ impl SlotIndex { // OK, now under the allocator lock, if we're still null then it's definitely us that will // initialize this bucket. if ptr.is_null() { - let bucket_layout = - std::alloc::Layout::array::>(self.entries as usize).unwrap(); + let bucket_len = SlotIndex { bucket_idx, index_in_bucket: 0 }.entries(); + let bucket_layout = std::alloc::Layout::array::>(bucket_len).unwrap(); // This is more of a sanity check -- this code is very cold, so it's safe to pay a // little extra cost here. assert!(bucket_layout.size() > 0); @@ -171,7 +172,7 @@ impl SlotIndex { let bucket = unsafe { buckets.get_unchecked(self.bucket_idx) }; let ptr = self.bucket_ptr(bucket); - assert!(self.index_in_bucket < self.entries); + debug_assert!(self.index_in_bucket < self.entries()); // SAFETY: `bucket` was allocated (so <= isize in total bytes) to hold `entries`, so this // must be inbounds. let slot = unsafe { ptr.add(self.index_in_bucket) }; @@ -204,6 +205,31 @@ impl SlotIndex { Err(_) => false, } } + + /// Inserts into the map, given that the slot is unique, so it won't race with other threads. + #[inline] + unsafe fn put_unique(&self, buckets: &[AtomicPtr>; 21], value: V, extra: u32) { + // SAFETY: `bucket_idx` is ilog2(u32).saturating_sub(11), which is at most 21, i.e., + // in-bounds of buckets. + let bucket = unsafe { buckets.get_unchecked(self.bucket_idx) }; + let ptr = self.bucket_ptr(bucket); + + debug_assert!(self.index_in_bucket < self.entries()); + // SAFETY: `bucket` was allocated (so <= isize in total bytes) to hold `entries`, so this + // must be inbounds. + let slot = unsafe { ptr.add(self.index_in_bucket) }; + + // SAFETY: We known our slot is unique as a precondition of this function, so this can't race. + unsafe { + (&raw mut (*slot).value).write(value); + } + + // SAFETY: initialized bucket has zeroed all memory within the bucket, so we are valid for + // AtomicU32 access. + let index_and_lock = unsafe { &(*slot).index_and_lock }; + + index_and_lock.store(extra.checked_add(2).unwrap(), Ordering::Release); + } } /// In-memory cache for queries whose keys are densely-numbered IDs @@ -229,11 +255,11 @@ pub struct VecCache { // Bucket 19: 1073741824 // Bucket 20: 2147483648 // The total number of entries if all buckets are initialized is u32::MAX-1. - buckets: [AtomicPtr>; 21], + buckets: [AtomicPtr>; BUCKETS], // In the compiler's current usage these are only *read* during incremental and self-profiling. // They are an optimization over iterating the full buckets array. - present: [AtomicPtr>; 21], + present: [AtomicPtr>; BUCKETS], len: AtomicUsize, key: PhantomData<(K, I)>, @@ -307,9 +333,11 @@ where let slot_idx = SlotIndex::from_index(key); if slot_idx.put(&self.buckets, value, index.index() as u32) { let present_idx = self.len.fetch_add(1, Ordering::Relaxed); - let slot = SlotIndex::from_index(present_idx as u32); - // We should always be uniquely putting due to `len` fetch_add returning unique values. - assert!(slot.put(&self.present, (), key)); + let slot = SlotIndex::from_index(u32::try_from(present_idx).unwrap()); + // SAFETY: We should always be uniquely putting due to `len` fetch_add returning unique values. + // We can't get here if `len` overflows because `put` will not succeed u32::MAX + 1 times + // as it will run out of slots. + unsafe { slot.put_unique(&self.present, (), key) }; } } @@ -331,6 +359,10 @@ where } } } + + pub fn len(&self) -> usize { + self.len.load(Ordering::Acquire) + } } #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/vec_cache/tests.rs b/compiler/rustc_data_structures/src/vec_cache/tests.rs index 9b60913ec922..f588442eee62 100644 --- a/compiler/rustc_data_structures/src/vec_cache/tests.rs +++ b/compiler/rustc_data_structures/src/vec_cache/tests.rs @@ -68,6 +68,13 @@ fn slot_entries_table() { ); } +#[test] +fn bucket_entries_matches() { + for i in 0..BUCKETS { + assert_eq!(SlotIndex { bucket_idx: i, index_in_bucket: 0 }.entries(), ENTRIES_BY_BUCKET[i]); + } +} + #[test] #[cfg(not(miri))] fn slot_index_exhaustive() { @@ -81,14 +88,18 @@ fn slot_index_exhaustive() { let mut prev = slot_idx; for idx in 1..=u32::MAX { let slot_idx = SlotIndex::from_index(idx); + + // SAFETY: Ensure indices don't go out of bounds of buckets. + assert!(slot_idx.index_in_bucket < slot_idx.entries()); + if prev.bucket_idx == slot_idx.bucket_idx { assert_eq!(prev.index_in_bucket + 1, slot_idx.index_in_bucket); } else { assert_eq!(slot_idx.index_in_bucket, 0); } - assert_eq!(buckets[slot_idx.bucket_idx], slot_idx.entries as u32); - assert_eq!(ENTRIES_BY_BUCKET[slot_idx.bucket_idx], slot_idx.entries, "{}", idx); + assert_eq!(buckets[slot_idx.bucket_idx], slot_idx.entries() as u32); + assert_eq!(ENTRIES_BY_BUCKET[slot_idx.bucket_idx], slot_idx.entries(), "{}", idx); prev = slot_idx; } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 531b9e0c8ff7..10e1b1987194 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -5,50 +5,35 @@ edition = "2024" [dependencies] # tidy-alphabetical-start +anstyle = "1.0.13" jiff = { version = "0.2.5", default-features = false, features = ["std"] } rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } -rustc_ast_lowering = { path = "../rustc_ast_lowering" } -rustc_ast_passes = { path = "../rustc_ast_passes" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } -rustc_attr_parsing = { path = "../rustc_attr_parsing" } -rustc_borrowck = { path = "../rustc_borrowck" } -rustc_builtin_macros = { path = "../rustc_builtin_macros" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_const_eval = { path = "../rustc_const_eval" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir_analysis = { path = "../rustc_hir_analysis" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } -rustc_hir_typeck = { path = "../rustc_hir_typeck" } -rustc_incremental = { path = "../rustc_incremental" } rustc_index = { path = "../rustc_index" } -rustc_infer = { path = "../rustc_infer" } rustc_interface = { path = "../rustc_interface" } +rustc_lexer = { path = "../rustc_lexer" } rustc_lint = { path = "../rustc_lint" } rustc_log = { path = "../rustc_log" } rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } rustc_mir_build = { path = "../rustc_mir_build" } -rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } rustc_mir_transform = { path = "../rustc_mir_transform" } -rustc_monomorphize = { path = "../rustc_monomorphize" } rustc_parse = { path = "../rustc_parse" } -rustc_passes = { path = "../rustc_passes" } -rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } -rustc_privacy = { path = "../rustc_privacy" } rustc_public = { path = "../rustc_public", features = ["rustc_internal"] } -rustc_query_system = { path = "../rustc_query_system" } rustc_resolve = { path = "../rustc_resolve" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -rustc_trait_selection = { path = "../rustc_trait_selection" } -rustc_ty_utils = { path = "../rustc_ty_utils" } serde_json = "1.0.59" shlex = "1.0" tracing = { version = "0.1.35" } diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl deleted file mode 100644 index b62cdc35f513..000000000000 --- a/compiler/rustc_driver_impl/messages.ftl +++ /dev/null @@ -1,29 +0,0 @@ -driver_impl_cant_emit_mir = could not emit MIR: {$error} - -driver_impl_ice = the compiler unexpectedly panicked. this is a bug. -driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url} -driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly -driver_impl_ice_bug_report_update_note = please make sure that you have updated to the latest nightly -driver_impl_ice_exclude_cargo_defaults = some of the compiler flags provided by cargo are hidden - -driver_impl_ice_flags = compiler flags: {$flags} -driver_impl_ice_path = please attach the file at `{$path}` to your bug report -driver_impl_ice_path_error = the ICE couldn't be written to `{$path}`: {$error} -driver_impl_ice_path_error_env = the environment variable `RUSTC_ICE` is set to `{$env_var}` -driver_impl_ice_version = rustc {$version} running on {$triple} - -driver_impl_rlink_corrupt_file = corrupt metadata encountered in `{$file}` - -driver_impl_rlink_empty_version_number = the input does not contain version number - -driver_impl_rlink_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}` - -driver_impl_rlink_no_a_file = rlink must be a file - -driver_impl_rlink_rustc_version_mismatch = .rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}` - -driver_impl_rlink_unable_to_read = failed to read rlink file: `{$err}` - -driver_impl_rlink_wrong_file_type = the input does not look like a .rlink file - -driver_impl_unstable_feature_usage = cannot dump feature usage metrics: {$error} diff --git a/compiler/rustc_driver_impl/src/args.rs b/compiler/rustc_driver_impl/src/args.rs index b0970144c421..d8d55ce14125 100644 --- a/compiler/rustc_driver_impl/src/args.rs +++ b/compiler/rustc_driver_impl/src/args.rs @@ -97,7 +97,6 @@ impl Expander { /// **Note:** This function doesn't interpret argument 0 in any special way. /// If this function is intended to be used with command line arguments, /// `argv[0]` must be removed prior to calling it manually. -#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec { let mut expander = Expander::default(); let mut result = Ok(()); diff --git a/compiler/rustc_driver_impl/src/highlighter.rs b/compiler/rustc_driver_impl/src/highlighter.rs new file mode 100644 index 000000000000..70b73cc29b72 --- /dev/null +++ b/compiler/rustc_driver_impl/src/highlighter.rs @@ -0,0 +1,159 @@ +//! This module provides a syntax highlighter for Rust code. +//! It is used by the `rustc --explain` command. +//! +//! The syntax highlighter uses `rustc_lexer`'s `tokenize` +//! function to parse the Rust code into a `Vec` of tokens. +//! The highlighter then highlights the tokens in the `Vec`, +//! and writes the highlighted output to the buffer. +use std::io::{self, Write}; + +use anstyle::{AnsiColor, Color, Effects, Style}; +use rustc_lexer::{LiteralKind, strip_shebang, tokenize}; + +const PRIMITIVE_TYPES: &'static [&str] = &[ + "i8", "i16", "i32", "i64", "i128", "isize", // signed integers + "u8", "u16", "u32", "u64", "u128", "usize", // unsigned integers + "f32", "f64", // floating point + "char", "bool", // others +]; + +const KEYWORDS: &'static [&str] = &[ + "static", "struct", "super", "trait", "true", "type", "unsafe", "use", "where", "while", "as", + "async", "await", "break", "const", "continue", "crate", "dyn", "else", "enum", "extern", + "false", "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", + "ref", +]; + +const STR_LITERAL_COLOR: AnsiColor = AnsiColor::Green; +const OTHER_LITERAL_COLOR: AnsiColor = AnsiColor::BrightRed; +const DERIVE_COLOR: AnsiColor = AnsiColor::BrightRed; +const KEYWORD_COLOR: AnsiColor = AnsiColor::BrightMagenta; +const TYPE_COLOR: AnsiColor = AnsiColor::Yellow; +const FUNCTION_COLOR: AnsiColor = AnsiColor::Blue; +const USE_COLOR: AnsiColor = AnsiColor::BrightMagenta; +const PRIMITIVE_TYPE_COLOR: AnsiColor = AnsiColor::Cyan; + +/// Highlight a Rust code string and write the highlighted +/// output to the buffer. It serves as a wrapper around +/// `Highlighter::highlight_rustc_lexer`. It is passed to +/// `write_anstream_buf` in the `lib.rs` file. +pub fn highlight(code: &str, buf: &mut Vec) -> io::Result<()> { + let mut highlighter = Highlighter::default(); + highlighter.highlight_rustc_lexer(code, buf) +} + +/// A syntax highlighter for Rust code +/// It is used by the `rustc --explain` command. +#[derive(Default)] +pub struct Highlighter { + /// Used to track if the previous token was a token + /// that warrants the next token to be colored differently + /// + /// For example, the keyword `fn` requires the next token + /// (the function name) to be colored differently. + prev_was_special: bool, + /// Used to track the length of tokens that have been + /// written so far. This is used to find the original + /// lexeme for a token from the code string. + len_accum: usize, +} + +impl Highlighter { + /// Create a new highlighter + pub fn new() -> Self { + Self::default() + } + + /// Highlight a Rust code string and write the highlighted + /// output to the buffer. + pub fn highlight_rustc_lexer(&mut self, code: &str, buf: &mut Vec) -> io::Result<()> { + use rustc_lexer::TokenKind; + + // Remove shebang from code string + let stripped_idx = strip_shebang(code).unwrap_or(0); + let stripped_code = &code[stripped_idx..]; + self.len_accum = stripped_idx; + let len_accum = &mut self.len_accum; + let tokens = tokenize(stripped_code, rustc_lexer::FrontmatterAllowed::No); + for token in tokens { + let len = token.len as usize; + // If the previous token was a special token, and this token is + // not a whitespace token, then it should be colored differently + let token_str = &code[*len_accum..*len_accum + len]; + if self.prev_was_special { + if token_str != " " { + self.prev_was_special = false; + } + let style = Style::new().fg_color(Some(Color::Ansi(AnsiColor::Blue))); + write!(buf, "{style}{token_str}{style:#}")?; + *len_accum += len; + continue; + } + match token.kind { + TokenKind::Ident => { + let mut style = Style::new(); + // Match if an identifier is a (well-known) keyword + if KEYWORDS.contains(&token_str) { + if token_str == "fn" { + self.prev_was_special = true; + } + style = style.fg_color(Some(Color::Ansi(KEYWORD_COLOR))); + } + // The `use` keyword is colored differently + if matches!(token_str, "use") { + style = style.fg_color(Some(Color::Ansi(USE_COLOR))); + } + // This heuristic test is to detect if the identifier is + // a function call. If it is, then the function identifier is + // colored differently. + if code[*len_accum..*len_accum + len + 1].ends_with('(') { + style = style.fg_color(Some(Color::Ansi(FUNCTION_COLOR))); + } + // The `derive` keyword is colored differently. + if token_str == "derive" { + style = style.fg_color(Some(Color::Ansi(DERIVE_COLOR))); + } + // This heuristic test is to detect if the identifier is + // a type. If it is, then the identifier is colored differently. + if matches!(token_str.chars().next().map(|c| c.is_uppercase()), Some(true)) { + style = style.fg_color(Some(Color::Ansi(TYPE_COLOR))); + } + // This if statement is to detect if the identifier is a primitive type. + if PRIMITIVE_TYPES.contains(&token_str) { + style = style.fg_color(Some(Color::Ansi(PRIMITIVE_TYPE_COLOR))); + } + write!(buf, "{style}{token_str}{style:#}")?; + } + + // Color literals + TokenKind::Literal { kind, suffix_start: _ } => { + // Strings -> Green + // Chars -> Green + // Raw strings -> Green + // C strings -> Green + // Byte Strings -> Green + // Other literals -> Bright Red (Orage-esque) + let style = match kind { + LiteralKind::Str { terminated: _ } + | LiteralKind::Char { terminated: _ } + | LiteralKind::RawStr { n_hashes: _ } + | LiteralKind::CStr { terminated: _ } => { + Style::new().fg_color(Some(Color::Ansi(STR_LITERAL_COLOR))) + } + _ => Style::new().fg_color(Some(Color::Ansi(OTHER_LITERAL_COLOR))), + }; + write!(buf, "{style}{token_str}{style:#}")?; + } + _ => { + // All other tokens are dimmed + let style = Style::new() + .fg_color(Some(Color::Ansi(AnsiColor::BrightWhite))) + .effects(Effects::DIMMED); + write!(buf, "{style}{token_str}{style:#}")?; + } + } + *len_accum += len; + } + Ok(()) + } +} diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 0853f638509f..a235d3e0aecd 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable #![feature(decl_macro)] #![feature(panic_backtrace_config)] #![feature(panic_update_hook)] @@ -19,9 +18,9 @@ use std::ffi::OsString; use std::fmt::Write as _; use std::fs::{self, File}; use std::io::{self, IsTerminal, Read, Write}; -use std::panic::{self, PanicHookInfo, catch_unwind}; +use std::panic::{self, PanicHookInfo}; use std::path::{Path, PathBuf}; -use std::process::{self, Command, Stdio}; +use std::process::{Command, ExitCode, Stdio, Termination}; use std::sync::OnceLock; use std::sync::atomic::{AtomicBool, Ordering}; use std::time::Instant; @@ -33,15 +32,16 @@ use rustc_codegen_ssa::{CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{ TimePassesFormat, get_resident_set_size, print_time_passes_entry, }; +pub use rustc_errors::catch_fatal_errors; use rustc_errors::emitter::stderr_destination; -use rustc_errors::registry::Registry; use rustc_errors::translation::Translator; -use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown}; +use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, PResult, markdown}; use rustc_feature::find_gated_cfg; // This avoids a false positive with `-Wunused_crate_dependencies`. // `rust_index` isn't used in this crate's code, but it must be named in the // `Cargo.toml` for the `rustc_randomized_layouts` feature. use rustc_index as _; +use rustc_interface::passes::collect_crate_types; use rustc_interface::util::{self, get_codegen_backend}; use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes}; use rustc_lint::unerased_lint_store; @@ -56,10 +56,10 @@ use rustc_session::config::{ }; use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; -use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target}; +use rustc_session::output::invalid_output_for_target; use rustc_session::{EarlyDiagCtxt, Session, config}; -use rustc_span::FileName; use rustc_span::def_id::LOCAL_CRATE; +use rustc_span::{DUMMY_SP, FileName}; use rustc_target::json::ToJson; use rustc_target::spec::{Target, TargetTuple}; use tracing::trace; @@ -86,6 +86,7 @@ pub mod args; pub mod pretty; #[macro_use] mod print; +pub mod highlighter; mod session_diagnostics; // Keep the OS parts of this `cfg` in sync with the `cfg` on the `libc` @@ -106,48 +107,10 @@ use crate::session_diagnostics::{ RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage, }; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn default_translator() -> Translator { - Translator::with_fallback_bundle(DEFAULT_LOCALE_RESOURCES.to_vec(), false) + Translator::new() } -pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ - // tidy-alphabetical-start - crate::DEFAULT_LOCALE_RESOURCE, - rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE, - rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, - rustc_attr_parsing::DEFAULT_LOCALE_RESOURCE, - rustc_borrowck::DEFAULT_LOCALE_RESOURCE, - rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, - rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE, - rustc_const_eval::DEFAULT_LOCALE_RESOURCE, - rustc_errors::DEFAULT_LOCALE_RESOURCE, - rustc_expand::DEFAULT_LOCALE_RESOURCE, - rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, - rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE, - rustc_incremental::DEFAULT_LOCALE_RESOURCE, - rustc_infer::DEFAULT_LOCALE_RESOURCE, - rustc_interface::DEFAULT_LOCALE_RESOURCE, - rustc_lint::DEFAULT_LOCALE_RESOURCE, - rustc_metadata::DEFAULT_LOCALE_RESOURCE, - rustc_middle::DEFAULT_LOCALE_RESOURCE, - rustc_mir_build::DEFAULT_LOCALE_RESOURCE, - rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE, - rustc_mir_transform::DEFAULT_LOCALE_RESOURCE, - rustc_monomorphize::DEFAULT_LOCALE_RESOURCE, - rustc_parse::DEFAULT_LOCALE_RESOURCE, - rustc_passes::DEFAULT_LOCALE_RESOURCE, - rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, - rustc_privacy::DEFAULT_LOCALE_RESOURCE, - rustc_query_system::DEFAULT_LOCALE_RESOURCE, - rustc_resolve::DEFAULT_LOCALE_RESOURCE, - rustc_session::DEFAULT_LOCALE_RESOURCE, - rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, - rustc_ty_utils::DEFAULT_LOCALE_RESOURCE, - // tidy-alphabetical-end -]; - /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -208,10 +171,6 @@ impl Callbacks for TimePassesCallbacks { } } -pub fn diagnostics_registry() -> Registry { - Registry::new(rustc_errors::codes::DIAGNOSTICS) -} - /// This is the primary entry point for rustc. pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) { let mut default_early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); @@ -228,8 +187,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) let args = args::arg_expand_all(&default_early_dcx, at_args); - let Some(matches) = handle_options(&default_early_dcx, &args) else { - return; + let (matches, help_only) = match handle_options(&default_early_dcx, &args) { + HandledOptions::None => return, + HandledOptions::Normal(matches) => (matches, false), + HandledOptions::HelpOnly(matches) => (matches, true), }; let sopts = config::build_session_options(&mut default_early_dcx, &matches); @@ -237,7 +198,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) let ice_file = ice_path_with_config(Some(&sopts.unstable_opts)).clone(); if let Some(ref code) = matches.opt_str("explain") { - handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color); + handle_explain(&default_early_dcx, code, sopts.color); return; } @@ -256,7 +217,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) output_dir: odir, ice_file, file_loader: None, - locale_resources: DEFAULT_LOCALE_RESOURCES.to_vec(), lint_caps: Default::default(), psess_created: None, hash_untracked_state: None, @@ -264,7 +224,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) override_queries: None, extra_symbols: Vec::new(), make_codegen_backend: None, - registry: diagnostics_registry(), using_internal_features: &USING_INTERNAL_FEATURES, }; @@ -291,12 +250,16 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) return early_exit(); } + // We have now handled all help options, exit + if help_only { + return early_exit(); + } + if print_crate_info(codegen_backend, sess, has_input) == Compilation::Stop { return early_exit(); } if !has_input { - #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal("no input filename given"); // this is fatal } @@ -460,12 +423,12 @@ pub enum Compilation { Continue, } -fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, color: ColorConfig) { +fn handle_explain(early_dcx: &EarlyDiagCtxt, code: &str, color: ColorConfig) { // Allow "E0123" or "0123" form. let upper_cased_code = code.to_ascii_uppercase(); if let Ok(code) = upper_cased_code.trim_prefix('E').parse::() && code <= ErrCode::MAX_AS_U32 - && let Ok(description) = registry.try_find_description(ErrCode::from_u32(code)) + && let Ok(description) = rustc_errors::codes::try_find_description(ErrCode::from_u32(code)) { let mut is_in_code_block = false; let mut text = String::new(); @@ -483,10 +446,18 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col } text.push('\n'); } + + // If output is a terminal, use a pager to display the content. if io::stdout().is_terminal() { show_md_content_with_pager(&text, color); } else { - safe_print!("{text}"); + // Otherwise, if the user has requested colored output + // print the content in color, else print the md content. + if color == ColorConfig::Always { + show_colored_md_content(&text); + } else { + safe_print!("{text}"); + } } } else { early_dcx.early_fatal(format!("{code} is not a valid error code")); @@ -521,11 +492,15 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { let mdstream = markdown::MdStream::parse_str(content); let bufwtr = markdown::create_stdout_bufwtr(); let mut mdbuf = Vec::new(); - if mdstream.write_anstream_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None } + if mdstream.write_anstream_buf(&mut mdbuf, Some(&highlighter::highlight)).is_ok() { + Some((bufwtr, mdbuf)) + } else { + None + } }; // Try to print via the pager, pretty output if possible. - let pager_res: Option<()> = try { + let pager_res = try { let mut pager = cmd.stdin(Stdio::piped()).spawn().ok()?; let pager_stdin = pager.stdin.as_mut()?; @@ -552,6 +527,33 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { safe_print!("{content}"); } +/// Prints the markdown content with colored output. +/// +/// This function is used when the output is not a terminal, +/// but the user has requested colored output with `--color=always`. +fn show_colored_md_content(content: &str) { + // Try to prettify the raw markdown text. + let mut pretty_data = { + let mdstream = markdown::MdStream::parse_str(content); + let bufwtr = markdown::create_stdout_bufwtr(); + let mut mdbuf = Vec::new(); + if mdstream.write_anstream_buf(&mut mdbuf, Some(&highlighter::highlight)).is_ok() { + Some((bufwtr, mdbuf)) + } else { + None + } + }; + + if let Some((bufwtr, mdbuf)) = &mut pretty_data + && bufwtr.write_all(&mdbuf).is_ok() + { + return; + } + + // Everything failed. Print the raw markdown text. + safe_print!("{content}"); +} + fn process_rlink(sess: &Session, compiler: &interface::Compiler) { assert!(sess.opts.unstable_opts.link_only); let dcx = sess.dcx(); @@ -608,7 +610,6 @@ fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) { safe_println!("{}", String::from_utf8(v).unwrap()); } Input::Str { .. } => { - #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal("cannot list metadata for stdin"); } } @@ -688,6 +689,7 @@ fn print_crate_info( &codegen_backend.supported_crate_types(sess), codegen_backend.name(), attrs, + DUMMY_SP, ); for &style in &crate_types { let fname = rustc_session::output::filename_for_input( @@ -765,30 +767,35 @@ fn print_crate_info( for (name, expected_values) in &sess.psess.check_config.expecteds { use crate::config::ExpectedValues; match expected_values { - ExpectedValues::Any => check_cfgs.push(format!("{name}=any()")), + ExpectedValues::Any => { + check_cfgs.push(format!("cfg({name}, values(any()))")) + } ExpectedValues::Some(values) => { - if !values.is_empty() { - check_cfgs.extend(values.iter().map(|value| { + let mut values: Vec<_> = values + .iter() + .map(|value| { if let Some(value) = value { - format!("{name}=\"{value}\"") + format!("\"{value}\"") } else { - name.to_string() + "none()".to_string() } - })) - } else { - check_cfgs.push(format!("{name}=")) - } + }) + .collect(); + + values.sort_unstable(); + + let values = values.join(", "); + + check_cfgs.push(format!("cfg({name}, values({values}))")) } } } check_cfgs.sort_unstable(); - if !sess.psess.check_config.exhaustive_names { - if !sess.psess.check_config.exhaustive_values { - println_info!("any()=any()"); - } else { - println_info!("any()"); - } + if !sess.psess.check_config.exhaustive_names + && sess.psess.check_config.exhaustive_values + { + println_info!("cfg(any())"); } for check_cfg in check_cfgs { println_info!("{check_cfg}"); @@ -798,8 +805,11 @@ fn print_crate_info( let calling_conventions = rustc_abi::all_names(); println_info!("{}", calling_conventions.join("\n")); } + BackendHasZstd => { + let has_zstd: bool = codegen_backend.has_zstd(); + println_info!("{has_zstd}"); + } RelocationModels - | BackendHasZstd | CodeModels | TlsModels | TargetCPUs @@ -827,12 +837,11 @@ fn print_crate_info( sess.apple_deployment_target().fmt_pretty(), ) } else { - #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal("only Apple targets currently support deployment version info") } } SupportedCrateTypes => { - let supported_crate_types = CRATE_TYPES + let supported_crate_types = CrateType::all() .iter() .filter(|(_, crate_type)| !invalid_output_for_target(sess, *crate_type)) .filter(|(_, crate_type)| *crate_type != CrateType::Sdylib) @@ -1089,7 +1098,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) -> // Don't handle -W help here, because we might first load additional lints. let debug_flags = matches.opt_strs("Z"); if debug_flags.iter().any(|x| *x == "help") { - describe_debug_flags(); + describe_unstable_flags(); return true; } @@ -1121,15 +1130,16 @@ fn get_backend_from_raw_matches( let backend_name = debug_flags .iter() .find_map(|x| x.strip_prefix("codegen-backend=").or(x.strip_prefix("codegen_backend="))); + let unstable_options = debug_flags.iter().find(|x| *x == "unstable-options").is_some(); let target = parse_target_triple(early_dcx, matches); let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from)); - let target = config::build_target_config(early_dcx, &target, sysroot.path()); + let target = config::build_target_config(early_dcx, &target, sysroot.path(), unstable_options); get_codegen_backend(early_dcx, &sysroot, backend_name, &target) } -fn describe_debug_flags() { - safe_println!("\nAvailable options:\n"); +fn describe_unstable_flags() { + safe_println!("\nAvailable unstable options:\n"); print_flag_list("-Z", config::Z_OPTIONS); } @@ -1153,6 +1163,16 @@ fn print_flag_list(cmdline_opt: &str, flag_list: &[OptionDesc]) { } } +pub enum HandledOptions { + /// Parsing failed, or we parsed a flag causing an early exit + None, + /// Successful parsing + Normal(getopts::Matches), + /// Parsing succeeded, but we received one or more 'help' flags + /// The compiler should proceed only until a possible `-W help` flag has been processed + HelpOnly(getopts::Matches), +} + /// Process command line options. Emits messages as appropriate. If compilation /// should continue, returns a getopts::Matches object parsed from args, /// otherwise returns `None`. @@ -1180,7 +1200,7 @@ fn print_flag_list(cmdline_opt: &str, flag_list: &[OptionDesc]) { /// This does not need to be `pub` for rustc itself, but @chaosite needs it to /// be public when using rustc as a library, see /// -pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option { +pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> HandledOptions { // Parse with *all* options defined in the compiler, we don't worry about // option stability here we just want to parse as much as possible. let mut options = getopts::Options::new(); @@ -1226,26 +1246,69 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option bool { + let opt_pos = |opt| matches.opt_positions(opt).first().copied(); + let opt_help_pos = |opt| { + matches + .opt_strs_pos(opt) + .iter() + .filter_map(|(pos, oval)| if oval == "help" { Some(*pos) } else { None }) + .next() + }; + let help_pos = if args.is_empty() { Some(0) } else { opt_pos("h").or_else(|| opt_pos("help")) }; + let zhelp_pos = opt_help_pos("Z"); + let chelp_pos = opt_help_pos("C"); + let print_help = || { + // Only show unstable options in --help if we accept unstable options. + let unstable_enabled = nightly_options::is_unstable_enabled(&matches); + let nightly_build = nightly_options::match_is_nightly_build(&matches); + usage(matches.opt_present("verbose"), unstable_enabled, nightly_build); + }; + + let mut helps = [ + (help_pos, &print_help as &dyn Fn()), + (zhelp_pos, &describe_unstable_flags), + (chelp_pos, &describe_codegen_flags), + ]; + helps.sort_by_key(|(pos, _)| pos.clone()); + let mut printed_any = false; + for printer in helps.iter().filter_map(|(pos, func)| pos.is_some().then_some(func)) { + printer(); + printed_any = true; + } + printed_any } /// Warn if `-o` is used without a space between the flag name and the value @@ -1307,27 +1370,12 @@ fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> { parser.parse_inner_attributes() } -/// Runs a closure and catches unwinds triggered by fatal errors. -/// -/// The compiler currently unwinds with a special sentinel value to abort -/// compilation on fatal errors. This function catches that sentinel and turns -/// the panic into a `Result` instead. -pub fn catch_fatal_errors R, R>(f: F) -> Result { - catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { - if value.is::() { - FatalError - } else { - panic::resume_unwind(value); - } - }) -} - /// Variant of `catch_fatal_errors` for the `interface::Result` return type /// that also computes the exit code. -pub fn catch_with_exit_code(f: impl FnOnce()) -> i32 { +pub fn catch_with_exit_code(f: impl FnOnce() -> T) -> ExitCode { match catch_fatal_errors(f) { - Ok(()) => EXIT_SUCCESS, - _ => EXIT_FAILURE, + Ok(status) => status.report(), + _ => ExitCode::FAILURE, } } @@ -1477,11 +1525,12 @@ fn report_ice( extra_info: fn(&DiagCtxt), using_internal_features: &AtomicBool, ) { - let translator = default_translator(); - let emitter = Box::new(rustc_errors::emitter::HumanEmitter::new( - stderr_destination(rustc_errors::ColorConfig::Auto), - translator, - )); + let translator = Translator::new(); + let emitter = + Box::new(rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter::new( + stderr_destination(rustc_errors::ColorConfig::Auto), + translator, + )); let dcx = rustc_errors::DiagCtxt::new(emitter); let dcx = dcx.handle(); @@ -1528,15 +1577,15 @@ fn report_ice( .map(PathBuf::from) .map(|env_var| session_diagnostics::IcePathErrorEnv { env_var }), }); - dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple }); None } } } else { - dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple }); None }; + dcx.emit_note(session_diagnostics::IceVersion { version, triple: tuple }); + if let Some((flags, excluded_cargo_defaults)) = rustc_session::utils::extra_compiler_flags() { dcx.emit_note(session_diagnostics::IceFlags { flags: flags.join(" ") }); if excluded_cargo_defaults { @@ -1611,7 +1660,7 @@ pub fn install_ctrlc_handler() { .expect("Unable to install ctrlc handler"); } -pub fn main() -> ! { +pub fn main() -> ExitCode { let start_time = Instant::now(); let start_rss = get_resident_set_size(); @@ -1631,5 +1680,5 @@ pub fn main() -> ! { print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss, format); } - process::exit(exit_code) + exit_code } diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 1604b704033b..962d035db862 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -181,7 +181,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { } fn get_source(sess: &Session) -> (String, FileName) { - let src_name = sess.io.input.source_name(); + let src_name = sess.io.input.file_name(&sess); let src = String::clone( sess.source_map() .get_source_file(&src_name) diff --git a/compiler/rustc_driver_impl/src/session_diagnostics.rs b/compiler/rustc_driver_impl/src/session_diagnostics.rs index 774221fd396a..97972185ebc4 100644 --- a/compiler/rustc_driver_impl/src/session_diagnostics.rs +++ b/compiler/rustc_driver_impl/src/session_diagnostics.rs @@ -3,82 +3,88 @@ use std::error::Error; use rustc_macros::{Diagnostic, Subdiagnostic}; #[derive(Diagnostic)] -#[diag(driver_impl_cant_emit_mir)] +#[diag("could not emit MIR: {$error}")] pub struct CantEmitMIR { pub error: std::io::Error, } #[derive(Diagnostic)] -#[diag(driver_impl_rlink_unable_to_read)] +#[diag("failed to read rlink file: `{$err}`")] pub(crate) struct RlinkUnableToRead { pub err: std::io::Error, } #[derive(Diagnostic)] -#[diag(driver_impl_rlink_wrong_file_type)] +#[diag("the input does not look like a .rlink file")] pub(crate) struct RLinkWrongFileType; #[derive(Diagnostic)] -#[diag(driver_impl_rlink_empty_version_number)] +#[diag("the input does not contain version number")] pub(crate) struct RLinkEmptyVersionNumber; #[derive(Diagnostic)] -#[diag(driver_impl_rlink_encoding_version_mismatch)] +#[diag( + ".rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}`" +)] pub(crate) struct RLinkEncodingVersionMismatch { pub version_array: String, pub rlink_version: u32, } #[derive(Diagnostic)] -#[diag(driver_impl_rlink_rustc_version_mismatch)] +#[diag( + ".rlink file was produced by rustc version `{$rustc_version}`, but the current version is `{$current_version}`" +)] pub(crate) struct RLinkRustcVersionMismatch<'a> { pub rustc_version: String, pub current_version: &'a str, } #[derive(Diagnostic)] -#[diag(driver_impl_rlink_no_a_file)] +#[diag("rlink must be a file")] pub(crate) struct RlinkNotAFile; #[derive(Diagnostic)] -#[diag(driver_impl_rlink_corrupt_file)] +#[diag("corrupt metadata encountered in `{$file}`")] pub(crate) struct RlinkCorruptFile<'a> { pub file: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(driver_impl_ice)] +#[diag("the compiler unexpectedly panicked. This is a bug")] pub(crate) struct Ice; #[derive(Diagnostic)] -#[diag(driver_impl_ice_bug_report)] +#[diag("we would appreciate a bug report: {$bug_report_url}")] pub(crate) struct IceBugReport<'a> { pub bug_report_url: &'a str, } #[derive(Diagnostic)] -#[diag(driver_impl_ice_bug_report_update_note)] +#[diag("please make sure that you have updated to the latest nightly")] pub(crate) struct UpdateNightlyNote; #[derive(Diagnostic)] -#[diag(driver_impl_ice_bug_report_internal_feature)] +#[diag( + "using internal features is not supported and expected to cause internal compiler errors when used incorrectly" +)] pub(crate) struct IceBugReportInternalFeature; #[derive(Diagnostic)] -#[diag(driver_impl_ice_version)] +#[diag("rustc {$version} running on {$triple}")] pub(crate) struct IceVersion<'a> { pub version: &'a str, pub triple: &'a str, } #[derive(Diagnostic)] -#[diag(driver_impl_ice_path)] +#[diag("please attach the file at `{$path}` to your bug report")] pub(crate) struct IcePath { pub path: std::path::PathBuf, } #[derive(Diagnostic)] -#[diag(driver_impl_ice_path_error)] +#[diag("the ICE couldn't be written to `{$path}`: {$error}")] pub(crate) struct IcePathError { pub path: std::path::PathBuf, pub error: String, @@ -87,23 +93,23 @@ pub(crate) struct IcePathError { } #[derive(Subdiagnostic)] -#[note(driver_impl_ice_path_error_env)] +#[note("the environment variable `RUSTC_ICE` is set to `{$env_var}`")] pub(crate) struct IcePathErrorEnv { pub env_var: std::path::PathBuf, } #[derive(Diagnostic)] -#[diag(driver_impl_ice_flags)] +#[diag("compiler flags: {$flags}")] pub(crate) struct IceFlags { pub flags: String, } #[derive(Diagnostic)] -#[diag(driver_impl_ice_exclude_cargo_defaults)] +#[diag("some of the compiler flags provided by cargo are hidden")] pub(crate) struct IceExcludeCargoDefaults; #[derive(Diagnostic)] -#[diag(driver_impl_unstable_feature_usage)] +#[diag("cannot dump feature usage metrics: {$error}")] pub(crate) struct UnstableFeatureUsage { pub error: Box, } diff --git a/compiler/rustc_error_codes/src/error_codes/E0010.md b/compiler/rustc_error_codes/src/error_codes/E0010.md index f03f8a6605f6..3ede08ee8f62 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0010.md +++ b/compiler/rustc_error_codes/src/error_codes/E0010.md @@ -1,9 +1,11 @@ +#### Note: this error code is no longer emitted by the compiler. + The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time. Erroneous code example: -```compile_fail,E0010 +```ignore (no longer emitted) const CON : Vec = vec![1, 2, 3]; ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0264.md b/compiler/rustc_error_codes/src/error_codes/E0264.md index 33ddf3405acc..b8d0f7d4d6af 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0264.md +++ b/compiler/rustc_error_codes/src/error_codes/E0264.md @@ -7,8 +7,8 @@ Erroneous code example: #![allow(internal_features)] extern "C" { - #[lang = "cake"] // error: unknown external lang item: `cake` - fn cake(); + #[lang = "copy"] // error: unknown external lang item: `copy` + fn copy(); } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0423.md b/compiler/rustc_error_codes/src/error_codes/E0423.md index a98ada17a469..4af17b1221b9 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0423.md +++ b/compiler/rustc_error_codes/src/error_codes/E0423.md @@ -44,3 +44,14 @@ fn h1() -> i32 { // did you mean `a::I`? } ``` + +### Enum types used as values + +Enums are types and cannot be used directly as values. + +```compile_fail,E0423 +fn main(){ + let x = Option::; + //~^ ERROR expected value,found enum `Option` +} +``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0536.md b/compiler/rustc_error_codes/src/error_codes/E0536.md index c1f43fa741cf..7603be4fcc93 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0536.md +++ b/compiler/rustc_error_codes/src/error_codes/E0536.md @@ -1,3 +1,5 @@ +#### Note: this error code is no longer emitted by the compiler. + The `not` cfg-predicate was malformed. Erroneous code example (using `cargo doc`): diff --git a/compiler/rustc_error_codes/src/error_codes/E0541.md b/compiler/rustc_error_codes/src/error_codes/E0541.md index 96334088feee..f1f97b39fa28 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0541.md +++ b/compiler/rustc_error_codes/src/error_codes/E0541.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + An unknown meta item was used. Erroneous code example: -```compile_fail,E0541 +```compile_fail (no longer emitted) #[deprecated( since="1.0.0", // error: unknown meta item diff --git a/compiler/rustc_error_codes/src/error_codes/E0570.md b/compiler/rustc_error_codes/src/error_codes/E0570.md index 355e71ffb432..e8a7200c1d05 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0570.md +++ b/compiler/rustc_error_codes/src/error_codes/E0570.md @@ -1,7 +1,7 @@ The requested ABI is unsupported by the current target. -The rust compiler maintains for each target a list of unsupported ABIs on -that target. If an ABI is present in such a list this usually means that the +The Rust compiler maintains a list of unsupported ABIs for each target. +If an ABI is present in such a list, this usually means that the target / ABI combination is currently unsupported by llvm. If necessary, you can circumvent this check using custom target specifications. diff --git a/compiler/rustc_error_codes/src/error_codes/E0773.md b/compiler/rustc_error_codes/src/error_codes/E0773.md index 5ebb43c6683e..91cf005d5471 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0773.md +++ b/compiler/rustc_error_codes/src/error_codes/E0773.md @@ -1,4 +1,4 @@ -#### this error code is no longer emitted by the compiler. +#### Note: this error code is no longer emitted by the compiler. This was triggered when multiple macro definitions used the same `#[rustc_builtin_macro(..)]`. This is no longer an error. diff --git a/compiler/rustc_error_codes/src/error_codes/E0778.md b/compiler/rustc_error_codes/src/error_codes/E0778.md index 467362dca58f..4bdf85451c9b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0778.md +++ b/compiler/rustc_error_codes/src/error_codes/E0778.md @@ -1,8 +1,9 @@ +#### Note: this error code is no longer emitted by the compiler The `instruction_set` attribute was malformed. Erroneous code example: -```compile_fail,E0778 +```compile_fail #![feature(isa_attribute)] #[instruction_set()] // error: expected one argument diff --git a/compiler/rustc_error_codes/src/error_codes/E0779.md b/compiler/rustc_error_codes/src/error_codes/E0779.md index 146e20c26265..036931379a06 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0779.md +++ b/compiler/rustc_error_codes/src/error_codes/E0779.md @@ -1,8 +1,9 @@ +#### Note: this error code is no longer emitted by the compiler An unknown argument was given to the `instruction_set` attribute. Erroneous code example: -```compile_fail,E0779 +```compile_fail #![feature(isa_attribute)] #[instruction_set(intel::x64)] // error: invalid argument diff --git a/compiler/rustc_error_codes/src/error_codes/E0806.md b/compiler/rustc_error_codes/src/error_codes/E0806.md new file mode 100644 index 000000000000..e4a89b92354f --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0806.md @@ -0,0 +1,68 @@ +An externally implementable item is not compatible with its declaration. + +Erroneous code example: + +```rust,edition2021,compile_fail,E0806 +#![feature(extern_item_impls)] + +#[eii(foo)] +fn x(); + +#[foo] +fn y(a: u64) -> u64 { +//~^ ERROR E0806 + a +} + + +fn main() {} +``` + +The error here is caused by the fact that `y` implements the +externally implementable item `foo`. +It can only do so if the signature of the implementation `y` matches +that of the declaration of `foo`. +So, to fix this, `y`'s signature must be changed to match that of `x`: + +```rust,edition2021 +#![feature(extern_item_impls)] + +#[eii(foo)] +fn x(); + +#[foo] +fn y() {} + + +fn main() {} +``` + +One common way this can be triggered is by using the wrong +signature for `#[panic_handler]`. +The signature is provided by `core`. + +```rust,edition2021,ignore +#![no_std] + +#[panic_handler] +fn on_panic() -> ! { +//~^ ERROR E0806 + + loop {} +} + +fn main() {} +``` + +Should be: + +```rust,edition2021,ignore +#![no_std] + +#[panic_handler] +fn on_panic(info: &core::panic::PanicInfo<'_>) -> ! { + loop {} +} + +fn main() {} +``` diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index f63f89748884..0537ba23de94 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -18,533 +18,533 @@ // Also, the contents of this macro is checked by tidy (in `check_error_codes_docs`). If you change // the macro syntax you will need to change tidy as well. // -// Both columns are necessary because it's not possible in Rust to create a new identifier such as -// `E0123` from an integer literal such as `0123`, unfortunately. -// -// Do *not* remove entries from this list. Instead, just add a note th the corresponding markdown +// Do *not* remove entries from this list. Instead, just add a note to the corresponding markdown // file saying that this error is not emitted by the compiler any more (see E0001.md for an -// example), and remove all code examples that do not build any more. +// example), and remove all code examples that do not build any more by marking them +// with `ignore (no longer emitted)`. #[macro_export] +#[rustfmt::skip] macro_rules! error_codes { ($macro:path) => ( $macro!( -E0001: 0001, -E0002: 0002, -E0004: 0004, -E0005: 0005, -E0007: 0007, -E0009: 0009, -E0010: 0010, -E0013: 0013, -E0014: 0014, -E0015: 0015, -E0023: 0023, -E0025: 0025, -E0026: 0026, -E0027: 0027, -E0029: 0029, -E0030: 0030, -E0033: 0033, -E0034: 0034, -E0038: 0038, -E0040: 0040, -E0044: 0044, -E0045: 0045, -E0046: 0046, -E0049: 0049, -E0050: 0050, -E0053: 0053, -E0054: 0054, -E0055: 0055, -E0057: 0057, -E0059: 0059, -E0060: 0060, -E0061: 0061, -E0062: 0062, -E0063: 0063, -E0067: 0067, -E0069: 0069, -E0070: 0070, -E0071: 0071, -E0072: 0072, -E0073: 0073, -E0074: 0074, -E0075: 0075, -E0076: 0076, -E0077: 0077, -E0080: 0080, -E0081: 0081, -E0084: 0084, -E0087: 0087, -E0088: 0088, -E0089: 0089, -E0090: 0090, -E0091: 0091, -E0092: 0092, -E0093: 0093, -E0094: 0094, -E0106: 0106, -E0107: 0107, -E0109: 0109, -E0110: 0110, -E0116: 0116, -E0117: 0117, -E0118: 0118, -E0119: 0119, -E0120: 0120, -E0121: 0121, -E0124: 0124, -E0128: 0128, -E0130: 0130, -E0131: 0131, -E0132: 0132, -E0133: 0133, -E0136: 0136, -E0137: 0137, -E0138: 0138, -E0139: 0139, -E0152: 0152, -E0154: 0154, -E0158: 0158, -E0161: 0161, -E0162: 0162, -E0164: 0164, -E0165: 0165, -E0170: 0170, -E0178: 0178, -E0183: 0183, -E0184: 0184, -E0185: 0185, -E0186: 0186, -E0191: 0191, -E0192: 0192, -E0193: 0193, -E0195: 0195, -E0197: 0197, -E0198: 0198, -E0199: 0199, -E0200: 0200, -E0201: 0201, -E0203: 0203, -E0204: 0204, -E0205: 0205, -E0206: 0206, -E0207: 0207, -E0208: 0208, -E0210: 0210, -E0211: 0211, -E0212: 0212, -E0214: 0214, -E0220: 0220, -E0221: 0221, -E0222: 0222, -E0223: 0223, -E0224: 0224, -E0225: 0225, -E0226: 0226, -E0227: 0227, -E0228: 0228, -E0229: 0229, -E0230: 0230, -E0231: 0231, -E0232: 0232, -E0243: 0243, -E0244: 0244, -E0251: 0251, -E0252: 0252, -E0253: 0253, -E0254: 0254, -E0255: 0255, -E0256: 0256, -E0259: 0259, -E0260: 0260, -E0261: 0261, -E0262: 0262, -E0263: 0263, -E0264: 0264, -E0267: 0267, -E0268: 0268, -E0271: 0271, -E0275: 0275, -E0276: 0276, -E0277: 0277, -E0281: 0281, -E0282: 0282, -E0283: 0283, -E0284: 0284, -E0297: 0297, -E0301: 0301, -E0302: 0302, -E0303: 0303, -E0307: 0307, -E0308: 0308, -E0309: 0309, -E0310: 0310, -E0311: 0311, -E0312: 0312, -E0316: 0316, -E0317: 0317, -E0320: 0320, -E0321: 0321, -E0322: 0322, -E0323: 0323, -E0324: 0324, -E0325: 0325, -E0326: 0326, -E0328: 0328, -E0329: 0329, -E0364: 0364, -E0365: 0365, -E0366: 0366, -E0367: 0367, -E0368: 0368, -E0369: 0369, -E0370: 0370, -E0371: 0371, -E0373: 0373, -E0374: 0374, -E0375: 0375, -E0376: 0376, -E0377: 0377, -E0378: 0378, -E0379: 0379, -E0380: 0380, -E0381: 0381, -E0382: 0382, -E0383: 0383, -E0384: 0384, -E0386: 0386, -E0387: 0387, -E0388: 0388, -E0389: 0389, -E0390: 0390, -E0391: 0391, -E0392: 0392, -E0393: 0393, -E0398: 0398, -E0399: 0399, -E0401: 0401, -E0403: 0403, -E0404: 0404, -E0405: 0405, -E0407: 0407, -E0408: 0408, -E0409: 0409, -E0411: 0411, -E0412: 0412, -E0415: 0415, -E0416: 0416, -E0422: 0422, -E0423: 0423, -E0424: 0424, -E0425: 0425, -E0426: 0426, -E0428: 0428, -E0429: 0429, -E0430: 0430, -E0431: 0431, -E0432: 0432, -E0433: 0433, -E0434: 0434, -E0435: 0435, -E0436: 0436, -E0437: 0437, -E0438: 0438, -E0439: 0439, -E0445: 0445, -E0446: 0446, -E0447: 0447, -E0448: 0448, -E0449: 0449, -E0451: 0451, -E0452: 0452, -E0453: 0453, -E0454: 0454, -E0455: 0455, -E0457: 0457, -E0458: 0458, -E0459: 0459, -E0460: 0460, -E0461: 0461, -E0462: 0462, -E0463: 0463, -E0464: 0464, -E0466: 0466, -E0468: 0468, -E0469: 0469, -E0472: 0472, -E0476: 0476, -E0477: 0477, -E0478: 0478, -E0482: 0482, -E0491: 0491, -E0492: 0492, -E0493: 0493, -E0495: 0495, -E0496: 0496, -E0497: 0497, -E0498: 0498, -E0499: 0499, -E0500: 0500, -E0501: 0501, -E0502: 0502, -E0503: 0503, -E0504: 0504, -E0505: 0505, -E0506: 0506, -E0507: 0507, -E0508: 0508, -E0509: 0509, -E0510: 0510, -E0511: 0511, -E0512: 0512, -E0514: 0514, -E0515: 0515, -E0516: 0516, -E0517: 0517, -E0518: 0518, -E0519: 0519, -E0520: 0520, -E0521: 0521, -E0522: 0522, -E0523: 0523, -E0524: 0524, -E0525: 0525, -E0527: 0527, -E0528: 0528, -E0529: 0529, -E0530: 0530, -E0531: 0531, -E0532: 0532, -E0533: 0533, -E0534: 0534, -E0535: 0535, -E0536: 0536, -E0537: 0537, -E0538: 0538, -E0539: 0539, -E0541: 0541, -E0542: 0542, -E0543: 0543, -E0544: 0544, -E0545: 0545, -E0546: 0546, -E0547: 0547, -E0549: 0549, -E0550: 0550, -E0551: 0551, -E0552: 0552, -E0554: 0554, -E0556: 0556, -E0557: 0557, -E0559: 0559, -E0560: 0560, -E0561: 0561, -E0562: 0562, -E0565: 0565, -E0566: 0566, -E0567: 0567, -E0568: 0568, -E0569: 0569, -E0570: 0570, -E0571: 0571, -E0572: 0572, -E0573: 0573, -E0574: 0574, -E0575: 0575, -E0576: 0576, -E0577: 0577, -E0578: 0578, -E0579: 0579, -E0580: 0580, -E0581: 0581, -E0582: 0582, -E0583: 0583, -E0584: 0584, -E0585: 0585, -E0586: 0586, -E0587: 0587, -E0588: 0588, -E0589: 0589, -E0590: 0590, -E0591: 0591, -E0592: 0592, -E0593: 0593, -E0594: 0594, -E0595: 0595, -E0596: 0596, -E0597: 0597, -E0599: 0599, -E0600: 0600, -E0601: 0601, -E0602: 0602, -E0603: 0603, -E0604: 0604, -E0605: 0605, -E0606: 0606, -E0607: 0607, -E0608: 0608, -E0609: 0609, -E0610: 0610, -E0614: 0614, -E0615: 0615, -E0616: 0616, -E0617: 0617, -E0618: 0618, -E0619: 0619, -E0620: 0620, -E0621: 0621, -E0622: 0622, // REMOVED: rustc-intrinsic ABI was removed -E0623: 0623, -E0624: 0624, -E0625: 0625, -E0626: 0626, -E0627: 0627, -E0628: 0628, -E0631: 0631, -E0632: 0632, -E0633: 0633, -E0634: 0634, -E0635: 0635, -E0636: 0636, -E0637: 0637, -E0638: 0638, -E0639: 0639, -E0640: 0640, -E0641: 0641, -E0642: 0642, -E0643: 0643, -E0644: 0644, -E0646: 0646, -E0647: 0647, -E0648: 0648, -E0657: 0657, -E0658: 0658, -E0659: 0659, -E0660: 0660, -E0661: 0661, -E0662: 0662, -E0663: 0663, -E0664: 0664, -E0665: 0665, -E0666: 0666, -E0667: 0667, -E0668: 0668, -E0669: 0669, -E0670: 0670, -E0671: 0671, -E0687: 0687, -E0688: 0688, -E0689: 0689, -E0690: 0690, -E0691: 0691, -E0692: 0692, -E0693: 0693, -E0695: 0695, -E0696: 0696, -E0697: 0697, -E0698: 0698, -E0699: 0699, // REMOVED: merged into generic inference var error -E0700: 0700, -E0701: 0701, -E0703: 0703, -E0704: 0704, -E0705: 0705, -E0706: 0706, -E0708: 0708, -E0710: 0710, -E0712: 0712, -E0713: 0713, -E0714: 0714, -E0715: 0715, -E0716: 0716, -E0711: 0711, -E0717: 0717, -E0718: 0718, -E0719: 0719, -E0720: 0720, -E0722: 0722, -E0724: 0724, -E0725: 0725, -E0726: 0726, -E0727: 0727, -E0728: 0728, -E0729: 0729, -E0730: 0730, -E0731: 0731, -E0732: 0732, -E0733: 0733, -E0734: 0734, -E0735: 0735, -E0736: 0736, -E0737: 0737, -E0739: 0739, -E0740: 0740, -E0741: 0741, -E0742: 0742, -E0743: 0743, -E0744: 0744, -E0745: 0745, -E0746: 0746, -E0747: 0747, -E0748: 0748, -E0749: 0749, -E0750: 0750, -E0751: 0751, -E0752: 0752, -E0753: 0753, -E0754: 0754, -E0755: 0755, -E0756: 0756, -E0757: 0757, -E0758: 0758, -E0759: 0759, -E0760: 0760, -E0761: 0761, -E0762: 0762, -E0763: 0763, -E0764: 0764, -E0765: 0765, -E0766: 0766, -E0767: 0767, -E0768: 0768, -E0769: 0769, -E0770: 0770, -E0771: 0771, -E0772: 0772, -E0773: 0773, -E0774: 0774, -E0775: 0775, -E0776: 0776, -E0777: 0777, -E0778: 0778, -E0779: 0779, -E0780: 0780, -E0781: 0781, -E0782: 0782, -E0783: 0783, -E0784: 0784, -E0785: 0785, -E0786: 0786, -E0787: 0787, -E0788: 0788, -E0789: 0789, -E0790: 0790, -E0791: 0791, -E0792: 0792, -E0793: 0793, -E0794: 0794, -E0795: 0795, -E0796: 0796, -E0797: 0797, -E0798: 0798, -E0799: 0799, -E0800: 0800, -E0801: 0801, -E0802: 0802, -E0803: 0803, -E0804: 0804, -E0805: 0805, +0001, +0002, +0004, +0005, +0007, +0009, +0010, +0013, +0014, +0015, +0023, +0025, +0026, +0027, +0029, +0030, +0033, +0034, +0038, +0040, +0044, +0045, +0046, +0049, +0050, +0053, +0054, +0055, +0057, +0059, +0060, +0061, +0062, +0063, +0067, +0069, +0070, +0071, +0072, +0073, +0074, +0075, +0076, +0077, +0080, +0081, +0084, +0087, +0088, +0089, +0090, +0091, +0092, +0093, +0094, +0106, +0107, +0109, +0110, +0116, +0117, +0118, +0119, +0120, +0121, +0124, +0128, +0130, +0131, +0132, +0133, +0136, +0137, +0138, +0139, +0152, +0154, +0158, +0161, +0162, +0164, +0165, +0170, +0178, +0183, +0184, +0185, +0186, +0191, +0192, +0193, +0195, +0197, +0198, +0199, +0200, +0201, +0203, +0204, +0205, +0206, +0207, +0208, +0210, +0211, +0212, +0214, +0220, +0221, +0222, +0223, +0224, +0225, +0226, +0227, +0228, +0229, +0230, +0231, +0232, +0243, +0244, +0251, +0252, +0253, +0254, +0255, +0256, +0259, +0260, +0261, +0262, +0263, +0264, +0267, +0268, +0271, +0275, +0276, +0277, +0281, +0282, +0283, +0284, +0297, +0301, +0302, +0303, +0307, +0308, +0309, +0310, +0311, +0312, +0316, +0317, +0320, +0321, +0322, +0323, +0324, +0325, +0326, +0328, +0329, +0364, +0365, +0366, +0367, +0368, +0369, +0370, +0371, +0373, +0374, +0375, +0376, +0377, +0378, +0379, +0380, +0381, +0382, +0383, +0384, +0386, +0387, +0388, +0389, +0390, +0391, +0392, +0393, +0398, +0399, +0401, +0403, +0404, +0405, +0407, +0408, +0409, +0411, +0412, +0415, +0416, +0422, +0423, +0424, +0425, +0426, +0428, +0429, +0430, +0431, +0432, +0433, +0434, +0435, +0436, +0437, +0438, +0439, +0445, +0446, +0447, +0448, +0449, +0451, +0452, +0453, +0454, +0455, +0457, +0458, +0459, +0460, +0461, +0462, +0463, +0464, +0466, +0468, +0469, +0472, +0476, +0477, +0478, +0482, +0491, +0492, +0493, +0495, +0496, +0497, +0498, +0499, +0500, +0501, +0502, +0503, +0504, +0505, +0506, +0507, +0508, +0509, +0510, +0511, +0512, +0514, +0515, +0516, +0517, +0518, +0519, +0520, +0521, +0522, +0523, +0524, +0525, +0527, +0528, +0529, +0530, +0531, +0532, +0533, +0534, +0535, +0536, +0537, +0538, +0539, +0541, +0542, +0543, +0544, +0545, +0546, +0547, +0549, +0550, +0551, +0552, +0554, +0556, +0557, +0559, +0560, +0561, +0562, +0565, +0566, +0567, +0568, +0569, +0570, +0571, +0572, +0573, +0574, +0575, +0576, +0577, +0578, +0579, +0580, +0581, +0582, +0583, +0584, +0585, +0586, +0587, +0588, +0589, +0590, +0591, +0592, +0593, +0594, +0595, +0596, +0597, +0599, +0600, +0601, +0602, +0603, +0604, +0605, +0606, +0607, +0608, +0609, +0610, +0614, +0615, +0616, +0617, +0618, +0619, +0620, +0621, +0622, // REMOVED: rustc-intrinsic ABI was removed +0623, +0624, +0625, +0626, +0627, +0628, +0631, +0632, +0633, +0634, +0635, +0636, +0637, +0638, +0639, +0640, +0641, +0642, +0643, +0644, +0646, +0647, +0648, +0657, +0658, +0659, +0660, +0661, +0662, +0663, +0664, +0665, +0666, +0667, +0668, +0669, +0670, +0671, +0687, +0688, +0689, +0690, +0691, +0692, +0693, +0695, +0696, +0697, +0698, +0699, // REMOVED: merged into generic inference var error +0700, +0701, +0703, +0704, +0705, +0706, +0708, +0710, +0712, +0713, +0714, +0715, +0716, +0711, +0717, +0718, +0719, +0720, +0722, +0724, +0725, +0726, +0727, +0728, +0729, +0730, +0731, +0732, +0733, +0734, +0735, +0736, +0737, +0739, +0740, +0741, +0742, +0743, +0744, +0745, +0746, +0747, +0748, +0749, +0750, +0751, +0752, +0753, +0754, +0755, +0756, +0757, +0758, +0759, +0760, +0761, +0762, +0763, +0764, +0765, +0766, +0767, +0768, +0769, +0770, +0771, +0772, +0773, // REMOVED: no longer an error +0774, +0775, +0776, +0777, +0778, +0779, +0780, +0781, +0782, +0783, +0784, +0785, +0786, +0787, +0788, +0789, +0790, +0791, +0792, +0793, +0794, +0795, +0796, +0797, +0798, +0799, +0800, +0801, +0802, +0803, +0804, +0805, +0806, ); ) } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 085403c8ef36..0b30102eb992 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -192,7 +192,7 @@ pub fn fluent_bundle( Ok(Some(bundle)) } -fn register_functions(bundle: &mut FluentBundle) { +pub fn register_functions(bundle: &mut fluent_bundle::bundle::FluentBundle) { bundle .add_function("STREQ", |positional, _named| match positional { [FluentValue::String(a), FluentValue::String(b)] => format!("{}", (a == b)).into(), @@ -230,54 +230,6 @@ pub fn fallback_fluent_bundle( }))) } -/// Identifier for the Fluent message/attribute corresponding to a diagnostic message. -type FluentId = Cow<'static, str>; - -/// Abstraction over a message in a subdiagnostic (i.e. label, note, help, etc) to support both -/// translatable and non-translatable diagnostic messages. -/// -/// Translatable messages for subdiagnostics are typically attributes attached to a larger Fluent -/// message so messages of this type must be combined with a `DiagMessage` (using -/// `DiagMessage::with_subdiagnostic_message`) before rendering. However, subdiagnostics from -/// the `Subdiagnostic` derive refer to Fluent identifiers directly. -#[rustc_diagnostic_item = "SubdiagMessage"] -pub enum SubdiagMessage { - /// Non-translatable diagnostic message. - Str(Cow<'static, str>), - /// Translatable message which has already been translated eagerly. - /// - /// Some diagnostics have repeated subdiagnostics where the same interpolated variables would - /// be instantiated multiple times with different values. These subdiagnostics' messages - /// are translated when they are added to the parent diagnostic, producing this variant of - /// `DiagMessage`. - Translated(Cow<'static, str>), - /// Identifier of a Fluent message. Instances of this variant are generated by the - /// `Subdiagnostic` derive. - FluentIdentifier(FluentId), - /// Attribute of a Fluent message. Needs to be combined with a Fluent identifier to produce an - /// actual translated message. Instances of this variant are generated by the `fluent_messages` - /// macro. - /// - /// - FluentAttr(FluentId), -} - -impl From for SubdiagMessage { - fn from(s: String) -> Self { - SubdiagMessage::Str(Cow::Owned(s)) - } -} -impl From<&'static str> for SubdiagMessage { - fn from(s: &'static str) -> Self { - SubdiagMessage::Str(Cow::Borrowed(s)) - } -} -impl From> for SubdiagMessage { - fn from(s: Cow<'static, str>) -> Self { - SubdiagMessage::Str(s) - } -} - /// Abstraction over a message in a diagnostic to support both translatable and non-translatable /// diagnostic messages. /// @@ -285,52 +237,22 @@ impl From> for SubdiagMessage { #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] #[rustc_diagnostic_item = "DiagMessage"] pub enum DiagMessage { - /// Non-translatable diagnostic message. - Str(Cow<'static, str>), - /// Translatable message which has been already translated. + /// Non-translatable diagnostic message or a message that has been translated eagerly. /// /// Some diagnostics have repeated subdiagnostics where the same interpolated variables would /// be instantiated multiple times with different values. These subdiagnostics' messages - /// are translated when they are added to the parent diagnostic, producing this variant of - /// `DiagMessage`. - Translated(Cow<'static, str>), - /// Identifier for a Fluent message (with optional attribute) corresponding to the diagnostic - /// message. Yet to be translated. - /// - /// - /// - FluentIdentifier(FluentId, Option), + /// are translated when they are added to the parent diagnostic. This is one of the ways + /// this variant of `DiagMessage` is produced. + Str(Cow<'static, str>), + /// An inline Fluent message, containing the to be translated diagnostic message. + Inline(Cow<'static, str>), } impl DiagMessage { - /// Given a `SubdiagMessage` which may contain a Fluent attribute, create a new - /// `DiagMessage` that combines that attribute with the Fluent identifier of `self`. - /// - /// - If the `SubdiagMessage` is non-translatable then return the message as a `DiagMessage`. - /// - If `self` is non-translatable then return `self`'s message. - pub fn with_subdiagnostic_message(&self, sub: SubdiagMessage) -> Self { - let attr = match sub { - SubdiagMessage::Str(s) => return DiagMessage::Str(s), - SubdiagMessage::Translated(s) => return DiagMessage::Translated(s), - SubdiagMessage::FluentIdentifier(id) => { - return DiagMessage::FluentIdentifier(id, None); - } - SubdiagMessage::FluentAttr(attr) => attr, - }; - - match self { - DiagMessage::Str(s) => DiagMessage::Str(s.clone()), - DiagMessage::Translated(s) => DiagMessage::Translated(s.clone()), - DiagMessage::FluentIdentifier(id, _) => { - DiagMessage::FluentIdentifier(id.clone(), Some(attr)) - } - } - } - pub fn as_str(&self) -> Option<&str> { match self { - DiagMessage::Translated(s) | DiagMessage::Str(s) => Some(s), - DiagMessage::FluentIdentifier(_, _) => None, + DiagMessage::Str(s) => Some(s), + DiagMessage::Inline(_) => None, } } } @@ -351,24 +273,6 @@ impl From> for DiagMessage { } } -/// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but -/// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagMessage` and the -/// subdiagnostic derive refers to typed identifiers that are `DiagMessage`s, so need to be -/// able to convert between these, as much as they'll be converted back into `DiagMessage` -/// using `with_subdiagnostic_message` eventually. Don't use this other than for the derive. -impl From for SubdiagMessage { - fn from(val: DiagMessage) -> Self { - match val { - DiagMessage::Str(s) => SubdiagMessage::Str(s), - DiagMessage::Translated(s) => SubdiagMessage::Translated(s), - DiagMessage::FluentIdentifier(id, None) => SubdiagMessage::FluentIdentifier(id), - // There isn't really a sensible behaviour for this because it loses information but - // this is the most sensible of the behaviours. - DiagMessage::FluentIdentifier(_, Some(attr)) => SubdiagMessage::FluentAttr(attr), - } - } -} - /// A span together with some additional data. #[derive(Clone, Debug)] pub struct SpanLabel { diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 6c5a1740a9a6..a81fc496c828 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -14,10 +14,8 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_codes = { path = "../rustc_error_codes" } rustc_error_messages = { path = "../rustc_error_messages" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index" } -rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_errors/messages.ftl b/compiler/rustc_errors/messages.ftl deleted file mode 100644 index ad2e206260d5..000000000000 --- a/compiler/rustc_errors/messages.ftl +++ /dev/null @@ -1,48 +0,0 @@ -errors_delayed_at_with_newline = - delayed at {$emitted_at} - {$note} - -errors_delayed_at_without_newline = - delayed at {$emitted_at} - {$note} - -errors_expected_lifetime_parameter = - expected lifetime {$count -> - [1] parameter - *[other] parameters - } - -errors_indicate_anonymous_lifetime = - indicate the anonymous {$count -> - [1] lifetime - *[other] lifetimes - } - -errors_invalid_flushed_delayed_diagnostic_level = - `flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug` - -errors_target_inconsistent_architecture = - inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}` - -errors_target_inconsistent_pointer_width = - inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}` - -errors_target_invalid_address_space = - invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err} - -errors_target_invalid_alignment = - invalid alignment for `{$cause}` in "data-layout": `{$align}` is {$err_kind -> - [not_power_of_two] not a power of 2 - [too_large] too large - *[other] {""} - } - -errors_target_invalid_bits = - invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err} - -errors_target_invalid_bits_size = {$err} - -errors_target_invalid_datalayout_pointer_spec = - unknown pointer specification `{$err}` in datalayout string - -errors_target_missing_alignment = - missing alignment for `{$cause}` in "data-layout" diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 7f64dc3df23e..bdd3266adb66 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -27,7 +27,6 @@ use crate::emitter::{ ConfusionType, Destination, MAX_SUGGESTIONS, OutputTheme, detect_confusion_type, is_different, normalize_whitespace, should_show_source_code, }; -use crate::registry::Registry; use crate::translation::{Translator, to_fluent_args}; use crate::{ CodeSuggestion, DiagInner, DiagMessage, Emitter, ErrCode, Level, MultiSpan, Style, Subdiag, @@ -73,7 +72,7 @@ impl Debug for AnnotateSnippetEmitter { impl Emitter for AnnotateSnippetEmitter { /// The entry point for the diagnostics generation - fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) { + fn emit_diagnostic(&mut self, mut diag: DiagInner) { let fluent_args = to_fluent_args(diag.args.iter()); if self.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() { @@ -303,17 +302,6 @@ impl AnnotateSnippetEmitter { } } - let suggestions_expected = suggestions - .iter() - .filter(|s| { - matches!( - s.style, - SuggestionStyle::HideCodeInline - | SuggestionStyle::ShowCode - | SuggestionStyle::ShowAlways - ) - }) - .count(); for suggestion in suggestions { match suggestion.style { SuggestionStyle::CompletelyHidden => { @@ -526,12 +514,6 @@ impl AnnotateSnippetEmitter { } } - // FIXME: This hack should be removed once annotate_snippets is the - // default emitter. - if suggestions_expected > 0 && report.is_empty() { - group = group.element(Padding); - } - if !group.is_empty() { report.push(group); } diff --git a/compiler/rustc_errors/src/codes.rs b/compiler/rustc_errors/src/codes.rs index 787a8af99b1f..c1e7b7c184c1 100644 --- a/compiler/rustc_errors/src/codes.rs +++ b/compiler/rustc_errors/src/codes.rs @@ -5,6 +5,9 @@ //! long description text. use std::fmt; +use std::sync::LazyLock; + +use rustc_data_structures::fx::FxHashMap; rustc_index::newtype_index! { #[max = 9999] // Because all error codes have four digits. @@ -23,19 +26,32 @@ impl fmt::Display for ErrCode { rustc_error_messages::into_diag_arg_using_display!(ErrCode); macro_rules! define_error_code_constants_and_diagnostics_table { - ($($name:ident: $num:literal,)*) => ( + ($($num:literal,)*) => ( $( - pub const $name: $crate::ErrCode = $crate::ErrCode::from_u32($num); + pub const ${concat(E, $num)}: $crate::ErrCode = $crate::ErrCode::from_u32($num); )* - pub static DIAGNOSTICS: &[($crate::ErrCode, &str)] = &[ - $( ( - $name, - include_str!( - concat!("../../rustc_error_codes/src/error_codes/", stringify!($name), ".md") - ) - ), )* - ]; + static DIAGNOSTICS: LazyLock> = LazyLock::new(|| { + [ + $( ( + ${concat(E, $num)}, + include_str!( + concat!("../../rustc_error_codes/src/error_codes/E", stringify!($num), ".md") + ) + ), )* + ] + .iter() + .copied() + .collect() + }); ) } rustc_error_codes::error_codes!(define_error_code_constants_and_diagnostics_table); + +#[derive(Debug)] +pub struct InvalidErrorCode; + +/// Returns `InvalidErrorCode` if the code requested does not exist. +pub fn try_find_description(code: ErrCode) -> Result<&'static str, InvalidErrorCode> { + DIAGNOSTICS.get(&code).copied().ok_or(InvalidErrorCode) +} diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 96a4ed3218fb..087c5e700df0 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -15,11 +15,9 @@ use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span, Symbol}; use tracing::debug; -use crate::snippet::Style; use crate::{ CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level, - MultiSpan, StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle, - Suggestions, + MultiSpan, StashKey, Style, Substitution, SubstitutionPart, SuggestionStyle, Suggestions, }; pub type DiagArgMap = FxIndexMap; @@ -326,30 +324,8 @@ impl DiagInner { } } - // See comment on `Diag::subdiagnostic_message_to_diagnostic_message`. - pub(crate) fn subdiagnostic_message_to_diagnostic_message( - &self, - attr: impl Into, - ) -> DiagMessage { - let msg = - self.messages.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages"); - msg.with_subdiagnostic_message(attr.into()) - } - - pub(crate) fn sub( - &mut self, - level: Level, - message: impl Into, - span: MultiSpan, - ) { - let sub = Subdiag { - level, - messages: vec![( - self.subdiagnostic_message_to_diagnostic_message(message), - Style::NoStyle, - )], - span, - }; + pub(crate) fn sub(&mut self, level: Level, message: impl Into, span: MultiSpan) { + let sub = Subdiag { level, messages: vec![(message.into(), Style::NoStyle)], span }; self.children.push(sub); } @@ -538,7 +514,6 @@ macro_rules! with_fn { } impl<'a, G: EmissionGuarantee> Diag<'a, G> { - #[rustc_lint_diagnostics] #[track_caller] pub fn new(dcx: DiagCtxtHandle<'a>, level: Level, message: impl Into) -> Self { Self::new_diagnostic(dcx, DiagInner::new(level, message)) @@ -566,7 +541,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// /// In the meantime, though, callsites are required to deal with the "bug" /// locally in whichever way makes the most sense. - #[rustc_lint_diagnostics] #[track_caller] pub fn downgrade_to_delayed_bug(&mut self) { assert!( @@ -584,7 +558,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// This function still gives an emission guarantee, the guarantee is now just that it exits fatally. /// For delayed bugs this is different, since those are buffered. If we upgrade one to fatal, another /// might now be ignored. - #[rustc_lint_diagnostics] #[track_caller] pub fn upgrade_to_fatal(mut self) -> Diag<'a, FatalAbort> { assert!( @@ -613,17 +586,14 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// the diagnostic was constructed. However, the label span is *not* considered a /// ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is /// primary. - #[rustc_lint_diagnostics] - pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { - let msg = self.subdiagnostic_message_to_diagnostic_message(label); - self.span.push_span_label(span, msg); + pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { + self.span.push_span_label(span, label.into()); self } } with_fn! { with_span_labels, /// Labels all the given spans with the provided label. /// See [`Self::span_label()`] for more information. - #[rustc_lint_diagnostics] pub fn span_labels(&mut self, spans: impl IntoIterator, label: &str) -> &mut Self { for span in spans { self.span_label(span, label.to_string()); @@ -631,7 +601,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } } - #[rustc_lint_diagnostics] pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self { let before = self.span.clone(); self.span(after); @@ -647,7 +616,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } - #[rustc_lint_diagnostics] pub fn note_expected_found( &mut self, expected_label: &str, @@ -665,7 +633,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { ) } - #[rustc_lint_diagnostics] pub fn note_expected_found_extra( &mut self, expected_label: &str, @@ -711,7 +678,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } - #[rustc_lint_diagnostics] pub fn note_trait_signature(&mut self, name: Symbol, signature: String) -> &mut Self { self.highlighted_note(vec![ StringPart::normal(format!("`{name}` from trait: `")), @@ -723,19 +689,16 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_note, /// Add a note attached to this diagnostic. - #[rustc_lint_diagnostics] - pub fn note(&mut self, msg: impl Into) -> &mut Self { + pub fn note(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Note, msg, MultiSpan::new()); self } } - #[rustc_lint_diagnostics] pub fn highlighted_note(&mut self, msg: Vec) -> &mut Self { self.sub_with_highlights(Level::Note, msg, MultiSpan::new()); self } - #[rustc_lint_diagnostics] pub fn highlighted_span_note( &mut self, span: impl Into, @@ -746,8 +709,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { } /// This is like [`Diag::note()`], but it's only printed once. - #[rustc_lint_diagnostics] - pub fn note_once(&mut self, msg: impl Into) -> &mut Self { + pub fn note_once(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::OnceNote, msg, MultiSpan::new()); self } @@ -755,11 +717,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_span_note, /// Prints the span with a note above it. /// This is like [`Diag::note()`], but it gets its own span. - #[rustc_lint_diagnostics] pub fn span_note( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Note, msg, sp.into()); self @@ -767,11 +728,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// Prints the span with a note above it. /// This is like [`Diag::note_once()`], but it gets its own span. - #[rustc_lint_diagnostics] pub fn span_note_once>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::OnceNote, msg, sp.into()); self @@ -779,19 +739,17 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_warn, /// Add a warning attached to this diagnostic. - #[rustc_lint_diagnostics] - pub fn warn(&mut self, msg: impl Into) -> &mut Self { + pub fn warn(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Warning, msg, MultiSpan::new()); self } } /// Prints the span with a warning above it. /// This is like [`Diag::warn()`], but it gets its own span. - #[rustc_lint_diagnostics] pub fn span_warn>( &mut self, sp: S, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Warning, msg, sp.into()); self @@ -799,28 +757,24 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_help, /// Add a help message attached to this diagnostic. - #[rustc_lint_diagnostics] - pub fn help(&mut self, msg: impl Into) -> &mut Self { + pub fn help(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Help, msg, MultiSpan::new()); self } } /// This is like [`Diag::help()`], but it's only printed once. - #[rustc_lint_diagnostics] - pub fn help_once(&mut self, msg: impl Into) -> &mut Self { + pub fn help_once(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::OnceHelp, msg, MultiSpan::new()); self } /// Add a help message attached to this diagnostic with a customizable highlighted message. - #[rustc_lint_diagnostics] pub fn highlighted_help(&mut self, msg: Vec) -> &mut Self { self.sub_with_highlights(Level::Help, msg, MultiSpan::new()); self } /// Add a help message attached to this diagnostic with a customizable highlighted message. - #[rustc_lint_diagnostics] pub fn highlighted_span_help( &mut self, span: impl Into, @@ -833,11 +787,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_span_help, /// Prints the span with some help above it. /// This is like [`Diag::help()`], but it gets its own span. - #[rustc_lint_diagnostics] pub fn span_help( &mut self, sp: impl Into, - msg: impl Into, + msg: impl Into, ) -> &mut Self { self.sub(Level::Help, msg, sp.into()); self @@ -846,7 +799,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// Disallow attaching suggestions to this diagnostic. /// Any suggestions attached e.g. with the `span_suggestion_*` methods /// (before and after the call to `disable_suggestions`) will be ignored. - #[rustc_lint_diagnostics] pub fn disable_suggestions(&mut self) -> &mut Self { self.suggestions = Suggestions::Disabled; self @@ -856,7 +808,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// /// Suggestions added before the call to `.seal_suggestions()` will be preserved /// and new suggestions will be ignored. - #[rustc_lint_diagnostics] pub fn seal_suggestions(&mut self) -> &mut Self { if let Suggestions::Enabled(suggestions) = &mut self.suggestions { let suggestions_slice = std::mem::take(suggestions).into_boxed_slice(); @@ -869,7 +820,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// /// A new suggestion is added if suggestions are enabled for this diagnostic. /// Otherwise, they are ignored. - #[rustc_lint_diagnostics] fn push_suggestion(&mut self, suggestion: CodeSuggestion) { for subst in &suggestion.substitutions { for part in &subst.parts { @@ -890,10 +840,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_multipart_suggestion, /// Show a suggestion that has multiple parts to it. /// In other words, multiple changes need to be applied as part of this suggestion. - #[rustc_lint_diagnostics] pub fn multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -907,10 +856,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// Show a suggestion that has multiple parts to it, always as its own subdiagnostic. /// In other words, multiple changes need to be applied as part of this suggestion. - #[rustc_lint_diagnostics] pub fn multipart_suggestion_verbose( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -923,10 +871,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { } /// [`Diag::multipart_suggestion()`] but you can set the [`SuggestionStyle`]. - #[rustc_lint_diagnostics] pub fn multipart_suggestion_with_style( &mut self, - msg: impl Into, + msg: impl Into, mut suggestion: Vec<(Span, String)>, applicability: Applicability, style: SuggestionStyle, @@ -953,7 +900,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.push_suggestion(CodeSuggestion { substitutions: vec![Substitution { parts }], - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style, applicability, }); @@ -966,10 +913,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// be from the message, showing the span label inline would be visually unpleasant /// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't /// improve understandability. - #[rustc_lint_diagnostics] pub fn tool_only_multipart_suggestion( &mut self, - msg: impl Into, + msg: impl Into, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -999,11 +945,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// * may contain a name of a function, variable, or type, but not whole expressions /// /// See [`CodeSuggestion`] for more information. - #[rustc_lint_diagnostics] pub fn span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1018,11 +963,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { } } /// [`Diag::span_suggestion()`] but you can set the [`SuggestionStyle`]. - #[rustc_lint_diagnostics] pub fn span_suggestion_with_style( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, style: SuggestionStyle, @@ -1035,7 +979,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { substitutions: vec![Substitution { parts: vec![SubstitutionPart { snippet: suggestion.to_string(), span: sp }], }], - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style, applicability, }); @@ -1044,11 +988,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_span_suggestion_verbose, /// Always show the suggested change. - #[rustc_lint_diagnostics] pub fn span_suggestion_verbose( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1065,11 +1008,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_span_suggestions, /// Prints out a message with multiple suggested edits of the code. /// See also [`Diag::span_suggestion()`]. - #[rustc_lint_diagnostics] pub fn span_suggestions( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestions: impl IntoIterator, applicability: Applicability, ) -> &mut Self { @@ -1082,11 +1024,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { ) } } - #[rustc_lint_diagnostics] pub fn span_suggestions_with_style( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestions: impl IntoIterator, applicability: Applicability, style: SuggestionStyle, @@ -1103,7 +1044,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { .collect(); self.push_suggestion(CodeSuggestion { substitutions, - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style, applicability, }); @@ -1113,10 +1054,9 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// Prints out a message with multiple suggested edits of the code, where each edit consists of /// multiple parts. /// See also [`Diag::multipart_suggestion()`]. - #[rustc_lint_diagnostics] pub fn multipart_suggestions( &mut self, - msg: impl Into, + msg: impl Into, suggestions: impl IntoIterator>, applicability: Applicability, ) -> &mut Self { @@ -1148,7 +1088,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self.push_suggestion(CodeSuggestion { substitutions, - msg: self.subdiagnostic_message_to_diagnostic_message(msg), + msg: msg.into(), style: SuggestionStyle::ShowAlways, applicability, }); @@ -1160,11 +1100,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// inline, it will only show the message and not the suggestion. /// /// See [`CodeSuggestion`] for more information. - #[rustc_lint_diagnostics] pub fn span_suggestion_short( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1184,11 +1123,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// be from the message, showing the span label inline would be visually unpleasant /// (marginally overlapping spans or multiline spans) and showing the snippet window wouldn't /// improve understandability. - #[rustc_lint_diagnostics] pub fn span_suggestion_hidden( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1207,11 +1145,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// /// This is intended to be used for suggestions that are *very* obvious in what the changes /// need to be from the message, but we still want other tools to be able to apply them. - #[rustc_lint_diagnostics] pub fn tool_only_span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: impl Into, suggestion: impl ToString, applicability: Applicability, ) -> &mut Self { @@ -1229,7 +1166,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages /// used in the subdiagnostic, so suitable for use with repeated messages (i.e. re-use of /// interpolated variables). - #[rustc_lint_diagnostics] pub fn subdiagnostic(&mut self, subdiagnostic: impl Subdiagnostic) -> &mut Self { subdiagnostic.add_to_diag(self); self @@ -1240,15 +1176,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { /// one value will clobber the other. Eagerly translating the /// diagnostic uses the variables defined right then, before the /// clobbering occurs. - pub fn eagerly_translate(&self, msg: impl Into) -> SubdiagMessage { + pub fn eagerly_translate(&self, msg: impl Into) -> DiagMessage { let args = self.args.iter(); - let msg = self.subdiagnostic_message_to_diagnostic_message(msg.into()); - self.dcx.eagerly_translate(msg, args) + self.dcx.eagerly_translate(msg.into(), args) } with_fn! { with_span, /// Add a span. - #[rustc_lint_diagnostics] pub fn span(&mut self, sp: impl Into) -> &mut Self { self.span = sp.into(); if let Some(span) = self.span.primary_span() { @@ -1257,7 +1191,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } } - #[rustc_lint_diagnostics] pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self { self.is_lint = Some(IsLint { name, has_future_breakage }); self @@ -1265,7 +1198,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_code, /// Add an error code. - #[rustc_lint_diagnostics] pub fn code(&mut self, code: ErrCode) -> &mut Self { self.code = Some(code); self @@ -1273,7 +1205,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_lint_id, /// Add an argument. - #[rustc_lint_diagnostics] pub fn lint_id( &mut self, id: LintExpectationId, @@ -1284,7 +1215,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_primary_message, /// Add a primary message. - #[rustc_lint_diagnostics] pub fn primary_message(&mut self, msg: impl Into) -> &mut Self { self.messages[0] = (msg.into(), Style::NoStyle); self @@ -1292,7 +1222,6 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { with_fn! { with_arg, /// Add an argument. - #[rustc_lint_diagnostics] pub fn arg( &mut self, name: impl Into, @@ -1302,31 +1231,18 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } } - /// Helper function that takes a `SubdiagMessage` and returns a `DiagMessage` by - /// combining it with the primary message of the diagnostic (if translatable, otherwise it just - /// passes the user's string along). - pub(crate) fn subdiagnostic_message_to_diagnostic_message( - &self, - attr: impl Into, - ) -> DiagMessage { - self.deref().subdiagnostic_message_to_diagnostic_message(attr) - } - /// Convenience function for internal use, clients should use one of the /// public methods above. /// /// Used by `proc_macro_server` for implementing `server::Diagnostic`. - pub fn sub(&mut self, level: Level, message: impl Into, span: MultiSpan) { + pub fn sub(&mut self, level: Level, message: impl Into, span: MultiSpan) { self.deref_mut().sub(level, message, span); } /// Convenience function for internal use, clients should use one of the /// public methods above. fn sub_with_highlights(&mut self, level: Level, messages: Vec, span: MultiSpan) { - let messages = messages - .into_iter() - .map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.content), m.style)) - .collect(); + let messages = messages.into_iter().map(|m| (m.content.into(), m.style)).collect(); let sub = Subdiag { level, messages, span }; self.children.push(sub); } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 435d16a83806..42c605d34814 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -6,10 +6,7 @@ use rustc_macros::Subdiagnostic; use rustc_span::{Span, Symbol}; use crate::diagnostic::DiagLocation; -use crate::{ - Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, - fluent_generated as fluent, -}; +use crate::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, msg}; impl IntoDiagArg for DiagLocation { fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { @@ -44,43 +41,50 @@ impl Diagnostic<'_, G> for TargetDataLayoutErrors<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { match self { TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => { - Diag::new(dcx, level, fluent::errors_target_invalid_address_space) + Diag::new(dcx, level, msg!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}")) .with_arg("addr_space", addr_space) .with_arg("cause", cause) .with_arg("err", err) } TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_bits) + Diag::new(dcx, level, msg!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}")) .with_arg("kind", kind) .with_arg("bit", bit) .with_arg("cause", cause) .with_arg("err", err) } TargetDataLayoutErrors::MissingAlignment { cause } => { - Diag::new(dcx, level, fluent::errors_target_missing_alignment) + Diag::new(dcx, level, msg!("missing alignment for `{$cause}` in \"data-layout\"")) .with_arg("cause", cause) } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_alignment) - .with_arg("cause", cause) - .with_arg("err_kind", err.diag_ident()) - .with_arg("align", err.align()) + Diag::new(dcx, level, msg!( + "invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind -> + [not_power_of_two] not a power of 2 + [too_large] too large + *[other] {\"\"} + }" + )) + .with_arg("cause", cause) + .with_arg("err_kind", err.diag_ident()) + .with_arg("align", err.align()) } TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { - Diag::new(dcx, level, fluent::errors_target_inconsistent_architecture) - .with_arg("dl", dl) - .with_arg("target", target) + Diag::new(dcx, level, msg!( + "inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`" + )) + .with_arg("dl", dl).with_arg("target", target) } TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => { - Diag::new(dcx, level, fluent::errors_target_inconsistent_pointer_width) - .with_arg("pointer_size", pointer_size) - .with_arg("target", target) + Diag::new(dcx, level, msg!( + "inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`" + )).with_arg("pointer_size", pointer_size).with_arg("target", target) } TargetDataLayoutErrors::InvalidBitsSize { err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_bits_size).with_arg("err", err) + Diag::new(dcx, level, msg!("{$err}")).with_arg("err", err) } TargetDataLayoutErrors::UnknownPointerSpecification { err } => { - Diag::new(dcx, level, fluent::errors_target_invalid_datalayout_pointer_spec) + Diag::new(dcx, level, msg!("unknown pointer specification `{$err}` in datalayout string")) .with_arg("err", err) } } @@ -99,7 +103,12 @@ impl Subdiagnostic for SingleLabelManySpans { } #[derive(Subdiagnostic)] -#[label(errors_expected_lifetime_parameter)] +#[label( + "expected lifetime {$count -> + [1] parameter + *[other] parameters + }" +)] pub struct ExpectedLifetimeParameter { #[primary_span] pub span: Span, @@ -107,7 +116,14 @@ pub struct ExpectedLifetimeParameter { } #[derive(Subdiagnostic)] -#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")] +#[suggestion( + "indicate the anonymous {$count -> + [1] lifetime + *[other] lifetimes + }", + code = "{suggestion}", + style = "verbose" +)] pub struct IndicateAnonymousLifetime { #[primary_span] pub span: Span, diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d08d5a5a1ea2..4ceb5cf06f93 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -8,161 +8,38 @@ //! The output types are defined in `rustc_session::config::ErrorOutputType`. use std::borrow::Cow; -use std::cmp::{Reverse, max, min}; use std::error::Report; use std::io::prelude::*; use std::io::{self, IsTerminal}; use std::iter; use std::path::Path; -use std::sync::Arc; use anstream::{AutoStream, ColorChoice}; use anstyle::{AnsiColor, Effects}; -use derive_setters::Setters; -use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; -use rustc_data_structures::sync::{DynSend, IntoDynSyncSend}; -use rustc_error_messages::{FluentArgs, SpanLabel}; -use rustc_lexer; -use rustc_lint_defs::pluralize; +use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::sync::DynSend; +use rustc_error_messages::FluentArgs; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; -use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width}; -use tracing::{debug, instrument, trace, warn}; +use rustc_span::{FileName, SourceFile, Span}; +use tracing::{debug, warn}; -use crate::registry::Registry; -use crate::snippet::{ - Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString, -}; -use crate::styled_buffer::StyledBuffer; use crate::timings::TimingRecord; -use crate::translation::{Translator, to_fluent_args}; +use crate::translation::Translator; use crate::{ - CodeSuggestion, DiagInner, DiagMessage, ErrCode, Level, MultiSpan, Subdiag, - SubstitutionHighlight, SuggestionStyle, TerminalUrl, + CodeSuggestion, DiagInner, DiagMessage, Level, MultiSpan, Style, Subdiag, SuggestionStyle, }; -/// Default column width, used in tests and when terminal dimensions cannot be determined. -const DEFAULT_COLUMN_WIDTH: usize = 140; - /// Describes the way the content of the `rendered` field of the json output is generated #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum HumanReadableErrorType { - Default { short: bool }, - AnnotateSnippet { short: bool, unicode: bool }, +pub struct HumanReadableErrorType { + pub short: bool, + pub unicode: bool, } impl HumanReadableErrorType { pub fn short(&self) -> bool { - match self { - HumanReadableErrorType::Default { short } - | HumanReadableErrorType::AnnotateSnippet { short, .. } => *short, - } - } -} - -#[derive(Clone, Copy, Debug)] -struct Margin { - /// The available whitespace in the left that can be consumed when centering. - pub whitespace_left: usize, - /// The column of the beginning of leftmost span. - pub span_left: usize, - /// The column of the end of rightmost span. - pub span_right: usize, - /// The beginning of the line to be displayed. - pub computed_left: usize, - /// The end of the line to be displayed. - pub computed_right: usize, - /// The current width of the terminal. Uses value of `DEFAULT_COLUMN_WIDTH` constant by default - /// and in tests. - pub column_width: usize, - /// The end column of a span label, including the span. Doesn't account for labels not in the - /// same line as the span. - pub label_right: usize, -} - -impl Margin { - fn new( - whitespace_left: usize, - span_left: usize, - span_right: usize, - label_right: usize, - column_width: usize, - max_line_len: usize, - ) -> Self { - // The 6 is padding to give a bit of room for `...` when displaying: - // ``` - // error: message - // --> file.rs:16:58 - // | - // 16 | ... fn foo(self) -> Self::Bar { - // | ^^^^^^^^^ - // ``` - - let mut m = Margin { - whitespace_left: whitespace_left.saturating_sub(6), - span_left: span_left.saturating_sub(6), - span_right: span_right + 6, - computed_left: 0, - computed_right: 0, - column_width, - label_right: label_right + 6, - }; - m.compute(max_line_len); - m - } - - fn was_cut_left(&self) -> bool { - self.computed_left > 0 - } - - fn compute(&mut self, max_line_len: usize) { - // When there's a lot of whitespace (>20), we want to trim it as it is useless. - // FIXME: this doesn't account for '\t', but to do so correctly we need to perform that - // calculation later, right before printing in order to be accurate with both unicode - // handling and trimming of long lines. - self.computed_left = if self.whitespace_left > 20 { - self.whitespace_left - 16 // We want some padding. - } else { - 0 - }; - // We want to show as much as possible, max_line_len is the rightmost boundary for the - // relevant code. - self.computed_right = max(max_line_len, self.computed_left); - - if self.computed_right - self.computed_left > self.column_width { - // Trimming only whitespace isn't enough, let's get craftier. - if self.label_right - self.whitespace_left <= self.column_width { - // Attempt to fit the code window only trimming whitespace. - self.computed_left = self.whitespace_left; - self.computed_right = self.computed_left + self.column_width; - } else if self.label_right - self.span_left <= self.column_width { - // Attempt to fit the code window considering only the spans and labels. - let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2; - self.computed_left = self.span_left.saturating_sub(padding_left); - self.computed_right = self.computed_left + self.column_width; - } else if self.span_right - self.span_left <= self.column_width { - // Attempt to fit the code window considering the spans and labels plus padding. - let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2; - self.computed_left = self.span_left.saturating_sub(padding_left); - self.computed_right = self.computed_left + self.column_width; - } else { - // Mostly give up but still don't show the full line. - self.computed_left = self.span_left; - self.computed_right = self.span_right; - } - } - } - - fn left(&self, line_len: usize) -> usize { - min(self.computed_left, line_len) - } - - fn right(&self, line_len: usize) -> usize { - if line_len.saturating_sub(self.computed_left) <= self.column_width { - line_len - } else { - min(line_len, self.computed_right) - } + self.short } } @@ -171,14 +48,12 @@ pub enum TimingEvent { End, } -const ANONYMIZED_LINE_NUM: &str = "LL"; - pub type DynEmitter = dyn Emitter + DynSend; /// Emitter trait for emitting errors and other structured information. pub trait Emitter { /// Emit a structured diagnostic. - fn emit_diagnostic(&mut self, diag: DiagInner, registry: &Registry); + fn emit_diagnostic(&mut self, diag: DiagInner); /// Emit a notification that an artifact has been output. /// Currently only supported for the JSON format. @@ -190,7 +65,7 @@ pub trait Emitter { /// Emit a report about future breakage. /// Currently only supported for the JSON format. - fn emit_future_breakage_report(&mut self, _diags: Vec, _registry: &Registry) {} + fn emit_future_breakage_report(&mut self, _diags: Vec) {} /// Emit list of unused externs. /// Currently only supported for the JSON format. @@ -474,9 +349,12 @@ pub trait Emitter { .chain(span.span_labels().iter().map(|sp_label| sp_label.span)) .filter_map(|sp| { if !sp.is_dummy() && source_map.is_imported(sp) { - let maybe_callsite = sp.source_callsite(); - if sp != maybe_callsite { - return Some((sp, maybe_callsite)); + let mut span = sp; + while let Some(callsite) = span.parent_callsite() { + span = callsite; + if !source_map.is_imported(span) { + return Some((sp, span)); + } } } None @@ -490,48 +368,6 @@ pub trait Emitter { } } -impl Emitter for HumanEmitter { - fn source_map(&self) -> Option<&SourceMap> { - self.sm.as_deref() - } - - fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) { - let fluent_args = to_fluent_args(diag.args.iter()); - - if self.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() { - diag.children.insert(0, diag.emitted_at_sub_diag()); - } - - let mut suggestions = diag.suggestions.unwrap_tag(); - self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args); - - self.fix_multispans_in_extern_macros_and_render_macro_backtrace( - &mut diag.span, - &mut diag.children, - &diag.level, - self.macro_backtrace, - ); - - self.emit_messages_default( - &diag.level, - &diag.messages, - &fluent_args, - &diag.code, - &diag.span, - &diag.children, - &suggestions, - ); - } - - fn should_show_explain(&self) -> bool { - !self.short_message - } - - fn translator(&self) -> &Translator { - &self.translator - } -} - /// An emitter that adds a note to each diagnostic. pub struct EmitterWithNote { pub emitter: Box, @@ -543,9 +379,9 @@ impl Emitter for EmitterWithNote { None } - fn emit_diagnostic(&mut self, mut diag: DiagInner, registry: &Registry) { + fn emit_diagnostic(&mut self, mut diag: DiagInner) { diag.sub(Level::Note, self.note.clone(), MultiSpan::new()); - self.emitter.emit_diagnostic(diag, registry); + self.emitter.emit_diagnostic(diag); } fn translator(&self) -> &Translator { @@ -562,7 +398,7 @@ impl Emitter for SilentEmitter { None } - fn emit_diagnostic(&mut self, _diag: DiagInner, _registry: &Registry) {} + fn emit_diagnostic(&mut self, _diag: DiagInner) {} fn translator(&self) -> &Translator { &self.translator @@ -604,2703 +440,6 @@ pub enum OutputTheme { Unicode, } -/// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short` -#[derive(Setters)] -pub struct HumanEmitter { - #[setters(skip)] - dst: IntoDynSyncSend, - sm: Option>, - #[setters(skip)] - translator: Translator, - short_message: bool, - ui_testing: bool, - ignored_directories_in_source_blocks: Vec, - diagnostic_width: Option, - - macro_backtrace: bool, - track_diagnostics: bool, - terminal_url: TerminalUrl, - theme: OutputTheme, -} - -#[derive(Debug)] -pub(crate) struct FileWithAnnotatedLines { - pub(crate) file: Arc, - pub(crate) lines: Vec, - multiline_depth: usize, -} - -impl HumanEmitter { - pub fn new(dst: Destination, translator: Translator) -> HumanEmitter { - HumanEmitter { - dst: IntoDynSyncSend(dst), - sm: None, - translator, - short_message: false, - ui_testing: false, - ignored_directories_in_source_blocks: Vec::new(), - diagnostic_width: None, - macro_backtrace: false, - track_diagnostics: false, - terminal_url: TerminalUrl::No, - theme: OutputTheme::Ascii, - } - } - - fn maybe_anonymized(&self, line_num: usize) -> Cow<'static, str> { - if self.ui_testing { - Cow::Borrowed(ANONYMIZED_LINE_NUM) - } else { - Cow::Owned(line_num.to_string()) - } - } - - fn draw_line( - &self, - buffer: &mut StyledBuffer, - source_string: &str, - line_index: usize, - line_offset: usize, - width_offset: usize, - code_offset: usize, - margin: Margin, - ) -> usize { - let line_len = source_string.len(); - // Create the source line we will highlight. - let left = margin.left(line_len); - let right = margin.right(line_len); - // FIXME: The following code looks fishy. See #132860. - // On long lines, we strip the source line, accounting for unicode. - let code: String = source_string - .chars() - .enumerate() - .skip_while(|(i, _)| *i < left) - .take_while(|(i, _)| *i < right) - .map(|(_, c)| c) - .collect(); - let code = normalize_whitespace(&code); - let was_cut_right = - source_string.chars().enumerate().skip_while(|(i, _)| *i < right).next().is_some(); - buffer.puts(line_offset, code_offset, &code, Style::Quotation); - let placeholder = self.margin(); - if margin.was_cut_left() { - // We have stripped some code/whitespace from the beginning, make it clear. - buffer.puts(line_offset, code_offset, placeholder, Style::LineNumber); - } - if was_cut_right { - let padding = str_width(placeholder); - // We have stripped some code after the rightmost span end, make it clear we did so. - buffer.puts( - line_offset, - code_offset + str_width(&code) - padding, - placeholder, - Style::LineNumber, - ); - } - self.draw_line_num(buffer, line_index, line_offset, width_offset - 3); - self.draw_col_separator_no_space(buffer, line_offset, width_offset - 2); - left - } - - #[instrument(level = "trace", skip(self), ret)] - fn render_source_line( - &self, - buffer: &mut StyledBuffer, - file: Arc, - line: &Line, - width_offset: usize, - code_offset: usize, - margin: Margin, - close_window: bool, - ) -> Vec<(usize, Style)> { - // Draw: - // - // LL | ... code ... - // | ^^-^ span label - // | | - // | secondary span label - // - // ^^ ^ ^^^ ^^^^ ^^^ we don't care about code too far to the right of a span, we trim it - // | | | | - // | | | actual code found in your source code and the spans we use to mark it - // | | when there's too much wasted space to the left, trim it - // | vertical divider between the column number and the code - // column number - - if line.line_index == 0 { - return Vec::new(); - } - - let Some(source_string) = file.get_line(line.line_index - 1) else { - return Vec::new(); - }; - trace!(?source_string); - - let line_offset = buffer.num_lines(); - - // Left trim. - // FIXME: This looks fishy. See #132860. - let left = self.draw_line( - buffer, - &source_string, - line.line_index, - line_offset, - width_offset, - code_offset, - margin, - ); - - // Special case when there's only one annotation involved, it is the start of a multiline - // span and there's no text at the beginning of the code line. Instead of doing the whole - // graph: - // - // 2 | fn foo() { - // | _^ - // 3 | | - // 4 | | } - // | |_^ test - // - // we simplify the output to: - // - // 2 | / fn foo() { - // 3 | | - // 4 | | } - // | |_^ test - let mut buffer_ops = vec![]; - let mut annotations = vec![]; - let mut short_start = true; - for ann in &line.annotations { - if let AnnotationType::MultilineStart(depth) = ann.annotation_type { - if source_string.chars().take(ann.start_col.file).all(|c| c.is_whitespace()) { - let uline = self.underline(ann.is_primary); - let chr = uline.multiline_whole_line; - annotations.push((depth, uline.style)); - buffer_ops.push((line_offset, width_offset + depth - 1, chr, uline.style)); - } else { - short_start = false; - break; - } - } else if let AnnotationType::MultilineLine(_) = ann.annotation_type { - } else { - short_start = false; - break; - } - } - if short_start { - for (y, x, c, s) in buffer_ops { - buffer.putc(y, x, c, s); - } - return annotations; - } - - // We want to display like this: - // - // vec.push(vec.pop().unwrap()); - // --- ^^^ - previous borrow ends here - // | | - // | error occurs here - // previous borrow of `vec` occurs here - // - // But there are some weird edge cases to be aware of: - // - // vec.push(vec.pop().unwrap()); - // -------- - previous borrow ends here - // || - // |this makes no sense - // previous borrow of `vec` occurs here - // - // For this reason, we group the lines into "highlight lines" - // and "annotations lines", where the highlight lines have the `^`. - - // Sort the annotations by (start, end col) - // The labels are reversed, sort and then reversed again. - // Consider a list of annotations (A1, A2, C1, C2, B1, B2) where - // the letter signifies the span. Here we are only sorting by the - // span and hence, the order of the elements with the same span will - // not change. On reversing the ordering (|a, b| but b.cmp(a)), you get - // (C1, C2, B1, B2, A1, A2). All the elements with the same span are - // still ordered first to last, but all the elements with different - // spans are ordered by their spans in last to first order. Last to - // first order is important, because the jiggly lines and | are on - // the left, so the rightmost span needs to be rendered first, - // otherwise the lines would end up needing to go over a message. - - let mut annotations = line.annotations.clone(); - annotations.sort_by_key(|a| Reverse(a.start_col)); - - // First, figure out where each label will be positioned. - // - // In the case where you have the following annotations: - // - // vec.push(vec.pop().unwrap()); - // -------- - previous borrow ends here [C] - // || - // |this makes no sense [B] - // previous borrow of `vec` occurs here [A] - // - // `annotations_position` will hold [(2, A), (1, B), (0, C)]. - // - // We try, when possible, to stick the rightmost annotation at the end - // of the highlight line: - // - // vec.push(vec.pop().unwrap()); - // --- --- - previous borrow ends here - // - // But sometimes that's not possible because one of the other - // annotations overlaps it. For example, from the test - // `span_overlap_label`, we have the following annotations - // (written on distinct lines for clarity): - // - // fn foo(x: u32) { - // -------------- - // - - // - // In this case, we can't stick the rightmost-most label on - // the highlight line, or we would get: - // - // fn foo(x: u32) { - // -------- x_span - // | - // fn_span - // - // which is totally weird. Instead we want: - // - // fn foo(x: u32) { - // -------------- - // | | - // | x_span - // fn_span - // - // which is...less weird, at least. In fact, in general, if - // the rightmost span overlaps with any other span, we should - // use the "hang below" version, so we can at least make it - // clear where the span *starts*. There's an exception for this - // logic, when the labels do not have a message: - // - // fn foo(x: u32) { - // -------------- - // | - // x_span - // - // instead of: - // - // fn foo(x: u32) { - // -------------- - // | | - // | x_span - // - // - let mut overlap = vec![false; annotations.len()]; - let mut annotations_position = vec![]; - let mut line_len: usize = 0; - let mut p = 0; - for (i, annotation) in annotations.iter().enumerate() { - for (j, next) in annotations.iter().enumerate() { - if overlaps(next, annotation, 0) && j > i { - overlap[i] = true; - overlap[j] = true; - } - if overlaps(next, annotation, 0) // This label overlaps with another one and both - && annotation.has_label() // take space (they have text and are not - && j > i // multiline lines). - && p == 0 - // We're currently on the first line, move the label one line down - { - // If we're overlapping with an un-labelled annotation with the same span - // we can just merge them in the output - if next.start_col == annotation.start_col - && next.end_col == annotation.end_col - && !next.has_label() - { - continue; - } - - // This annotation needs a new line in the output. - p += 1; - break; - } - } - annotations_position.push((p, annotation)); - for (j, next) in annotations.iter().enumerate() { - if j > i { - let l = next.label.as_ref().map_or(0, |label| label.len() + 2); - if (overlaps(next, annotation, l) // Do not allow two labels to be in the same - // line if they overlap including padding, to - // avoid situations like: - // - // fn foo(x: u32) { - // -------^------ - // | | - // fn_spanx_span - // - && annotation.has_label() // Both labels must have some text, otherwise - && next.has_label()) // they are not overlapping. - // Do not add a new line if this annotation - // or the next are vertical line placeholders. - || (annotation.takes_space() // If either this or the next annotation is - && next.has_label()) // multiline start/end, move it to a new line - || (annotation.has_label() // so as not to overlap the horizontal lines. - && next.takes_space()) - || (annotation.takes_space() && next.takes_space()) - || (overlaps(next, annotation, l) - && next.end_col <= annotation.end_col - && next.has_label() - && p == 0) - // Avoid #42595. - { - // This annotation needs a new line in the output. - p += 1; - break; - } - } - } - line_len = max(line_len, p); - } - - if line_len != 0 { - line_len += 1; - } - - // If there are no annotations or the only annotations on this line are - // MultilineLine, then there's only code being shown, stop processing. - if line.annotations.iter().all(|a| a.is_line()) { - return vec![]; - } - - if annotations_position - .iter() - .all(|(_, ann)| matches!(ann.annotation_type, AnnotationType::MultilineStart(_))) - && let Some(max_pos) = annotations_position.iter().map(|(pos, _)| *pos).max() - { - // Special case the following, so that we minimize overlapping multiline spans. - // - // 3 │ X0 Y0 Z0 - // │ â”â”â”â”â”â”â”› │ │ < We are writing these lines - // │ ┃┌───────┘ │ < by reverting the "depth" of - // │ ┃│┌─────────┘ < their multiline spans. - // 4 │ ┃││ X1 Y1 Z1 - // 5 │ ┃││ X2 Y2 Z2 - // │ ┃│└────╿──│──┘ `Z` label - // │ ┃└─────│──┤ - // │ â”—â”â”â”â”â”â”┥ `Y` is a good letter too - // â•°â•´ `X` is a good letter - for (pos, _) in &mut annotations_position { - *pos = max_pos - *pos; - } - // We know then that we don't need an additional line for the span label, saving us - // one line of vertical space. - line_len = line_len.saturating_sub(1); - } - - // Write the column separator. - // - // After this we will have: - // - // 2 | fn foo() { - // | - // | - // | - // 3 | - // 4 | } - // | - for pos in 0..=line_len { - self.draw_col_separator_no_space(buffer, line_offset + pos + 1, width_offset - 2); - } - if close_window { - self.draw_col_separator_end(buffer, line_offset + line_len + 1, width_offset - 2); - } - - // Write the horizontal lines for multiline annotations - // (only the first and last lines need this). - // - // After this we will have: - // - // 2 | fn foo() { - // | __________ - // | - // | - // 3 | - // 4 | } - // | _ - for &(pos, annotation) in &annotations_position { - let underline = self.underline(annotation.is_primary); - let pos = pos + 1; - match annotation.annotation_type { - AnnotationType::MultilineStart(depth) | AnnotationType::MultilineEnd(depth) => { - let pre: usize = source_string - .chars() - .take(annotation.start_col.file) - .skip(left) - .map(|c| char_width(c)) - .sum(); - self.draw_range( - buffer, - underline.multiline_horizontal, - line_offset + pos, - width_offset + depth, - code_offset + pre, - underline.style, - ); - } - _ => {} - } - } - - // Write the vertical lines for labels that are on a different line as the underline. - // - // After this we will have: - // - // 2 | fn foo() { - // | __________ - // | | | - // | | - // 3 | | - // 4 | | } - // | |_ - for &(pos, annotation) in &annotations_position { - let underline = self.underline(annotation.is_primary); - let pos = pos + 1; - - let code_offset = code_offset - + source_string - .chars() - .take(annotation.start_col.file) - .skip(left) - .map(|c| char_width(c)) - .sum::(); - if pos > 1 && (annotation.has_label() || annotation.takes_space()) { - for p in line_offset + 1..=line_offset + pos { - buffer.putc( - p, - code_offset, - match annotation.annotation_type { - AnnotationType::MultilineLine(_) => underline.multiline_vertical, - _ => underline.vertical_text_line, - }, - underline.style, - ); - } - if let AnnotationType::MultilineStart(_) = annotation.annotation_type { - buffer.putc( - line_offset + pos, - code_offset, - underline.bottom_right, - underline.style, - ); - } - if let AnnotationType::MultilineEnd(_) = annotation.annotation_type - && annotation.has_label() - { - buffer.putc( - line_offset + pos, - code_offset, - underline.multiline_bottom_right_with_text, - underline.style, - ); - } - } - match annotation.annotation_type { - AnnotationType::MultilineStart(depth) => { - buffer.putc( - line_offset + pos, - width_offset + depth - 1, - underline.top_left, - underline.style, - ); - for p in line_offset + pos + 1..line_offset + line_len + 2 { - buffer.putc( - p, - width_offset + depth - 1, - underline.multiline_vertical, - underline.style, - ); - } - } - AnnotationType::MultilineEnd(depth) => { - for p in line_offset..line_offset + pos { - buffer.putc( - p, - width_offset + depth - 1, - underline.multiline_vertical, - underline.style, - ); - } - buffer.putc( - line_offset + pos, - width_offset + depth - 1, - underline.bottom_left, - underline.style, - ); - } - _ => (), - } - } - - // Write the labels on the annotations that actually have a label. - // - // After this we will have: - // - // 2 | fn foo() { - // | __________ - // | | - // | something about `foo` - // 3 | - // 4 | } - // | _ test - for &(pos, annotation) in &annotations_position { - let style = - if annotation.is_primary { Style::LabelPrimary } else { Style::LabelSecondary }; - let (pos, col) = if pos == 0 { - let pre: usize = source_string - .chars() - .take(annotation.end_col.file) - .skip(left) - .map(|c| char_width(c)) - .sum(); - if annotation.end_col.file == 0 { - (pos + 1, (pre + 2)) - } else { - let pad = if annotation.end_col.file - annotation.start_col.file == 0 { - 2 - } else { - 1 - }; - (pos + 1, (pre + pad)) - } - } else { - let pre: usize = source_string - .chars() - .take(annotation.start_col.file) - .skip(left) - .map(|c| char_width(c)) - .sum(); - (pos + 2, pre) - }; - if let Some(ref label) = annotation.label { - buffer.puts(line_offset + pos, code_offset + col, label, style); - } - } - - // Sort from biggest span to smallest span so that smaller spans are - // represented in the output: - // - // x | fn foo() - // | ^^^---^^ - // | | | - // | | something about `foo` - // | something about `fn foo()` - annotations_position.sort_by_key(|(_, ann)| { - // Decreasing order. When annotations share the same length, prefer `Primary`. - (Reverse(ann.len()), ann.is_primary) - }); - - // Write the underlines. - // - // After this we will have: - // - // 2 | fn foo() { - // | ____-_____^ - // | | - // | something about `foo` - // 3 | - // 4 | } - // | _^ test - for &(pos, annotation) in &annotations_position { - let uline = self.underline(annotation.is_primary); - let width = annotation.end_col.file - annotation.start_col.file; - let previous: String = - source_string.chars().take(annotation.start_col.file).skip(left).collect(); - let underlined: String = - source_string.chars().skip(annotation.start_col.file).take(width).collect(); - debug!(?previous, ?underlined); - let code_offset = code_offset - + source_string - .chars() - .take(annotation.start_col.file) - .skip(left) - .map(|c| char_width(c)) - .sum::(); - let ann_width: usize = source_string - .chars() - .skip(annotation.start_col.file) - .take(width) - .map(|c| char_width(c)) - .sum(); - let ann_width = if ann_width == 0 - && matches!(annotation.annotation_type, AnnotationType::Singleline) - { - 1 - } else { - ann_width - }; - for p in 0..ann_width { - // The default span label underline. - buffer.putc(line_offset + 1, code_offset + p, uline.underline, uline.style); - } - - if pos == 0 - && matches!( - annotation.annotation_type, - AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_) - ) - { - // The beginning of a multiline span with its leftward moving line on the same line. - buffer.putc( - line_offset + 1, - code_offset, - match annotation.annotation_type { - AnnotationType::MultilineStart(_) => uline.top_right_flat, - AnnotationType::MultilineEnd(_) => uline.multiline_end_same_line, - _ => panic!("unexpected annotation type: {annotation:?}"), - }, - uline.style, - ); - } else if pos != 0 - && matches!( - annotation.annotation_type, - AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_) - ) - { - // The beginning of a multiline span with its leftward moving line on another line, - // so we start going down first. - buffer.putc( - line_offset + 1, - code_offset, - match annotation.annotation_type { - AnnotationType::MultilineStart(_) => uline.multiline_start_down, - AnnotationType::MultilineEnd(_) => uline.multiline_end_up, - _ => panic!("unexpected annotation type: {annotation:?}"), - }, - uline.style, - ); - } else if pos != 0 && annotation.has_label() { - // The beginning of a span label with an actual label, we'll point down. - buffer.putc(line_offset + 1, code_offset, uline.label_start, uline.style); - } - } - - // We look for individual *long* spans, and we trim the *middle*, so that we render - // LL | ...= [0, 0, 0, ..., 0, 0]; - // | ^^^^^^^^^^...^^^^^^^ expected `&[u8]`, found `[{integer}; 1680]` - for (i, (_pos, annotation)) in annotations_position.iter().enumerate() { - // Skip cases where multiple spans overlap each other. - if overlap[i] { - continue; - }; - let AnnotationType::Singleline = annotation.annotation_type else { continue }; - let width = annotation.end_col.display - annotation.start_col.display; - if width > margin.column_width * 2 && width > 10 { - // If the terminal is *too* small, we keep at least a tiny bit of the span for - // display. - let pad = max(margin.column_width / 3, 5); - // Code line - buffer.replace( - line_offset, - annotation.start_col.file + pad, - annotation.end_col.file - pad, - self.margin(), - ); - // Underline line - buffer.replace( - line_offset + 1, - annotation.start_col.file + pad, - annotation.end_col.file - pad, - self.margin(), - ); - } - } - annotations_position - .iter() - .filter_map(|&(_, annotation)| match annotation.annotation_type { - AnnotationType::MultilineStart(p) | AnnotationType::MultilineEnd(p) => { - let style = if annotation.is_primary { - Style::LabelPrimary - } else { - Style::LabelSecondary - }; - Some((p, style)) - } - _ => None, - }) - .collect::>() - } - - fn get_multispan_max_line_num(&mut self, msp: &MultiSpan) -> usize { - let Some(ref sm) = self.sm else { - return 0; - }; - - let will_be_emitted = |span: Span| { - !span.is_dummy() && { - let file = sm.lookup_source_file(span.hi()); - should_show_source_code(&self.ignored_directories_in_source_blocks, sm, &file) - } - }; - - let mut max = 0; - for primary_span in msp.primary_spans() { - if will_be_emitted(*primary_span) { - let hi = sm.lookup_char_pos(primary_span.hi()); - max = (hi.line).max(max); - } - } - if !self.short_message { - for span_label in msp.span_labels() { - if will_be_emitted(span_label.span) { - let hi = sm.lookup_char_pos(span_label.span.hi()); - max = (hi.line).max(max); - } - } - } - - max - } - - fn get_max_line_num(&mut self, span: &MultiSpan, children: &[Subdiag]) -> usize { - let primary = self.get_multispan_max_line_num(span); - children - .iter() - .map(|sub| self.get_multispan_max_line_num(&sub.span)) - .max() - .unwrap_or(0) - .max(primary) - } - - /// Adds a left margin to every line but the first, given a padding length and the label being - /// displayed, keeping the provided highlighting. - fn msgs_to_buffer( - &self, - buffer: &mut StyledBuffer, - msgs: &[(DiagMessage, Style)], - args: &FluentArgs<'_>, - padding: usize, - label: &str, - override_style: Option
#[allow(dead_code)]
 #[rustfmt::skip]
-#[proc_macros::identity]
+#[proc_macros::identity]
 #[derive(Default)]
 /// This is a doc comment
 // This is a normal comment
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
index e3daeef84109..982e89dfab69 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
@@ -54,7 +54,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         foo!(Bar);
         fn func(_: y::Bar) {
             mod inner {
-                struct Innerest<const C: usize> { field: [(); {C}] }
+                struct Innerest<const C: usize> { field: [u32; {C}], field2: &Innerest }
             }
         }
     }
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
index a6e6b16bead5..0b32cedca5d8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
@@ -41,25 +41,25 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
-
extern crate foo;
-use core::iter;
+
extern crate foo;
+use core::iter;
 
 pub const NINETY_TWO: u8 = 92;
 
-use foo as foooo;
+use foo as foooo;
 
-pub(crate) fn main() {
+pub(crate) fn main() {
     let baz = iter::repeat(92);
 }
 
 mod bar {
-    pub(in super) const FORTY_TWO: u8 = 42;
+    pub(in super) const FORTY_TWO: u8 = 42;
 
     mod baz {
-        use super::super::NINETY_TWO;
-        use crate::foooo::Point;
+        use super::super::NINETY_TWO;
+        use crate::foooo::Point;
 
-        pub(in super::super) const TWENTY_NINE: u8 = 29;
+        pub(in super::super) const TWENTY_NINE: u8 = 29;
     }
 }
 
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html index 2f4a2004f1de..29f78959a54f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html @@ -41,7 +41,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
use core::iter;
+
use core::iter;
 
 fn main() {
     let foo = Some(92);
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
index 41d3dff8ed9e..5287affbfc5c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
@@ -42,8 +42,8 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
 
#![deprecated]
-use crate as _;
-extern crate bar;
+use crate as _;
+extern crate bar;
 #[deprecated]
 macro_rules! macro_ {
     () => {};
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index b5c3df6ee447..ce9ec7431a97 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -48,9 +48,9 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 //! Syntactic name ref highlighting testing
 //! ```rust
-//! extern crate self;
-//! extern crate other as otter;
-//! extern crate core;
+//! extern crate self;
+//! extern crate other as otter;
+//! extern crate core;
 //! trait T { type Assoc; }
 //! fn f<Arg>() -> use<Arg> where (): T<Assoc = ()> {}
 //! ```
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
index 3a4518236883..8f7cbddd7ffb 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
@@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
-
extern crate self as this;
-extern crate std;
-extern crate alloc as abc;
-extern crate unresolved as definitely_unresolved;
+
extern crate self as this;
+extern crate std;
+extern crate alloc as abc;
+extern crate unresolved as definitely_unresolved;
 extern crate unresolved as _;
-extern crate test as opt_in_crate;
-extern crate test as _;
-extern crate proc_macro;
+extern crate test as opt_in_crate;
+extern crate test as _;
+extern crate proc_macro;
 
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index fd652f444ffd..c6dbc435c0e8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -72,7 +72,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } } -use self::FooCopy::{self as BarCopy}; +use self::FooCopy::{self as BarCopy}; #[derive(Copy)] struct FooCopy { @@ -110,7 +110,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd FOO } -use core::ops::Fn; +use core::ops::Fn; fn baz<F: Fn() -> ()>(f: F) { f() } @@ -184,15 +184,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd } fn use_foo_items() { - let bob = foo::Person { + let bob = foo::Person { name: "Bob", - age: foo::consts::NUMBER, + age: foo::consts::NUMBER, }; - let control_flow = foo::identity(foo::ControlFlow::Continue); + let control_flow = foo::identity(foo::ControlFlow::Continue); if control_flow.should_die() { - foo::die!(); + foo::die!(); } } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html index 5a5d9bd1f909..391a46f706c8 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html @@ -47,7 +47,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd fixture(r#" @@- /main.rs crate:main deps:other_crate fn test() { - let x = other_crate::foo::S::thing(); + let x = other_crate::foo::S::thing(); x; } //^ i128 diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html index b28818e679ff..fccf34083d7f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html @@ -45,5 +45,5 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd template!(template); } -#[proc_macros::issue_18089] +#[proc_macros::issue_18089] fn template() {}
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html index d2a53b2ff9e1..6366cba1bd03 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html @@ -41,12 +41,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
extern crate self;
+
extern crate self;
 
-use crate;
-use self;
+use crate;
+use self;
 mod __ {
-    use super::*;
+    use super::*;
 }
 
 macro_rules! void {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
index d309b4723238..a89e8190832e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
@@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
-
extern crate self;
+
extern crate self;
 
-use crate;
-use self;
+use crate;
+use self;
 mod __ {
-    use super::*;
+    use super::*;
 }
 
 macro_rules! void {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
index d309b4723238..a89e8190832e 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
@@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
-
extern crate self;
+
extern crate self;
 
-use crate;
-use self;
+use crate;
+use self;
 mod __ {
-    use super::*;
+    use super::*;
 }
 
 macro_rules! void {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
index 575c9a6b0aca..aa1500b8f85b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
@@ -41,12 +41,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
-
extern crate self;
+
extern crate self;
 
-use crate;
-use self;
+use crate;
+use self;
 mod __ {
-    use super::*;
+    use super::*;
 }
 
 macro_rules! void {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
index caf66ace7a68..484afd81ead2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
@@ -41,6 +41,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
-
lib2015::void_2015!(try async await gen);
-lib2024::void_2024!(try async await gen);
+
lib2015::void_2015!(try async await gen);
+lib2024::void_2024!(try async await gen);
 
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html index b63d5cedc825..740a6272a79a 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html @@ -41,7 +41,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; } .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
use proc_macros::{mirror, identity, DeriveIdentity};
+
use proc_macros::{mirror, identity, DeriveIdentity};
+use pm::proc_macro;
 
 mirror! {
     {
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
index d5401e7aec91..7c64707ac1f9 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
@@ -42,14 +42,14 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 
 
fn main() {
-    let hello = "hello";
-    let x = hello.to_string();
-    let y = hello.to_string();
+    let hello = "hello";
+    let x = hello.to_string();
+    let y = hello.to_string();
 
-    let x = "other color please!";
-    let y = x.to_string();
+    let x = "other color please!";
+    let y = x.to_string();
 }
 
 fn bar() {
-    let mut hello = "hello";
+    let mut hello = "hello";
 }
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 1b0512977a38..4e3822c3d31f 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html @@ -101,18 +101,18 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd println!("Hello, {}!", "world"); // => "Hello, world!" println!("The number is {}", 1); // => "The number is 1" println!("{:?}", (3, 4)); // => "(3, 4)" - println!("{value}", value=4); // => "4" + println!("{value}", value=4); // => "4" println!("{} {}", 1, 2); // => "1 2" println!("{:04}", 42); // => "0042" with leading zerosV println!("{1} {} {0} {}", 1, 2); // => "2 1 1 2" - println!("{argument}", argument = "test"); // => "test" - println!("{name} {}", 1, name = 2); // => "2 1" - println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" + println!("{argument}", argument = "test"); // => "test" + println!("{name} {}", 1, name = 2); // => "2 1" + println!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b" println!("{{{}}}", 2); // => "{2}" println!("Hello {:5}!", "x"); println!("Hello {:1$}!", "x", 5); println!("Hello {1:0$}!", 5, "x"); - println!("Hello {:width$}!", "x", width = 5); + println!("Hello {:width$}!", "x", width = 5); println!("Hello {:<5}!", "x"); println!("Hello {:-<5}!", "x"); println!("Hello {:^5}!", "x"); @@ -127,10 +127,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd println!("Hello {0} is {2:.1$}", "x", 5, 0.01); println!("Hello {} is {:.*}", "x", 5, 0.01); println!("Hello {} is {2:.*}", "x", 5, 0.01); - println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); - println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); - println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); - println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); + println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); + println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); + println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); + println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); let _ = "{}" let _ = "{{}}"; @@ -154,8 +154,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd let _ = c"\u{FF}\xFF"; // valid bytes, valid unicodes let backslash = r"\\"; - println!("{\x41}", A = 92); - println!("{ничоÑи}", ничоÑи = 92); + println!("{\x41}", A = 92); + println!("{ничоÑи}", ничоÑи = 92); println!("{:x?} {} ", thingy, n2); panic!("{}", 0); @@ -165,7 +165,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd toho!("{}fmt", 0); let i: u64 = 3; let o: u64; - core::arch::asm!( + core::arch::asm!( "mov {0}, {1}", "add {0}, 5", out(reg) o, diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings_disabled.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings_disabled.html new file mode 100644 index 000000000000..344d0c2ff03b --- /dev/null +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings_disabled.html @@ -0,0 +1,47 @@ + + +
fn main() {
+    format_args!("foo\nbar");
+    format_args!("foo\invalid");
+}
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index 93513f5b575d..008987d409ad 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html @@ -91,7 +91,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd // unsafe fn and method calls unsafe_fn(); - self::unsafe_fn(); + self::unsafe_fn(); (unsafe_fn as unsafe fn())(); Struct { field: 0 }.unsafe_method(); @@ -120,7 +120,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd &EXTERN_STATIC; &raw const EXTERN_STATIC; - core::arch::asm!( + core::arch::asm!( "push {base}", base = const 0 ); diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index b7510e3abaea..c6aebd0b0cd1 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -55,8 +55,9 @@ fn macros() { r#" //- proc_macros: mirror, identity, derive_identity //- minicore: fmt, include, concat -//- /lib.rs crate:lib +//- /lib.rs crate:lib deps:pm use proc_macros::{mirror, identity, DeriveIdentity}; +use pm::proc_macro; mirror! { { @@ -126,6 +127,11 @@ fn main() { //- /foo/foo.rs crate:foo mod foo {} use self::foo as bar; +//- /pm.rs crate:pm +#![crate_type = "proc-macro"] + +#[proc_macro_attribute] +pub fn proc_macro() {} "#, expect_file!["./test_data/highlight_macros.html"], false, @@ -1183,7 +1189,7 @@ fn main() { foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest { field: [(); {C}] } + struct Innerest { field: [u32; {C}], field2: &Innerest } } } } @@ -1498,6 +1504,23 @@ fn main() { ); } +#[test] +fn test_strings_highlighting_disabled() { + // Test that comments are not highlighted when disabled + check_highlighting_with_config( + r#" +//- minicore: fmt +fn main() { + format_args!("foo\nbar"); + format_args!("foo\invalid"); +} +"#, + HighlightConfig { strings: false, ..HL_CONFIG }, + expect_file!["./test_data/highlight_strings_disabled.html"], + false, + ); +} + #[test] fn regression_20952() { check_highlighting( diff --git a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs index bd60ffe55912..4792566f5f5b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs +++ b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs @@ -135,11 +135,11 @@ fn find_module_id_and_test_parents( module: Module, ) -> Option<(Vec, String)> { let Some(parent) = module.parent(sema.db) else { - let name = module.krate().display_name(sema.db)?.to_string(); + let name = module.krate(sema.db).display_name(sema.db)?.to_string(); return Some(( vec![TestItem { id: name.clone(), - kind: TestItemKind::Crate(module.krate().into()), + kind: TestItemKind::Crate(module.krate(sema.db).into()), label: name.clone(), parent: None, file: None, @@ -181,7 +181,7 @@ pub(crate) fn discover_tests_in_crate( let kind = TestItemKind::Crate(crate_id); let crate_test_id = crate_test_id.to_string(); let crate_id: Crate = crate_id.into(); - let module = crate_id.root_module(); + let module = crate_id.root_module(db); let mut r = vec![TestItem { id: crate_test_id.clone(), kind, diff --git a/src/tools/rust-analyzer/crates/ide/src/typing.rs b/src/tools/rust-analyzer/crates/ide/src/typing.rs index 0381865fed45..f8b0dbfe6282 100644 --- a/src/tools/rust-analyzer/crates/ide/src/typing.rs +++ b/src/tools/rust-analyzer/crates/ide/src/typing.rs @@ -17,7 +17,10 @@ mod on_enter; use either::Either; use hir::EditionedFileId; -use ide_db::{FilePosition, RootDatabase, base_db::RootQueryDb}; +use ide_db::{ + FilePosition, RootDatabase, + base_db::{RootQueryDb, SourceDatabase}, +}; use span::Edition; use std::iter; @@ -70,11 +73,12 @@ pub(crate) fn on_char_typed( if !TRIGGER_CHARS.contains(&char_typed) { return None; } - // FIXME: We need to figure out the edition of the file here, but that means hitting the - // database for more than just parsing the file which is bad. + let edition = db + .source_root_crates(db.file_source_root(position.file_id).source_root_id(db)) + .first() + .map_or(Edition::CURRENT, |crates| crates.data(db).edition); // FIXME: We are hitting the database here, if we are unlucky this call might block momentarily - // causing the editor to feel sluggish! - let edition = Edition::CURRENT_FIXME; + // causing the editor to feel sluggish! We need to make this bail if it would block too long? let editioned_file_id_wrapper = EditionedFileId::from_span_guess_origin( db, span::EditionedFileId::new(position.file_id, edition), @@ -457,8 +461,8 @@ mod tests { let (offset, mut before) = extract_offset(before); let edit = TextEdit::insert(offset, char_typed.to_string()); edit.apply(&mut before); - let parse = SourceFile::parse(&before, span::Edition::CURRENT_FIXME); - on_char_typed_(&parse, offset, char_typed, span::Edition::CURRENT_FIXME).map(|it| { + let parse = SourceFile::parse(&before, span::Edition::CURRENT); + on_char_typed_(&parse, offset, char_typed, span::Edition::CURRENT).map(|it| { it.apply(&mut before); before.to_string() }) diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml index 81b6703deef5..ad73c191c047 100644 --- a/src/tools/rust-analyzer/crates/intern/Cargo.toml +++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml @@ -18,6 +18,7 @@ dashmap.workspace = true hashbrown.workspace = true rustc-hash.workspace = true triomphe.workspace = true +rayon.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/intern/src/gc.rs b/src/tools/rust-analyzer/crates/intern/src/gc.rs new file mode 100644 index 000000000000..937de26831e2 --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/gc.rs @@ -0,0 +1,331 @@ +//! Garbage collection of interned values. +//! +//! The GC is a simple mark-and-sweep GC: you first mark all storages, then the +//! GC visits them, and each live value they refer, recursively, then removes +//! those not marked. The sweep phase is done in parallel. + +use std::{hash::Hash, marker::PhantomData, ops::ControlFlow}; + +use dashmap::DashMap; +use hashbrown::raw::RawTable; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use rustc_hash::{FxBuildHasher, FxHashSet}; +use triomphe::{Arc, ThinArc}; + +use crate::{Internable, InternedRef, InternedSliceRef, SliceInternable}; + +trait Storage { + fn len(&self) -> usize; + + fn mark(&self, gc: &mut GarbageCollector); + + fn sweep(&self, gc: &GarbageCollector); +} + +struct InternedStorage(PhantomData T>); + +impl Storage for InternedStorage { + fn len(&self) -> usize { + T::storage().get().len() + } + + fn mark(&self, gc: &mut GarbageCollector) { + let storage = T::storage().get(); + for item in storage { + let item = item.key(); + let addr = Arc::as_ptr(item).addr(); + if Arc::strong_count(item) > 1 { + // The item is referenced from the outside. + gc.alive.insert(addr); + item.visit_with(gc); + } + } + } + + fn sweep(&self, gc: &GarbageCollector) { + let storage = T::storage().get(); + gc.sweep_storage(storage, |item| item.as_ptr().addr()); + } +} + +struct InternedSliceStorage(PhantomData T>); + +impl Storage for InternedSliceStorage { + fn len(&self) -> usize { + T::storage().get().len() + } + + fn mark(&self, gc: &mut GarbageCollector) { + let storage = T::storage().get(); + for item in storage { + let item = item.key(); + let addr = ThinArc::as_ptr(item).addr(); + if ThinArc::strong_count(item) > 1 { + // The item is referenced from the outside. + gc.alive.insert(addr); + T::visit_header(&item.header.header, gc); + T::visit_slice(&item.slice, gc); + } + } + } + + fn sweep(&self, gc: &GarbageCollector) { + let storage = T::storage().get(); + gc.sweep_storage(storage, |item| item.as_ptr().addr()); + } +} + +pub trait GcInternedVisit { + fn visit_with(&self, gc: &mut GarbageCollector); +} + +pub trait GcInternedSliceVisit: SliceInternable { + fn visit_header(header: &Self::Header, gc: &mut GarbageCollector); + fn visit_slice(header: &[Self::SliceType], gc: &mut GarbageCollector); +} + +#[derive(Default)] +pub struct GarbageCollector { + alive: FxHashSet, + storages: Vec<&'static (dyn Storage + Send + Sync)>, +} + +impl GarbageCollector { + pub fn add_storage(&mut self) { + const { assert!(T::USE_GC) }; + + self.storages.push(&InternedStorage::(PhantomData)); + } + + pub fn add_slice_storage(&mut self) { + const { assert!(T::USE_GC) }; + + self.storages.push(&InternedSliceStorage::(PhantomData)); + } + + /// # Safety + /// + /// - This cannot be called if there are some not-yet-recorded type values. + /// - All relevant storages must have been added; that is, within the full graph of values, + /// the added storages must form a DAG. + /// - [`GcInternedVisit`] and [`GcInternedSliceVisit`] must mark all values reachable from the node. + pub unsafe fn collect(mut self) { + let total_nodes = self.storages.iter().map(|storage| storage.len()).sum(); + self.alive.clear(); + self.alive.reserve(total_nodes); + + let storages = std::mem::take(&mut self.storages); + + for &storage in &storages { + storage.mark(&mut self); + } + + // Miri doesn't support rayon. + if cfg!(miri) { + storages.iter().for_each(|storage| storage.sweep(&self)); + } else { + storages.par_iter().for_each(|storage| storage.sweep(&self)); + } + } + + pub fn mark_interned_alive( + &mut self, + interned: InternedRef<'_, T>, + ) -> ControlFlow<()> { + if interned.strong_count() > 1 { + // It will be visited anyway, so short-circuit + return ControlFlow::Break(()); + } + let addr = interned.as_raw().addr(); + if !self.alive.insert(addr) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } + } + + pub fn mark_interned_slice_alive( + &mut self, + interned: InternedSliceRef<'_, T>, + ) -> ControlFlow<()> { + if interned.strong_count() > 1 { + // It will be visited anyway, so short-circuit + return ControlFlow::Break(()); + } + let addr = interned.as_raw().addr(); + if !self.alive.insert(addr) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } + } + + fn sweep_storage( + &self, + storage: &DashMap, + get_addr: impl Fn(&T) -> usize + Send + Sync, + ) { + // Miri doesn't support rayon. + if cfg!(miri) { + storage.shards().iter().for_each(|shard| { + self.retain_only_alive(&mut *shard.write(), |item| get_addr(&item.0)) + }); + } else { + storage.shards().par_iter().for_each(|shard| { + self.retain_only_alive(&mut *shard.write(), |item| get_addr(&item.0)) + }); + } + } + + #[inline] + fn retain_only_alive(&self, map: &mut RawTable, mut get_addr: impl FnMut(&T) -> usize) { + // This code was copied from DashMap's retain() - which we can't use because we want to run in parallel. + unsafe { + // Here we only use `iter` as a temporary, preventing use-after-free + for bucket in map.iter() { + let item = bucket.as_mut(); + let addr = get_addr(item); + if !self.alive.contains(&addr) { + map.erase(bucket); + } + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::{ + GarbageCollector, GcInternedSliceVisit, GcInternedVisit, Interned, InternedSliceRef, + }; + + crate::impl_internable!(String); + + #[test] + fn simple_interned() { + let a = Interned::new("abc".to_owned()); + let b = Interned::new("abc".to_owned()); + assert_eq!(a, b); + assert_eq!(a.as_ref(), b.as_ref()); + assert_eq!(a.as_ref(), a.as_ref()); + assert_eq!(a, a.clone()); + assert_eq!(a, a.clone().clone()); + assert_eq!(b.clone(), a.clone().clone()); + assert_eq!(*a, "abc"); + assert_eq!(*b, "abc"); + assert_eq!(b.as_ref().to_owned(), a); + let c = Interned::new("def".to_owned()); + assert_ne!(a, c); + assert_ne!(b, c); + assert_ne!(b.as_ref(), c.as_ref()); + assert_eq!(*c.as_ref(), "def"); + drop(c); + assert_eq!(*a, "abc"); + assert_eq!(*b, "abc"); + drop(a); + assert_eq!(*b, "abc"); + drop(b); + } + + #[test] + fn simple_gc() { + #[derive(Debug, PartialEq, Eq, Hash)] + struct GcString(String); + + crate::impl_internable!(gc; GcString); + + impl GcInternedVisit for GcString { + fn visit_with(&self, _gc: &mut GarbageCollector) {} + } + + crate::impl_slice_internable!(gc; StringSlice, String, u32); + type InternedSlice = crate::InternedSlice; + + impl GcInternedSliceVisit for StringSlice { + fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {} + + fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {} + } + + let (a, d) = { + let a = Interned::new_gc(GcString("abc".to_owned())).to_owned(); + let b = Interned::new_gc(GcString("abc".to_owned())).to_owned(); + assert_eq!(a, b); + assert_eq!(a.as_ref(), b.as_ref()); + assert_eq!(a.as_ref(), a.as_ref()); + assert_eq!(a, a.clone()); + assert_eq!(a, a.clone().clone()); + assert_eq!(b.clone(), a.clone().clone()); + assert_eq!(a.0, "abc"); + assert_eq!(b.0, "abc"); + assert_eq!(b.as_ref().to_owned(), a); + let c = Interned::new_gc(GcString("def".to_owned())).to_owned(); + assert_ne!(a, c); + assert_ne!(b, c); + assert_ne!(b.as_ref(), c.as_ref()); + assert_eq!(c.as_ref().0, "def"); + + let d = InternedSlice::from_header_and_slice("abc".to_owned(), &[123, 456]); + let e = InternedSlice::from_header_and_slice("abc".to_owned(), &[123, 456]); + assert_eq!(d, e); + assert_eq!(d.to_owned(), e.to_owned()); + assert_eq!(d.header.length, 2); + assert_eq!(d.header.header, "abc"); + assert_eq!(d.slice, [123, 456]); + (a, d.to_owned()) + }; + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + + assert_eq!(a.0, "abc"); + assert_eq!(d.header.length, 2); + assert_eq!(d.header.header, "abc"); + assert_eq!(d.slice, [123, 456]); + + drop(a); + drop(d); + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + } + + #[test] + fn gc_visit() { + #[derive(PartialEq, Eq, Hash)] + struct GcInterned(InternedSliceRef<'static, StringSlice>); + + crate::impl_internable!(gc; GcInterned); + + impl GcInternedVisit for GcInterned { + fn visit_with(&self, gc: &mut GarbageCollector) { + _ = gc.mark_interned_slice_alive(self.0); + } + } + + crate::impl_slice_internable!(gc; StringSlice, String, i32); + type InternedSlice = crate::InternedSlice; + + impl GcInternedSliceVisit for StringSlice { + fn visit_header(_header: &Self::Header, _gc: &mut GarbageCollector) {} + + fn visit_slice(_header: &[Self::SliceType], _gc: &mut GarbageCollector) {} + } + + let outer = { + let inner = InternedSlice::from_header_and_slice("abc".to_owned(), &[123, 456, 789]); + Interned::new_gc(GcInterned(inner)).to_owned() + }; + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + + assert_eq!(outer.0.header.header, "abc"); + assert_eq!(outer.0.slice, [123, 456, 789]); + + drop(outer); + + let mut gc = GarbageCollector::default(); + gc.add_slice_storage::(); + gc.add_storage::(); + unsafe { gc.collect() }; + } +} diff --git a/src/tools/rust-analyzer/crates/intern/src/intern.rs b/src/tools/rust-analyzer/crates/intern/src/intern.rs new file mode 100644 index 000000000000..a96dfcfa9fe3 --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/intern.rs @@ -0,0 +1,372 @@ +//! Interning of single values. +//! +//! Interning supports two modes: GC and non-GC. +//! +//! In non-GC mode, you create [`Interned`]s, and can create `Copy` handles to them +//! that can still be upgraded back to [`Interned`] ([`InternedRef`]) via [`Interned::as_ref`]. +//! Generally, letting the [`InternedRef`] to outlive the [`Interned`] is a soundness bug and can +//! lead to UB. When all [`Interned`]s of some value are dropped, the value is freed (newer interns +//! may re-create it, not necessarily in the same place). +//! +//! In GC mode, you generally operate on [`InternedRef`]s. They are `Copy` and comfortable. To intern +//! a value you call [`Interned::new_gc`], which returns an [`InternedRef`]. Having all [`Interned`]s +//! of some value be dropped will *not* immediately free the value. Instead, a mark-and-sweep GC can +//! be initiated, which will free all values which have no live [`Interned`]s. +//! +//! Generally, in GC mode, you operate on [`InternedRef`], but when you need to store some long-term +//! value (e.g. a Salsa query output), you convert it to an [`Interned`]. This ensures that an eventual +//! GC will not free it as long as it is alive. +//! +//! Making mistakes is hard due to GC [`InternedRef`] wrappers not implementing `salsa::Update`, meaning +//! Salsa will ensure you do not store them in queries or Salsa-interneds. However it's still *possible* +//! without unsafe code (for example, by storing them in a `static`), which is why triggering GC is unsafe. +//! +//! For more information about GC see [`crate::gc`]. + +use std::{ + fmt::{self, Debug, Display}, + hash::{BuildHasher, Hash, Hasher}, + ops::Deref, + ptr, + sync::OnceLock, +}; + +use dashmap::{DashMap, SharedValue}; +use hashbrown::raw::RawTable; +use rustc_hash::FxBuildHasher; +use triomphe::{Arc, ArcBorrow}; + +type InternMap = DashMap, (), FxBuildHasher>; +type Guard = dashmap::RwLockWriteGuard<'static, RawTable<(Arc, SharedValue<()>)>>; + +pub struct Interned { + arc: Arc, +} + +impl Interned { + #[inline] + pub fn new(obj: T) -> Self { + const { assert!(!T::USE_GC) }; + + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &obj); + // Atomically, + // - check if `obj` is already in the map + // - if so, clone its `Arc` and return it + // - if not, box it up, insert it, and return a clone + // This needs to be atomic (locking the shard) to avoid races with other thread, which could + // insert the same object between us looking it up and inserting it. + let bucket = match shard.find_or_find_insert_slot( + hash, + |(other, _)| **other == obj, + |(x, _)| Self::hash(storage, x), + ) { + Ok(bucket) => bucket, + // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. + Err(insert_slot) => unsafe { + shard.insert_in_slot(hash, insert_slot, (Arc::new(obj), SharedValue::new(()))) + }, + }; + // SAFETY: We just retrieved/inserted this bucket. + unsafe { Self { arc: bucket.as_ref().0.clone() } } + } + + #[inline] + pub fn new_gc<'a>(obj: T) -> InternedRef<'a, T> { + const { assert!(T::USE_GC) }; + + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &obj); + // Atomically, + // - check if `obj` is already in the map + // - if so, clone its `Arc` and return it + // - if not, box it up, insert it, and return a clone + // This needs to be atomic (locking the shard) to avoid races with other thread, which could + // insert the same object between us looking it up and inserting it. + let bucket = match shard.find_or_find_insert_slot( + hash, + |(other, _)| **other == obj, + |(x, _)| Self::hash(storage, x), + ) { + Ok(bucket) => bucket, + // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. + Err(insert_slot) => unsafe { + shard.insert_in_slot(hash, insert_slot, (Arc::new(obj), SharedValue::new(()))) + }, + }; + // SAFETY: We just retrieved/inserted this bucket. + unsafe { InternedRef { arc: Arc::borrow_arc(&bucket.as_ref().0) } } + } + + #[inline] + fn select(storage: &'static InternMap, obj: &T) -> (Guard, u64) { + let hash = Self::hash(storage, obj); + let shard_idx = storage.determine_shard(hash as usize); + let shard = &storage.shards()[shard_idx]; + (shard.write(), hash) + } + + #[inline] + fn hash(storage: &'static InternMap, obj: &T) -> u64 { + storage.hasher().hash_one(obj) + } + + /// # Safety + /// + /// The pointer should originate from an `Interned` or an `InternedRef`. + #[inline] + pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Our precondition. + Self { arc: unsafe { Arc::from_raw(ptr) } } + } + + #[inline] + pub fn as_ref(&self) -> InternedRef<'_, T> { + InternedRef { arc: self.arc.borrow_arc() } + } +} + +impl Drop for Interned { + #[inline] + fn drop(&mut self) { + // When the last `Ref` is dropped, remove the object from the global map. + if !T::USE_GC && Arc::count(&self.arc) == 2 { + // Only `self` and the global map point to the object. + + self.drop_slow(); + } + } +} + +impl Interned { + #[cold] + fn drop_slow(&mut self) { + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &self.arc); + + if Arc::count(&self.arc) != 2 { + // Another thread has interned another copy + return; + } + + shard.remove_entry(hash, |(other, _)| **other == **self); + + // Shrink the backing storage if the shard is less than 50% occupied. + if shard.len() * 2 < shard.capacity() { + let len = shard.len(); + shard.shrink_to(len, |(x, _)| Self::hash(storage, x)); + } + } +} + +/// Compares interned `Ref`s using pointer equality. +impl PartialEq for Interned { + // NOTE: No `?Sized` because `ptr_eq` doesn't work right with trait objects. + + #[inline] + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.arc, &other.arc) + } +} + +impl Eq for Interned {} + +impl Hash for Interned { + #[inline] + fn hash(&self, state: &mut H) { + state.write_usize(self.arc.as_ptr().addr()) + } +} + +impl AsRef for Interned { + #[inline] + fn as_ref(&self) -> &T { + self + } +} + +impl Deref for Interned { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.arc + } +} + +impl Clone for Interned { + #[inline] + fn clone(&self) -> Self { + Self { arc: self.arc.clone() } + } +} + +impl Debug for Interned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(&**self, f) + } +} + +impl Display for Interned { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ::fmt(&**self, f) + } +} + +#[repr(transparent)] +pub struct InternedRef<'a, T> { + arc: ArcBorrow<'a, T>, +} + +impl<'a, T: Internable> InternedRef<'a, T> { + #[inline] + pub fn as_raw(self) -> *const T { + // Not `ptr::from_ref(&*self.arc)`, because we need to keep the provenance. + self.arc.with_arc(|arc| Arc::as_ptr(arc)) + } + + /// # Safety + /// + /// The pointer needs to originate from `Interned` or `InternedRef`. + #[inline] + pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Our precondition. + Self { arc: unsafe { ArcBorrow::from_ptr(ptr) } } + } + + #[inline] + pub fn to_owned(self) -> Interned { + Interned { arc: self.arc.clone_arc() } + } + + #[inline] + pub fn get(self) -> &'a T { + self.arc.get() + } + + /// # Safety + /// + /// You have to make sure the data is not referenced after the refcount reaches zero; beware the interning + /// map also keeps a reference to the value. + #[inline] + pub unsafe fn decrement_refcount(self) { + // SAFETY: Our precondition. + unsafe { drop(Arc::from_raw(self.as_raw())) } + } + + #[inline] + pub(crate) fn strong_count(self) -> usize { + ArcBorrow::strong_count(&self.arc) + } + + /// **Available only on GC mode**. + /// + /// Changes the attached lifetime, as in GC mode, the lifetime is more kind of a lint to prevent misuse + /// than actual soundness check. + #[inline] + pub fn change_lifetime<'b>(self) -> InternedRef<'b, T> { + const { assert!(T::USE_GC) }; + // SAFETY: The lifetime on `InternedRef` is essentially advisory only for GCed types. + unsafe { std::mem::transmute::, InternedRef<'b, T>>(self) } + } +} + +impl Clone for InternedRef<'_, T> { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +impl Copy for InternedRef<'_, T> {} + +impl Hash for InternedRef<'_, T> { + #[inline] + fn hash(&self, state: &mut H) { + let ptr = ptr::from_ref::(&*self.arc); + state.write_usize(ptr.addr()); + } +} + +impl PartialEq for InternedRef<'_, T> { + #[inline] + fn eq(&self, other: &Self) -> bool { + ArcBorrow::ptr_eq(&self.arc, &other.arc) + } +} + +impl Eq for InternedRef<'_, T> {} + +impl Deref for InternedRef<'_, T> { + type Target = T; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.arc + } +} + +impl Debug for InternedRef<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (*self.arc).fmt(f) + } +} + +impl Display for InternedRef<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (*self.arc).fmt(f) + } +} + +pub struct InternStorage { + map: OnceLock>, +} + +#[allow( + clippy::new_without_default, + reason = "this a const fn, so it can't be default yet. See " +)] +impl InternStorage { + pub const fn new() -> Self { + Self { map: OnceLock::new() } + } +} + +impl InternStorage { + pub(crate) fn get(&self) -> &InternMap { + self.map.get_or_init(|| DashMap::with_capacity_and_hasher(1024, Default::default())) + } +} + +pub trait Internable: Hash + Eq + Send + Sync + 'static { + const USE_GC: bool; + + fn storage() -> &'static InternStorage; +} + +/// Implements `Internable` for a given list of types, making them usable with `Interned`. +#[macro_export] +#[doc(hidden)] +macro_rules! _impl_internable { + ( gc; $($t:ty),+ $(,)? ) => { $( + impl $crate::Internable for $t { + const USE_GC: bool = true; + + fn storage() -> &'static $crate::InternStorage { + static STORAGE: $crate::InternStorage<$t> = $crate::InternStorage::new(); + &STORAGE + } + } + )+ }; + ( $($t:ty),+ $(,)? ) => { $( + impl $crate::Internable for $t { + const USE_GC: bool = false; + + fn storage() -> &'static $crate::InternStorage { + static STORAGE: $crate::InternStorage<$t> = $crate::InternStorage::new(); + &STORAGE + } + } + )+ }; +} +pub use crate::_impl_internable as impl_internable; diff --git a/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs new file mode 100644 index 000000000000..8857771d2e01 --- /dev/null +++ b/src/tools/rust-analyzer/crates/intern/src/intern_slice.rs @@ -0,0 +1,330 @@ +//! Interning of slices, potentially with a header. +//! +//! See [`crate::intern`] for an explanation of interning modes. Note that slice interning is currently +//! available only in GC mode (there is no other need). +//! +//! [`InternedSlice`] and [`InternedSliceRef`] are essentially [`Interned<(Header, Box<[SliceType]>)>`][crate::Interned] +//! and [`InternedRef`][crate::InternedRef] with the same types, but more optimized. There is only one +//! allocation and the pointer is thin. + +use std::{ + ffi::c_void, + fmt::{self, Debug}, + hash::{BuildHasher, Hash, Hasher}, + marker::PhantomData, + mem::ManuallyDrop, + ops::Deref, + ptr::{self, NonNull}, + sync::OnceLock, +}; + +use dashmap::{DashMap, SharedValue}; +use hashbrown::raw::RawTable; +use rustc_hash::FxBuildHasher; +use triomphe::{HeaderSlice, HeaderWithLength, ThinArc}; + +type InternMap = DashMap< + ThinArc<::Header, ::SliceType>, + (), + FxBuildHasher, +>; +type Guard = dashmap::RwLockWriteGuard< + 'static, + RawTable<( + ThinArc<::Header, ::SliceType>, + SharedValue<()>, + )>, +>; +type Pointee = HeaderSlice< + HeaderWithLength<::Header>, + [::SliceType], +>; + +pub struct InternedSlice { + arc: ThinArc, +} + +impl InternedSlice { + #[inline] + pub fn from_header_and_slice<'a>( + header: T::Header, + slice: &[T::SliceType], + ) -> InternedSliceRef<'a, T> { + const { assert!(T::USE_GC) }; + + let storage = T::storage().get(); + let (mut shard, hash) = Self::select(storage, &header, slice); + // Atomically, + // - check if `obj` is already in the map + // - if so, clone its `Arc` and return it + // - if not, box it up, insert it, and return a clone + // This needs to be atomic (locking the shard) to avoid races with other thread, which could + // insert the same object between us looking it up and inserting it. + let bucket = match shard.find_or_find_insert_slot( + hash, + |(other, _)| other.header.header == header && other.slice == *slice, + |(x, _)| storage.hasher().hash_one(x), + ) { + Ok(bucket) => bucket, + // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. + Err(insert_slot) => unsafe { + shard.insert_in_slot( + hash, + insert_slot, + (ThinArc::from_header_and_slice(header, slice), SharedValue::new(())), + ) + }, + }; + // SAFETY: We just retrieved/inserted this bucket. + // `NonNull::new_unchecked()` is safe because the pointer originates from a `ThinArc`. + unsafe { + InternedSliceRef { + // INVARIANT: We create it from a `ThinArc`. + ptr: NonNull::new_unchecked(ThinArc::as_ptr(&bucket.as_ref().0).cast_mut()), + _marker: PhantomData, + } + } + } + + #[inline] + fn select( + storage: &'static InternMap, + header: &T::Header, + slice: &[T::SliceType], + ) -> (Guard, u64) { + let hash = Self::hash(storage, header, slice); + let shard_idx = storage.determine_shard(hash as usize); + let shard = &storage.shards()[shard_idx]; + (shard.write(), hash) + } + + #[inline] + fn hash(storage: &'static InternMap, header: &T::Header, slice: &[T::SliceType]) -> u64 { + storage.hasher().hash_one(HeaderSlice { + header: HeaderWithLength { header, length: slice.len() }, + slice, + }) + } + + #[inline(always)] + fn ptr(&self) -> *const c_void { + self.arc.as_ptr() + } + + #[inline] + pub fn as_ref(&self) -> InternedSliceRef<'_, T> { + InternedSliceRef { + // SAFETY: `self.ptr` comes from a valid `ThinArc`, so non null. + // INVARIANT: We create it from a `ThinArc`. + ptr: unsafe { NonNull::new_unchecked(self.ptr().cast_mut()) }, + _marker: PhantomData, + } + } +} + +/// Compares interned `Ref`s using pointer equality. +impl PartialEq for InternedSlice { + // NOTE: No `?Sized` because `ptr_eq` doesn't work right with trait objects. + + #[inline] + fn eq(&self, other: &Self) -> bool { + self.arc.as_ptr() == other.arc.as_ptr() + } +} + +impl Eq for InternedSlice {} + +impl Hash for InternedSlice { + #[inline] + fn hash(&self, state: &mut H) { + state.write_usize(self.ptr().addr()) + } +} + +impl Deref for InternedSlice { + type Target = Pointee; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.arc + } +} + +impl Clone for InternedSlice { + #[inline] + fn clone(&self) -> Self { + Self { arc: self.arc.clone() } + } +} + +impl Debug for InternedSlice +where + T: SliceInternable, + T::SliceType: Debug, + T::Header: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (*self.arc).fmt(f) + } +} + +#[repr(transparent)] +pub struct InternedSliceRef<'a, T> { + /// # Invariant + /// + /// There is no `ThinArcBorrow` unfortunately, so this is basically a `ManuallyDrop`, + /// except that can't be `Copy`, so we store a raw pointer instead. + ptr: NonNull, + _marker: PhantomData<&'a T>, +} + +// SAFETY: This is essentially a `ThinArc`, implemented as a raw pointer because there is no `ThinArcBorrowed`. +unsafe impl Send for InternedSliceRef<'_, T> {} +unsafe impl Sync for InternedSliceRef<'_, T> {} + +impl<'a, T: SliceInternable> InternedSliceRef<'a, T> { + #[inline(always)] + fn arc(self) -> ManuallyDrop> { + // SAFETY: `self.ptr`'s invariant. + unsafe { ManuallyDrop::new(ThinArc::from_raw(self.ptr.as_ptr())) } + } + + #[inline] + pub fn to_owned(self) -> InternedSlice { + InternedSlice { arc: (*self.arc()).clone() } + } + + #[inline] + pub fn get(self) -> &'a Pointee { + // SAFETY: This is a lifetime extension, valid because we live for `'a`. + unsafe { &*ptr::from_ref::>(&*self.arc()) } + } + + /// # Safety + /// + /// You have to make sure the data is not referenced after the refcount reaches zero; beware the interning + /// map also keeps a reference to the value. + #[inline] + pub unsafe fn decrement_refcount(self) { + drop(ManuallyDrop::into_inner(self.arc())); + } + + #[inline] + pub(crate) fn strong_count(self) -> usize { + ThinArc::strong_count(&self.arc()) + } + + #[inline] + pub(crate) fn as_raw(self) -> *const c_void { + self.arc().as_ptr() + } + + /// **Available only on GC mode**. + /// + /// Changes the attached lifetime, as in GC mode, the lifetime is more kind of a lint to prevent misuse + /// than actual soundness check. + #[inline] + pub fn change_lifetime<'b>(self) -> InternedSliceRef<'b, T> { + const { assert!(T::USE_GC) }; + // SAFETY: The lifetime on `InternedSliceRef` is essentially advisory only for GCed types. + unsafe { std::mem::transmute::, InternedSliceRef<'b, T>>(self) } + } +} + +impl Clone for InternedSliceRef<'_, T> { + #[inline] + fn clone(&self) -> Self { + *self + } +} + +impl Copy for InternedSliceRef<'_, T> {} + +impl Hash for InternedSliceRef<'_, T> { + #[inline] + fn hash(&self, state: &mut H) { + state.write_usize(self.ptr.as_ptr().addr()); + } +} + +impl PartialEq for InternedSliceRef<'_, T> { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.ptr == other.ptr + } +} + +impl Eq for InternedSliceRef<'_, T> {} + +impl Deref for InternedSliceRef<'_, T> { + type Target = Pointee; + + #[inline] + fn deref(&self) -> &Self::Target { + self.get() + } +} + +impl Debug for InternedSliceRef<'_, T> +where + T: SliceInternable, + T::SliceType: Debug, + T::Header: Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (**self).fmt(f) + } +} + +pub struct InternSliceStorage { + map: OnceLock>, +} + +#[allow( + clippy::new_without_default, + reason = "this a const fn, so it can't be default yet. See " +)] +impl InternSliceStorage { + pub const fn new() -> Self { + Self { map: OnceLock::new() } + } +} + +impl InternSliceStorage { + pub(crate) fn get(&self) -> &InternMap { + self.map.get_or_init(|| { + DashMap::with_capacity_and_hasher( + (64 * 1024) / std::mem::size_of::(), + Default::default(), + ) + }) + } +} + +pub trait SliceInternable: Sized + 'static { + const USE_GC: bool; + type Header: Eq + Hash + Send + Sync; + type SliceType: Eq + Hash + Send + Sync + Copy + 'static; + fn storage() -> &'static InternSliceStorage; +} + +/// Implements `SliceInternable` for a given list of types, making them usable with `InternedSlice`. +#[macro_export] +#[doc(hidden)] +macro_rules! _impl_slice_internable { + ( gc; $tag:ident, $h:ty, $t:ty $(,)? ) => { + #[allow(unreachable_pub)] + pub struct $tag; + impl $crate::SliceInternable for $tag { + const USE_GC: bool = true; + type Header = $h; + type SliceType = $t; + fn storage() -> &'static $crate::InternSliceStorage { + static STORAGE: $crate::InternSliceStorage<$tag> = + $crate::InternSliceStorage::new(); + &STORAGE + } + } + }; +} +pub use crate::_impl_slice_internable as impl_slice_internable; diff --git a/src/tools/rust-analyzer/crates/intern/src/lib.rs b/src/tools/rust-analyzer/crates/intern/src/lib.rs index 398d224c07ad..0c0b12427d21 100644 --- a/src/tools/rust-analyzer/crates/intern/src/lib.rs +++ b/src/tools/rust-analyzer/crates/intern/src/lib.rs @@ -2,219 +2,14 @@ //! //! Eventually this should probably be replaced with salsa-based interning. -use std::{ - borrow::Borrow, - fmt::{self, Debug, Display}, - hash::{BuildHasher, BuildHasherDefault, Hash, Hasher}, - ops::Deref, - sync::OnceLock, -}; - -use dashmap::{DashMap, SharedValue}; -use hashbrown::raw::RawTable; -use rustc_hash::FxHasher; -use triomphe::Arc; - -type InternMap = DashMap, (), BuildHasherDefault>; -type Guard = dashmap::RwLockWriteGuard<'static, RawTable<(Arc, SharedValue<()>)>>; - +mod gc; +mod intern; +mod intern_slice; mod symbol; + +pub use self::gc::{GarbageCollector, GcInternedSliceVisit, GcInternedVisit}; +pub use self::intern::{InternStorage, Internable, Interned, InternedRef, impl_internable}; +pub use self::intern_slice::{ + InternSliceStorage, InternedSlice, InternedSliceRef, SliceInternable, impl_slice_internable, +}; pub use self::symbol::{Symbol, symbols as sym}; - -pub struct Interned { - arc: Arc, -} - -impl Interned { - #[inline] - pub fn new(obj: T) -> Self { - Self::new_generic(obj) - } -} - -impl Interned { - #[inline] - pub fn new_str(s: &str) -> Self { - Self::new_generic(s) - } -} - -impl Interned { - #[inline] - pub fn new_generic(obj: U) -> Self - where - U: Borrow, - Arc: From, - { - let storage = T::storage().get(); - let (mut shard, hash) = Self::select(storage, obj.borrow()); - // Atomically, - // - check if `obj` is already in the map - // - if so, clone its `Arc` and return it - // - if not, box it up, insert it, and return a clone - // This needs to be atomic (locking the shard) to avoid races with other thread, which could - // insert the same object between us looking it up and inserting it. - let bucket = match shard.find_or_find_insert_slot( - hash, - |(other, _)| **other == *obj.borrow(), - |(x, _)| Self::hash(storage, x), - ) { - Ok(bucket) => bucket, - // SAFETY: The slot came from `find_or_find_insert_slot()`, and the table wasn't modified since then. - Err(insert_slot) => unsafe { - shard.insert_in_slot(hash, insert_slot, (Arc::from(obj), SharedValue::new(()))) - }, - }; - // SAFETY: We just retrieved/inserted this bucket. - unsafe { Self { arc: bucket.as_ref().0.clone() } } - } - - #[inline] - fn select(storage: &'static InternMap, obj: &T) -> (Guard, u64) { - let hash = Self::hash(storage, obj); - let shard_idx = storage.determine_shard(hash as usize); - let shard = &storage.shards()[shard_idx]; - (shard.write(), hash) - } - - #[inline] - fn hash(storage: &'static InternMap, obj: &T) -> u64 { - storage.hasher().hash_one(obj) - } -} - -impl Drop for Interned { - #[inline] - fn drop(&mut self) { - // When the last `Ref` is dropped, remove the object from the global map. - if Arc::count(&self.arc) == 2 { - // Only `self` and the global map point to the object. - - self.drop_slow(); - } - } -} - -impl Interned { - #[cold] - fn drop_slow(&mut self) { - let storage = T::storage().get(); - let (mut shard, hash) = Self::select(storage, &self.arc); - - if Arc::count(&self.arc) != 2 { - // Another thread has interned another copy - return; - } - - shard.remove_entry(hash, |(other, _)| **other == *self.arc); - - // Shrink the backing storage if the shard is less than 50% occupied. - if shard.len() * 2 < shard.capacity() { - let len = shard.len(); - shard.shrink_to(len, |(x, _)| Self::hash(storage, x)); - } - } -} - -/// Compares interned `Ref`s using pointer equality. -impl PartialEq for Interned { - // NOTE: No `?Sized` because `ptr_eq` doesn't work right with trait objects. - - #[inline] - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.arc, &other.arc) - } -} - -impl Eq for Interned {} - -impl PartialEq for Interned { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.arc, &other.arc) - } -} - -impl Eq for Interned {} - -impl Hash for Interned { - fn hash(&self, state: &mut H) { - // NOTE: Cast disposes vtable pointer / slice/str length. - state.write_usize(Arc::as_ptr(&self.arc) as *const () as usize) - } -} - -impl AsRef for Interned { - #[inline] - fn as_ref(&self) -> &T { - &self.arc - } -} - -impl Deref for Interned { - type Target = T; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.arc - } -} - -impl Clone for Interned { - fn clone(&self) -> Self { - Self { arc: self.arc.clone() } - } -} - -impl Debug for Interned { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (*self.arc).fmt(f) - } -} - -impl Display for Interned { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (*self.arc).fmt(f) - } -} - -pub struct InternStorage { - map: OnceLock>, -} - -#[allow( - clippy::new_without_default, - reason = "this a const fn, so it can't be default yet. See " -)] -impl InternStorage { - pub const fn new() -> Self { - Self { map: OnceLock::new() } - } -} - -impl InternStorage { - fn get(&self) -> &InternMap { - self.map.get_or_init(DashMap::default) - } -} - -pub trait Internable: Hash + Eq + 'static { - fn storage() -> &'static InternStorage; -} - -/// Implements `Internable` for a given list of types, making them usable with `Interned`. -#[macro_export] -#[doc(hidden)] -macro_rules! _impl_internable { - ( $($t:path),+ $(,)? ) => { $( - impl $crate::Internable for $t { - fn storage() -> &'static $crate::InternStorage { - static STORAGE: $crate::InternStorage<$t> = $crate::InternStorage::new(); - &STORAGE - } - } - )+ }; -} - -pub use crate::_impl_internable as impl_internable; - -impl_internable!(str,); diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 37eb3d4101c6..cc09a1aae7a6 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -109,6 +109,8 @@ define_symbols! { vectorcall_dash_unwind = "vectorcall-unwind", win64_dash_unwind = "win64-unwind", x86_dash_interrupt = "x86-interrupt", + rust_dash_preserve_dash_none = "preserve-none", + _0_u8 = "0_u8", @PLAIN: __ra_fixup, @@ -161,6 +163,7 @@ define_symbols! { cfg_select, char, clone, + trivial_clone, Clone, coerce_unsized, column, @@ -283,6 +286,7 @@ define_symbols! { Into, into_future, into_iter, + into_try_type, IntoFuture, IntoIter, IntoIterator, @@ -296,6 +300,7 @@ define_symbols! { iterator, keyword, lang, + lang_items, le, Left, len, @@ -440,7 +445,6 @@ define_symbols! { rustc_skip_array_during_method_dispatch, rustc_skip_during_method_dispatch, rustc_force_inline, - semitransparent, shl_assign, shl, shr_assign, @@ -524,4 +528,17 @@ define_symbols! { arbitrary_self_types, arbitrary_self_types_pointers, supertrait_item_shadowing, + new_range, + range, + RangeCopy, + RangeFromCopy, + RangeInclusiveCopy, + RangeToInclusiveCopy, + hash, + partial_cmp, + cmp, + CoerceUnsized, + DispatchFromDyn, + define_opaque, + marker, } diff --git a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs index a486219efa20..70a00cf82516 100644 --- a/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs +++ b/src/tools/rust-analyzer/crates/load-cargo/src/lib.rs @@ -2,12 +2,21 @@ //! for incorporating changes. // Note, don't remove any public api from this. This API is consumed by external tools // to run rust-analyzer as a library. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::{any::Any, collections::hash_map::Entry, mem, path::Path, sync}; use crossbeam_channel::{Receiver, unbounded}; -use hir_expand::proc_macro::{ - ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacroLoadResult, - ProcMacrosBuilder, +use hir_expand::{ + db::ExpandDatabase, + proc_macro::{ + ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacroLoadResult, + ProcMacrosBuilder, + }, }; use ide_db::{ ChangeWithProcMacros, FxHashMap, RootDatabase, @@ -15,11 +24,15 @@ use ide_db::{ prime_caches, }; use itertools::Itertools; -use proc_macro_api::{MacroDylib, ProcMacroClient}; +use proc_macro_api::{ + MacroDylib, ProcMacroClient, + bidirectional_protocol::msg::{SubRequest, SubResponse}, +}; use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace}; -use span::Span; +use span::{Span, SpanAnchor, SyntaxContext}; +use tt::{TextRange, TextSize}; use vfs::{ - AbsPath, AbsPathBuf, VfsPath, + AbsPath, AbsPathBuf, FileId, VfsPath, file_set::FileSetConfig, loader::{Handle, LoadingProgress}, }; @@ -29,6 +42,7 @@ pub struct LoadCargoConfig { pub load_out_dirs_from_check: bool, pub with_proc_macro_server: ProcMacroServerChoice, pub prefill_caches: bool, + pub proc_macro_processes: usize, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -97,15 +111,25 @@ pub fn load_workspace_into_db( let proc_macro_server = match &load_config.with_proc_macro_server { ProcMacroServerChoice::Sysroot => ws.find_sysroot_proc_macro_srv().map(|it| { it.and_then(|it| { - ProcMacroClient::spawn(&it, extra_env, ws.toolchain.as_ref()).map_err(Into::into) + ProcMacroClient::spawn( + &it, + extra_env, + ws.toolchain.as_ref(), + load_config.proc_macro_processes, + ) + .map_err(Into::into) }) .map_err(|e| ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str())) }), - ProcMacroServerChoice::Explicit(path) => { - Some(ProcMacroClient::spawn(path, extra_env, ws.toolchain.as_ref()).map_err(|e| { - ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str()) - })) - } + ProcMacroServerChoice::Explicit(path) => Some( + ProcMacroClient::spawn( + path, + extra_env, + ws.toolchain.as_ref(), + load_config.proc_macro_processes, + ) + .map_err(|e| ProcMacroLoadingError::ProcMacroSrvError(e.to_string().into_boxed_str())), + ), ProcMacroServerChoice::None => Some(Err(ProcMacroLoadingError::Disabled)), }; match &proc_macro_server { @@ -516,14 +540,79 @@ struct Expander(proc_macro_api::ProcMacro); impl ProcMacroExpander for Expander { fn expand( &self, - subtree: &tt::TopSubtree, - attrs: Option<&tt::TopSubtree>, + db: &dyn ExpandDatabase, + subtree: &tt::TopSubtree, + attrs: Option<&tt::TopSubtree>, env: &Env, def_site: Span, call_site: Span, mixed_site: Span, current_dir: String, - ) -> Result, ProcMacroExpansionError> { + ) -> Result { + let cb = |req| match req { + SubRequest::LocalFilePath { file_id } => { + let file_id = FileId::from_raw(file_id); + let source_root_id = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); + let name = source_root + .path_for_file(&file_id) + .and_then(|path| path.as_path()) + .map(|path| path.to_string()); + + Ok(SubResponse::LocalFilePathResult { name }) + } + // Not incremental: requires full file text. + SubRequest::SourceText { file_id, ast_id, start, end } => { + let range = resolve_sub_span( + db, + file_id, + ast_id, + TextRange::new(TextSize::from(start), TextSize::from(end)), + ); + let source = db.file_text(range.file_id.file_id(db)).text(db); + let text = source + .get(usize::from(range.range.start())..usize::from(range.range.end())) + .map(ToOwned::to_owned); + + Ok(SubResponse::SourceTextResult { text }) + } + // Not incremental: requires building line index. + SubRequest::LineColumn { file_id, ast_id, offset } => { + let range = + resolve_sub_span(db, file_id, ast_id, TextRange::empty(TextSize::from(offset))); + let source = db.file_text(range.file_id.file_id(db)).text(db); + let line_index = ide_db::line_index::LineIndex::new(source); + let (line, column) = line_index + .try_line_col(range.range.start()) + .map(|lc| (lc.line + 1, lc.col + 1)) + .unwrap_or((1, 1)); + // proc_macro::Span line/column are 1-based + Ok(SubResponse::LineColumnResult { line, column }) + } + SubRequest::FilePath { file_id } => { + let file_id = FileId::from_raw(file_id); + let source_root_id = db.file_source_root(file_id).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); + let name = source_root + .path_for_file(&file_id) + .and_then(|path| path.as_path()) + .map(|path| path.to_string()) + .unwrap_or_default(); + + Ok(SubResponse::FilePathResult { name }) + } + // Not incremental: requires global span resolution. + SubRequest::ByteRange { file_id, ast_id, start, end } => { + let range = resolve_sub_span( + db, + file_id, + ast_id, + TextRange::new(TextSize::from(start), TextSize::from(end)), + ); + + Ok(SubResponse::ByteRangeResult { range: range.range.into() }) + } + }; match self.0.expand( subtree.view(), attrs.map(|attrs| attrs.view()), @@ -532,6 +621,7 @@ impl ProcMacroExpander for Expander { call_site, mixed_site, current_dir, + Some(&cb), ) { Ok(Ok(subtree)) => Ok(subtree), Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err)), @@ -544,6 +634,22 @@ impl ProcMacroExpander for Expander { } } +fn resolve_sub_span( + db: &dyn ExpandDatabase, + file_id: u32, + ast_id: u32, + range: TextRange, +) -> hir_expand::FileRange { + let ast_id = span::ErasedFileAstId::from_raw(ast_id); + let editioned_file_id = span::EditionedFileId::from_raw(file_id); + let span = Span { + range, + anchor: SpanAnchor { file_id: editioned_file_id, ast_id }, + ctx: SyntaxContext::root(editioned_file_id.edition()), + }; + db.resolve_span(span) +} + #[cfg(test)] mod tests { use ide_db::base_db::RootQueryDb; @@ -559,6 +665,7 @@ mod tests { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::None, prefill_caches: false, + proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) = load_workspace_at(path, &cargo_config, &load_cargo_config, &|_| {}).unwrap(); diff --git a/src/tools/rust-analyzer/crates/macros/src/lib.rs b/src/tools/rust-analyzer/crates/macros/src/lib.rs index 3f90ecc8f902..de8c3f2e55f1 100644 --- a/src/tools/rust-analyzer/crates/macros/src/lib.rs +++ b/src/tools/rust-analyzer/crates/macros/src/lib.rs @@ -25,6 +25,9 @@ decl_derive!( /// visited (and its type is not required to implement `TypeVisitable`). type_visitable_derive ); +decl_derive!( + [GenericTypeVisitable] => generic_type_visitable_derive +); fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { if let syn::Data::Union(_) = s.ast().data { @@ -163,6 +166,33 @@ fn has_ignore_attr(attrs: &[syn::Attribute], name: &'static str, meta: &'static ignored } +fn generic_type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + s.add_bounds(synstructure::AddBounds::Fields); + s.bind_with(|_| synstructure::BindStyle::Move); + s.add_impl_generic(parse_quote!(__V: hir_ty::next_solver::interner::WorldExposer)); + let body_visit = s.each(|bind| { + quote! { + ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(#bind, __visitor); + } + }); + + s.bound_impl( + quote!(::rustc_type_ir::GenericTypeVisitable<__V>), + quote! { + fn generic_visit_with( + &self, + __visitor: &mut __V + ) { + match self { #body_visit } + } + }, + ) +} + decl_derive!( [UpmapFromRaFixture] => upmap_from_ra_fixture ); diff --git a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs index ffe3bdd06cfb..603fee73064e 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/benchmark.rs @@ -2,7 +2,6 @@ use intern::Symbol; use rustc_hash::FxHashMap; -use span::Span; use stdx::itertools::Itertools; use syntax::{ AstNode, @@ -55,7 +54,7 @@ fn benchmark_expand_macro_rules() { .map(|(id, tt)| { let res = rules[&id].expand(&db, &tt, |_| (), MacroCallStyle::FnLike, DUMMY); assert!(res.err.is_none()); - res.value.0.0.len() + res.value.0.as_token_trees().len() }) .sum() }; @@ -70,7 +69,7 @@ fn macro_rules_fixtures() -> FxHashMap { .collect() } -fn macro_rules_fixtures_tt() -> FxHashMap> { +fn macro_rules_fixtures_tt() -> FxHashMap { let fixture = bench_fixture::numerous_macro_rules(); let source_file = ast::SourceFile::parse(&fixture, span::Edition::CURRENT).ok().unwrap(); @@ -95,7 +94,7 @@ fn macro_rules_fixtures_tt() -> FxHashMap> { fn invocation_fixtures( db: &dyn salsa::Database, rules: &FxHashMap, -) -> Vec<(String, tt::TopSubtree)> { +) -> Vec<(String, tt::TopSubtree)> { let mut seed = 123456789; let mut res = Vec::new(); @@ -140,7 +139,7 @@ fn invocation_fixtures( } return res; - fn collect_from_op(op: &Op, builder: &mut tt::TopSubtreeBuilder, seed: &mut usize) { + fn collect_from_op(op: &Op, builder: &mut tt::TopSubtreeBuilder, seed: &mut usize) { return match op { Op::Var { kind, .. } => match kind.as_ref() { Some(MetaVarKind::Ident) => builder.push(make_ident("foo")), @@ -226,25 +225,20 @@ fn invocation_fixtures( *seed = usize::wrapping_add(usize::wrapping_mul(*seed, a), c); *seed } - fn make_ident(ident: &str) -> tt::Leaf { + fn make_ident(ident: &str) -> tt::Leaf { tt::Leaf::Ident(tt::Ident { span: DUMMY, sym: Symbol::intern(ident), is_raw: tt::IdentIsRaw::No, }) } - fn make_punct(char: char) -> tt::Leaf { + fn make_punct(char: char) -> tt::Leaf { tt::Leaf::Punct(tt::Punct { span: DUMMY, char, spacing: tt::Spacing::Alone }) } - fn make_literal(lit: &str) -> tt::Leaf { - tt::Leaf::Literal(tt::Literal { - span: DUMMY, - symbol: Symbol::intern(lit), - kind: tt::LitKind::Str, - suffix: None, - }) + fn make_literal(lit: &str) -> tt::Leaf { + tt::Leaf::Literal(tt::Literal::new_no_suffix(lit, DUMMY, tt::LitKind::Str)) } - fn make_subtree(kind: tt::DelimiterKind, builder: &mut tt::TopSubtreeBuilder) { + fn make_subtree(kind: tt::DelimiterKind, builder: &mut tt::TopSubtreeBuilder) { builder.open(kind, DUMMY); builder.close(DUMMY); } diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander.rs b/src/tools/rust-analyzer/crates/mbe/src/expander.rs index 6510fefcb6ad..25e05df7b710 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander.rs @@ -17,11 +17,11 @@ use crate::{ pub(crate) fn expand_rules( db: &dyn salsa::Database, rules: &[crate::Rule], - input: &tt::TopSubtree, + input: &tt::TopSubtree, marker: impl Fn(&mut Span) + Copy, call_style: MacroCallStyle, call_site: Span, -) -> ExpandResult<(tt::TopSubtree, MatchedArmIndex)> { +) -> ExpandResult<(tt::TopSubtree, MatchedArmIndex)> { let mut match_: Option<(matcher::Match<'_>, &crate::Rule, usize)> = None; for (idx, rule) in rules.iter().enumerate() { // Skip any rules that aren't relevant to the call style (fn-like/attr/derive). @@ -128,7 +128,10 @@ enum Fragment<'a> { #[default] Empty, /// token fragments are just copy-pasted into the output - Tokens(tt::TokenTreesView<'a, Span>), + Tokens { + tree: tt::TokenTreesView<'a>, + origin: TokensOrigin, + }, /// Expr ast fragments are surrounded with `()` on transcription to preserve precedence. /// Note that this impl is different from the one currently in `rustc` -- /// `rustc` doesn't translate fragments into token trees at all. @@ -138,7 +141,7 @@ enum Fragment<'a> { /// tricky to handle in the parser, and rustc doesn't handle those either. /// /// The span of the outer delimiters is marked on transcription. - Expr(tt::TokenTreesView<'a, Span>), + Expr(tt::TokenTreesView<'a>), /// There are roughly two types of paths: paths in expression context, where a /// separator `::` between an identifier and its following generic argument list /// is mandatory, and paths in type context, where `::` can be omitted. @@ -148,18 +151,24 @@ enum Fragment<'a> { /// and is trasncribed as an expression-context path, verbatim transcription /// would cause a syntax error. We need to fix it up just before transcribing; /// see `transcriber::fix_up_and_push_path_tt()`. - Path(tt::TokenTreesView<'a, Span>), - TokensOwned(tt::TopSubtree), + Path(tt::TokenTreesView<'a>), + TokensOwned(tt::TopSubtree), } impl Fragment<'_> { fn is_empty(&self) -> bool { match self { Fragment::Empty => true, - Fragment::Tokens(it) => it.len() == 0, + Fragment::Tokens { tree, .. } => tree.len() == 0, Fragment::Expr(it) => it.len() == 0, Fragment::Path(it) => it.len() == 0, - Fragment::TokensOwned(it) => it.0.is_empty(), + Fragment::TokensOwned(_) => false, // A `TopSubtree` is never empty } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum TokensOrigin { + Raw, + Ast, +} diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs index 4da8b309f005..fe01fb1f1063 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/matcher.rs @@ -63,7 +63,6 @@ use std::{rc::Rc, sync::Arc}; use intern::{Symbol, sym}; use smallvec::{SmallVec, smallvec}; -use span::Span; use tt::{ DelimSpan, iter::{TtElement, TtIter}, @@ -71,7 +70,7 @@ use tt::{ use crate::{ ExpandError, ExpandErrorKind, MetaTemplate, ValueResult, - expander::{Binding, Bindings, ExpandResult, Fragment}, + expander::{Binding, Bindings, ExpandResult, Fragment, TokensOrigin}, expect_fragment, parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator}, }; @@ -114,7 +113,7 @@ impl Match<'_> { pub(super) fn match_<'t>( db: &dyn salsa::Database, pattern: &'t MetaTemplate, - input: &'t tt::TopSubtree, + input: &'t tt::TopSubtree, ) -> Match<'t> { let mut res = match_loop(db, pattern, input); res.bound_count = count(res.bindings.bindings()); @@ -339,7 +338,7 @@ struct MatchState<'t> { bindings: BindingsIdx, /// Cached result of meta variable parsing - meta_result: Option<(TtIter<'t, Span>, ExpandResult>>)>, + meta_result: Option<(TtIter<'t>, ExpandResult>>)>, /// Is error occurred in this state, will `poised` to "parent" is_error: bool, @@ -366,8 +365,8 @@ struct MatchState<'t> { #[inline] fn match_loop_inner<'t>( db: &dyn salsa::Database, - src: TtIter<'t, Span>, - stack: &[TtIter<'t, Span>], + src: TtIter<'t>, + stack: &[TtIter<'t>], res: &mut Match<'t>, bindings_builder: &mut BindingsBuilder<'t>, cur_items: &mut SmallVec<[MatchState<'t>; 1]>, @@ -375,7 +374,7 @@ fn match_loop_inner<'t>( next_items: &mut Vec>, eof_items: &mut SmallVec<[MatchState<'t>; 1]>, error_items: &mut SmallVec<[MatchState<'t>; 1]>, - delim_span: tt::DelimSpan, + delim_span: tt::DelimSpan, ) { macro_rules! try_push { ($items: expr, $it:expr) => { @@ -415,8 +414,9 @@ fn match_loop_inner<'t>( } // Check if we need a separator. - if item.sep.is_some() && !item.sep_matched { - let sep = item.sep.as_ref().unwrap(); + if let Some(sep) = &item.sep + && !item.sep_matched + { let mut fork = src.clone(); if expect_separator(&mut fork, sep) { // HACK: here we use `meta_result` to pass `TtIter` back to caller because @@ -518,7 +518,8 @@ fn match_loop_inner<'t>( } OpDelimited::Op(Op::Literal(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Literal(it) if it.symbol == lhs.symbol) { + if matches!(&rhs, tt::Leaf::Literal(it) if it.text_and_suffix == lhs.text_and_suffix) + { item.dot.next(); } else { res.add_err(ExpandError::new( @@ -538,7 +539,7 @@ fn match_loop_inner<'t>( } OpDelimited::Op(Op::Ident(lhs)) => { if let Ok(rhs) = src.clone().expect_leaf() { - if matches!(rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) { + if matches!(&rhs, tt::Leaf::Ident(it) if it.sym == lhs.sym) { item.dot.next(); } else { res.add_err(ExpandError::new( @@ -623,11 +624,11 @@ fn match_loop_inner<'t>( fn match_loop<'t>( db: &dyn salsa::Database, pattern: &'t MetaTemplate, - src: &'t tt::TopSubtree, + src: &'t tt::TopSubtree, ) -> Match<'t> { let span = src.top_subtree().delimiter.delim_span(); let mut src = src.iter(); - let mut stack: SmallVec<[TtIter<'_, Span>; 1]> = SmallVec::new(); + let mut stack: SmallVec<[TtIter<'_>; 1]> = SmallVec::new(); let mut res = Match::default(); let mut error_recover_item = None; @@ -702,7 +703,7 @@ fn match_loop<'t>( || !(bb_items.is_empty() || next_items.is_empty()) || bb_items.len() > 1; if has_leftover_tokens { - res.unmatched_tts += src.remaining().flat_tokens().len(); + res.unmatched_tts += src.remaining().len(); res.add_err(ExpandError::new(span.open, ExpandErrorKind::LeftoverTokens)); if let Some(error_recover_item) = error_recover_item { @@ -774,8 +775,8 @@ fn match_loop<'t>( fn match_meta_var<'t>( db: &dyn salsa::Database, kind: MetaVarKind, - input: &mut TtIter<'t, Span>, - delim_span: DelimSpan, + input: &mut TtIter<'t>, + delim_span: DelimSpan, ) -> ExpandResult> { let fragment = match kind { MetaVarKind::Path => { @@ -842,18 +843,23 @@ fn match_meta_var<'t>( } .err(); let tt_result = input.from_savepoint(savepoint); - return ValueResult { value: Fragment::Tokens(tt_result), err }; + return ValueResult { + value: Fragment::Tokens { tree: tt_result, origin: TokensOrigin::Raw }, + err, + }; } - MetaVarKind::Ty => parser::PrefixEntryPoint::Ty, - MetaVarKind::Pat => parser::PrefixEntryPoint::PatTop, - MetaVarKind::PatParam => parser::PrefixEntryPoint::Pat, - MetaVarKind::Stmt => parser::PrefixEntryPoint::Stmt, - MetaVarKind::Block => parser::PrefixEntryPoint::Block, - MetaVarKind::Meta => parser::PrefixEntryPoint::MetaItem, - MetaVarKind::Item => parser::PrefixEntryPoint::Item, - MetaVarKind::Vis => parser::PrefixEntryPoint::Vis, + MetaVarKind::Ty => (parser::PrefixEntryPoint::Ty, TokensOrigin::Ast), + MetaVarKind::Pat => (parser::PrefixEntryPoint::PatTop, TokensOrigin::Ast), + MetaVarKind::PatParam => (parser::PrefixEntryPoint::Pat, TokensOrigin::Ast), + MetaVarKind::Stmt => (parser::PrefixEntryPoint::Stmt, TokensOrigin::Ast), + MetaVarKind::Block => (parser::PrefixEntryPoint::Block, TokensOrigin::Ast), + MetaVarKind::Meta => (parser::PrefixEntryPoint::MetaItem, TokensOrigin::Ast), + MetaVarKind::Item => (parser::PrefixEntryPoint::Item, TokensOrigin::Ast), + MetaVarKind::Vis => (parser::PrefixEntryPoint::Vis, TokensOrigin::Ast), }; - expect_fragment(db, input, fragment, delim_span).map(Fragment::Tokens) + let (entry_point, origin) = fragment; + expect_fragment(db, input, entry_point, delim_span) + .map(|tree| Fragment::Tokens { tree, origin }) } fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) { @@ -874,10 +880,10 @@ fn collect_vars(collector_fun: &mut impl FnMut(Symbol), pattern: &MetaTemplate) } } impl MetaTemplate { - fn iter_delimited_with(&self, delimiter: tt::Delimiter) -> OpDelimitedIter<'_> { + fn iter_delimited_with(&self, delimiter: tt::Delimiter) -> OpDelimitedIter<'_> { OpDelimitedIter { inner: &self.0, idx: 0, delimited: delimiter } } - fn iter_delimited(&self, span: tt::DelimSpan) -> OpDelimitedIter<'_> { + fn iter_delimited(&self, span: tt::DelimSpan) -> OpDelimitedIter<'_> { OpDelimitedIter { inner: &self.0, idx: 0, @@ -896,7 +902,7 @@ enum OpDelimited<'a> { #[derive(Debug, Clone, Copy)] struct OpDelimitedIter<'a> { inner: &'a [Op], - delimited: tt::Delimiter, + delimited: tt::Delimiter, idx: usize, } @@ -940,7 +946,7 @@ impl<'a> Iterator for OpDelimitedIter<'a> { } } -fn expect_separator(iter: &mut TtIter<'_, S>, separator: &Separator) -> bool { +fn expect_separator(iter: &mut TtIter<'_>, separator: &Separator) -> bool { let mut fork = iter.clone(); let ok = match separator { Separator::Ident(lhs) => match fork.expect_ident_or_underscore() { @@ -949,8 +955,8 @@ fn expect_separator(iter: &mut TtIter<'_, S>, separator: &Separator) -> }, Separator::Literal(lhs) => match fork.expect_literal() { Ok(rhs) => match rhs { - tt::Leaf::Literal(rhs) => rhs.symbol == lhs.symbol, - tt::Leaf::Ident(rhs) => rhs.sym == lhs.symbol, + tt::Leaf::Literal(rhs) => rhs.text_and_suffix == lhs.text_and_suffix, + tt::Leaf::Ident(rhs) => rhs.sym == lhs.text_and_suffix, tt::Leaf::Punct(_) => false, }, Err(_) => false, @@ -974,7 +980,7 @@ fn expect_separator(iter: &mut TtIter<'_, S>, separator: &Separator) -> ok } -fn expect_tt(iter: &mut TtIter<'_, S>) -> Result<(), ()> { +fn expect_tt(iter: &mut TtIter<'_>) -> Result<(), ()> { if let Some(TtElement::Leaf(tt::Leaf::Punct(punct))) = iter.peek() { if punct.char == '\'' { expect_lifetime(iter)?; @@ -987,7 +993,7 @@ fn expect_tt(iter: &mut TtIter<'_, S>) -> Result<(), ()> { Ok(()) } -fn expect_lifetime<'a, S: Copy>(iter: &mut TtIter<'a, S>) -> Result<&'a tt::Ident, ()> { +fn expect_lifetime<'a>(iter: &mut TtIter<'a>) -> Result { let punct = iter.expect_single_punct()?; if punct.char != '\'' { return Err(()); @@ -995,8 +1001,8 @@ fn expect_lifetime<'a, S: Copy>(iter: &mut TtIter<'a, S>) -> Result<&'a tt::Iden iter.expect_ident_or_underscore() } -fn eat_char(iter: &mut TtIter<'_, S>, c: char) { - if matches!(iter.peek(), Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char, .. }))) if *char == c) +fn eat_char(iter: &mut TtIter<'_>, c: char) { + if matches!(iter.peek(), Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char, .. }))) if char == c) { iter.next().expect("already peeked"); } diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index 3e4ab8bdc1d8..e8e7928c263f 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -3,8 +3,10 @@ use intern::{Symbol, sym}; use span::{Edition, Span}; +use stdx::itertools::Itertools; use tt::{Delimiter, TopSubtreeBuilder, iter::TtElement}; +use super::TokensOrigin; use crate::{ ExpandError, ExpandErrorKind, ExpandResult, MetaTemplate, expander::{Binding, Bindings, Fragment}, @@ -124,7 +126,7 @@ pub(super) fn transcribe( bindings: &Bindings<'_>, marker: impl Fn(&mut Span) + Copy, call_site: Span, -) -> ExpandResult> { +) -> ExpandResult { let mut ctx = ExpandCtx { bindings, nesting: Vec::new(), call_site }; let mut builder = tt::TopSubtreeBuilder::new(tt::Delimiter::invisible_spanned(ctx.call_site)); expand_subtree(&mut ctx, template, &mut builder, marker).map(|()| builder.build()) @@ -151,8 +153,8 @@ struct ExpandCtx<'a> { fn expand_subtree_with_delimiter( ctx: &mut ExpandCtx<'_>, template: &MetaTemplate, - builder: &mut tt::TopSubtreeBuilder, - delimiter: Option>, + builder: &mut tt::TopSubtreeBuilder, + delimiter: Option, marker: impl Fn(&mut Span) + Copy, ) -> ExpandResult<()> { let delimiter = delimiter.unwrap_or_else(|| tt::Delimiter::invisible_spanned(ctx.call_site)); @@ -165,7 +167,7 @@ fn expand_subtree_with_delimiter( fn expand_subtree( ctx: &mut ExpandCtx<'_>, template: &MetaTemplate, - builder: &mut tt::TopSubtreeBuilder, + builder: &mut tt::TopSubtreeBuilder, marker: impl Fn(&mut Span) + Copy, ) -> ExpandResult<()> { let mut err = None; @@ -220,10 +222,10 @@ fn expand_subtree( let index = ctx.nesting.get(ctx.nesting.len() - 1 - depth).map_or(0, |nest| nest.idx); builder.push(tt::Leaf::Literal(tt::Literal { - symbol: Symbol::integer(index), + text_and_suffix: Symbol::integer(index), span: ctx.call_site, kind: tt::LitKind::Integer, - suffix: None, + suffix_len: 0, })); } Op::Len { depth } => { @@ -232,10 +234,10 @@ fn expand_subtree( 0 }); builder.push(tt::Leaf::Literal(tt::Literal { - symbol: Symbol::integer(length), + text_and_suffix: Symbol::integer(length), span: ctx.call_site, kind: tt::LitKind::Integer, - suffix: None, + suffix_len: 0, })); } Op::Count { name, depth } => { @@ -276,9 +278,9 @@ fn expand_subtree( let res = count(binding, 0, depth.unwrap_or(0)); builder.push(tt::Leaf::Literal(tt::Literal { - symbol: Symbol::integer(res), + text_and_suffix: Symbol::integer(res), span: ctx.call_site, - suffix: None, + suffix_len: 0, kind: tt::LitKind::Integer, })); } @@ -292,7 +294,7 @@ fn expand_subtree( ConcatMetaVarExprElem::Literal(lit) => { // FIXME: This isn't really correct wrt. escaping, but that's what rustc does and anyway // escaping is used most of the times for characters that are invalid in identifiers. - concatenated.push_str(lit.symbol.as_str()) + concatenated.push_str(lit.text()) } ConcatMetaVarExprElem::Var(var) => { // Handling of repetitions in `${concat}` isn't fleshed out in rustc, so we currently @@ -313,7 +315,7 @@ fn expand_subtree( } }; let values = match &var_value { - Fragment::Tokens(tokens) => { + Fragment::Tokens { tree: tokens, .. } => { let mut iter = tokens.iter(); (iter.next(), iter.next()) } @@ -323,13 +325,11 @@ fn expand_subtree( } _ => (None, None), }; - let value = match values { + let value = match &values { (Some(TtElement::Leaf(tt::Leaf::Ident(ident))), None) => { ident.sym.as_str() } - (Some(TtElement::Leaf(tt::Leaf::Literal(lit))), None) => { - lit.symbol.as_str() - } + (Some(TtElement::Leaf(tt::Leaf::Literal(lit))), None) => lit.text(), _ => { if err.is_none() { err = Some(ExpandError::binding_error( @@ -381,7 +381,7 @@ fn expand_var( ctx: &mut ExpandCtx<'_>, v: &Symbol, id: Span, - builder: &mut tt::TopSubtreeBuilder, + builder: &mut tt::TopSubtreeBuilder, marker: impl Fn(&mut Span) + Copy, ) -> ExpandResult<()> { // We already handle $crate case in mbe parser @@ -393,7 +393,13 @@ fn expand_var( // rustc spacing is not like ours. Ours is like proc macros', it dictates how puncts will actually be joined. // rustc uses them mostly for pretty printing. So we have to deviate a bit from what rustc does here. // Basically, a metavariable can never be joined with whatever after it. - Fragment::Tokens(tt) => builder.extend_with_tt_alone(tt.strip_invisible()), + Fragment::Tokens { tree, origin } => { + let view = match origin { + TokensOrigin::Raw => tree.strip_invisible(), + TokensOrigin::Ast => tree, + }; + builder.extend_with_tt_alone(view); + } Fragment::TokensOwned(tt) => { builder.extend_with_tt_alone(tt.view().strip_invisible()) } @@ -405,15 +411,15 @@ fn expand_var( // Check if this is a simple negative literal (MINUS + LITERAL) // that should not be wrapped in parentheses let is_negative_literal = matches!( - sub.flat_tokens(), - [ - tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '-', .. })), - tt::TokenTree::Leaf(tt::Leaf::Literal(_)) - ] + sub.iter().collect_array(), + Some([ + tt::TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char: '-', .. })), + tt::TtElement::Leaf(tt::Leaf::Literal(_)) + ]) ); let wrap_in_parens = !is_negative_literal - && !matches!(sub.flat_tokens(), [tt::TokenTree::Leaf(_)]) + && !matches!(sub.iter().collect_array(), Some([tt::TtElement::Leaf(_)])) && sub.try_into_subtree().is_none_or(|it| { it.top_subtree().delimiter.kind == tt::DelimiterKind::Invisible }); @@ -459,7 +465,7 @@ fn expand_repeat( template: &MetaTemplate, kind: RepeatKind, separator: Option<&Separator>, - builder: &mut tt::TopSubtreeBuilder, + builder: &mut tt::TopSubtreeBuilder, marker: impl Fn(&mut Span) + Copy, ) -> ExpandResult<()> { ctx.nesting.push(NestingState { idx: 0, at_end: false, hit: false }); @@ -539,8 +545,8 @@ fn expand_repeat( /// we need this fixup. fn fix_up_and_push_path_tt( ctx: &ExpandCtx<'_>, - builder: &mut tt::TopSubtreeBuilder, - subtree: tt::TokenTreesView<'_, Span>, + builder: &mut tt::TopSubtreeBuilder, + subtree: tt::TokenTreesView<'_>, ) { let mut prev_was_ident = false; // Note that we only need to fix up the top-level `TokenTree`s because the @@ -553,8 +559,8 @@ fn fix_up_and_push_path_tt( // argument list and thus needs `::` between it and `FnOnce`. However in // today's Rust this type of path *semantically* cannot appear as a // top-level expression-context path, so we can safely ignore it. - if let [tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '<', .. }))] = - tt.flat_tokens() + if let Some([tt::TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char: '<', .. }))]) = + tt.iter().collect_array() { builder.extend([ tt::Leaf::Punct(tt::Punct { @@ -570,7 +576,8 @@ fn fix_up_and_push_path_tt( ]); } } - prev_was_ident = matches!(tt.flat_tokens(), [tt::TokenTree::Leaf(tt::Leaf::Ident(_))]); + prev_was_ident = + matches!(tt.iter().collect_array(), Some([tt::TtElement::Leaf(tt::Leaf::Ident(_))])); builder.extend_with_tt(tt); } } diff --git a/src/tools/rust-analyzer/crates/mbe/src/lib.rs b/src/tools/rust-analyzer/crates/mbe/src/lib.rs index 1193c4290c4c..936cf178f015 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/lib.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/lib.rs @@ -152,7 +152,7 @@ impl DeclarativeMacro { /// The old, `macro_rules! m {}` flavor. pub fn parse_macro_rules( - tt: &tt::TopSubtree, + tt: &tt::TopSubtree, ctx_edition: impl Copy + Fn(SyntaxContext) -> Edition, ) -> DeclarativeMacro { // Note: this parsing can be implemented using mbe machinery itself, by @@ -191,8 +191,8 @@ impl DeclarativeMacro { /// The new, unstable `macro m {}` flavor. pub fn parse_macro2( - args: Option<&tt::TopSubtree>, - body: &tt::TopSubtree, + args: Option<&tt::TopSubtree>, + body: &tt::TopSubtree, ctx_edition: impl Copy + Fn(SyntaxContext) -> Edition, ) -> DeclarativeMacro { let mut rules = Vec::new(); @@ -276,11 +276,11 @@ impl DeclarativeMacro { pub fn expand( &self, db: &dyn salsa::Database, - tt: &tt::TopSubtree, + tt: &tt::TopSubtree, marker: impl Fn(&mut Span) + Copy, call_style: MacroCallStyle, call_site: Span, - ) -> ExpandResult<(tt::TopSubtree, MatchedArmIndex)> { + ) -> ExpandResult<(tt::TopSubtree, MatchedArmIndex)> { expander::expand_rules(db, &self.rules, tt, marker, call_style, call_site) } } @@ -288,7 +288,7 @@ impl DeclarativeMacro { impl Rule { fn parse( edition: impl Copy + Fn(SyntaxContext) -> Edition, - src: &mut TtIter<'_, Span>, + src: &mut TtIter<'_>, ) -> Result { // Parse an optional `attr()` or `derive()` prefix before the LHS pattern. let style = parser::parse_rule_style(src)?; @@ -391,10 +391,10 @@ impl From> for ValueResult { pub fn expect_fragment<'t>( db: &dyn salsa::Database, - tt_iter: &mut TtIter<'t, Span>, + tt_iter: &mut TtIter<'t>, entry_point: ::parser::PrefixEntryPoint, - delim_span: DelimSpan, -) -> ExpandResult> { + delim_span: DelimSpan, +) -> ExpandResult> { use ::parser; let buffer = tt_iter.remaining(); let parser_input = to_parser_input(buffer, &mut |ctx| ctx.edition(db)); diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs index e1cb98abae77..796ee62d48e3 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs @@ -13,7 +13,7 @@ use tt::{ use crate::{MacroCallStyle, ParseError}; -pub(crate) fn parse_rule_style(src: &mut TtIter<'_, Span>) -> Result { +pub(crate) fn parse_rule_style(src: &mut TtIter<'_>) -> Result { // Skip an optional `unsafe`. This is only actually allowed for `attr` // rules, but we'll let rustc worry about that. if let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = src.peek() @@ -59,14 +59,14 @@ pub(crate) struct MetaTemplate(pub(crate) Box<[Op]>); impl MetaTemplate { pub(crate) fn parse_pattern( edition: impl Copy + Fn(SyntaxContext) -> Edition, - pattern: TtIter<'_, Span>, + pattern: TtIter<'_>, ) -> Result { MetaTemplate::parse(edition, pattern, Mode::Pattern) } pub(crate) fn parse_template( edition: impl Copy + Fn(SyntaxContext) -> Edition, - template: TtIter<'_, Span>, + template: TtIter<'_>, ) -> Result { MetaTemplate::parse(edition, template, Mode::Template) } @@ -77,7 +77,7 @@ impl MetaTemplate { fn parse( edition: impl Copy + Fn(SyntaxContext) -> Edition, - mut src: TtIter<'_, Span>, + mut src: TtIter<'_>, mode: Mode, ) -> Result { let mut res = Vec::new(); @@ -123,23 +123,23 @@ pub(crate) enum Op { }, Subtree { tokens: MetaTemplate, - delimiter: tt::Delimiter, + delimiter: tt::Delimiter, }, - Literal(tt::Literal), - Punct(Box, MAX_GLUED_PUNCT_LEN>>), - Ident(tt::Ident), + Literal(tt::Literal), + Punct(Box>), + Ident(tt::Ident), } #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum ConcatMetaVarExprElem { /// There is NO preceding dollar sign, which means that this identifier should be interpreted /// as a literal. - Ident(tt::Ident), + Ident(tt::Ident), /// There is a preceding dollar sign, which means that this identifier should be expanded /// and interpreted as a variable. - Var(tt::Ident), + Var(tt::Ident), /// For example, a number or a string. - Literal(tt::Literal), + Literal(tt::Literal), } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -179,10 +179,10 @@ pub(crate) enum MetaVarKind { #[derive(Clone, Debug, Eq)] pub(crate) enum Separator { - Literal(tt::Literal), - Ident(tt::Ident), - Puncts(ArrayVec, MAX_GLUED_PUNCT_LEN>), - Lifetime(tt::Punct, tt::Ident), + Literal(tt::Literal), + Ident(tt::Ident), + Puncts(ArrayVec), + Lifetime(tt::Punct, tt::Ident), } // Note that when we compare a Separator, we just care about its textual value. @@ -192,7 +192,7 @@ impl PartialEq for Separator { match (self, other) { (Ident(a), Ident(b)) => a.sym == b.sym, - (Literal(a), Literal(b)) => a.symbol == b.symbol, + (Literal(a), Literal(b)) => a.text_and_suffix == b.text_and_suffix, (Puncts(a), Puncts(b)) if a.len() == b.len() => { let a_iter = a.iter().map(|a| a.char); let b_iter = b.iter().map(|b| b.char); @@ -212,8 +212,8 @@ enum Mode { fn next_op( edition: impl Copy + Fn(SyntaxContext) -> Edition, - first_peeked: TtElement<'_, Span>, - src: &mut TtIter<'_, Span>, + first_peeked: TtElement<'_>, + src: &mut TtIter<'_>, mode: Mode, ) -> Result { let res = match first_peeked { @@ -224,7 +224,7 @@ fn next_op( None => { return Ok(Op::Punct({ let mut res = ArrayVec::new(); - res.push(*p); + res.push(p); Box::new(res) })); } @@ -268,9 +268,9 @@ fn next_op( let id = ident.span; Op::Var { name, kind, id } } - tt::Leaf::Literal(lit) if is_boolean_literal(lit) => { + tt::Leaf::Literal(lit) if is_boolean_literal(&lit) => { let kind = eat_fragment_kind(edition, src, mode)?; - let name = lit.symbol.clone(); + let name = lit.text_and_suffix.clone(); let id = lit.span; Op::Var { name, kind, id } } @@ -282,7 +282,7 @@ fn next_op( } Mode::Template => Op::Punct({ let mut res = ArrayVec::new(); - res.push(*punct); + res.push(punct); Box::new(res) }), }, @@ -320,7 +320,7 @@ fn next_op( fn eat_fragment_kind( edition: impl Copy + Fn(SyntaxContext) -> Edition, - src: &mut TtIter<'_, Span>, + src: &mut TtIter<'_>, mode: Mode, ) -> Result, ParseError> { if let Mode::Pattern = mode { @@ -363,11 +363,11 @@ fn eat_fragment_kind( Ok(None) } -fn is_boolean_literal(lit: &tt::Literal) -> bool { - matches!(lit.symbol.as_str(), "true" | "false") +fn is_boolean_literal(lit: &tt::Literal) -> bool { + lit.text_and_suffix == sym::true_ || lit.text_and_suffix == sym::false_ } -fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option, RepeatKind), ParseError> { +fn parse_repeat(src: &mut TtIter<'_>) -> Result<(Option, RepeatKind), ParseError> { let mut separator = Separator::Puncts(ArrayVec::new()); for tt in src { let tt = match tt { @@ -400,7 +400,7 @@ fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option, Repeat '?' => RepeatKind::ZeroOrOne, _ => match &mut separator { Separator::Puncts(puncts) if puncts.len() < 3 => { - puncts.push(*punct); + puncts.push(punct); continue; } _ => return Err(ParseError::InvalidRepeat), @@ -413,7 +413,7 @@ fn parse_repeat(src: &mut TtIter<'_, Span>) -> Result<(Option, Repeat Err(ParseError::InvalidRepeat) } -fn parse_metavar_expr(src: &mut TtIter<'_, Span>) -> Result { +fn parse_metavar_expr(src: &mut TtIter<'_>) -> Result { let func = src.expect_ident()?; let (args, mut args_iter) = src.expect_subtree()?; @@ -475,20 +475,21 @@ fn parse_metavar_expr(src: &mut TtIter<'_, Span>) -> Result { Ok(op) } -fn parse_depth(src: &mut TtIter<'_, Span>) -> Result { +fn parse_depth(src: &mut TtIter<'_>) -> Result { if src.is_empty() { Ok(0) - } else if let tt::Leaf::Literal(tt::Literal { symbol: text, suffix: None, .. }) = - src.expect_literal()? + } else if let tt::Leaf::Literal(lit) = src.expect_literal()? + && let (text, suffix) = lit.text_and_suffix() + && suffix.is_empty() { // Suffixes are not allowed. - text.as_str().parse().map_err(|_| ()) + text.parse().map_err(|_| ()) } else { Err(()) } } -fn try_eat_comma(src: &mut TtIter<'_, Span>) -> bool { +fn try_eat_comma(src: &mut TtIter<'_>) -> bool { if let Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char: ',', .. }))) = src.peek() { let _ = src.next(); return true; @@ -496,7 +497,7 @@ fn try_eat_comma(src: &mut TtIter<'_, Span>) -> bool { false } -fn try_eat_dollar(src: &mut TtIter<'_, Span>) -> bool { +fn try_eat_dollar(src: &mut TtIter<'_>) -> bool { if let Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char: '$', .. }))) = src.peek() { let _ = src.next(); return true; diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar.rs b/src/tools/rust-analyzer/crates/parser/src/grammar.rs index bf8430294110..e481bbe9bc4a 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar.rs @@ -6,7 +6,7 @@ //! each submodule starts with `use super::*` import and exports //! "public" productions via `pub(super)`. //! -//! See docs for [`Parser`](super::parser::Parser) to learn about API, +//! See docs for [`Parser`] to learn about API, //! available to the grammar, and see docs for [`Event`](super::event::Event) //! to learn how this actually manages to produce parse trees. //! diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs index ccb556b2ccac..c0cf43a87bf7 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/attributes.rs @@ -24,15 +24,11 @@ fn attr(p: &mut Parser<'_>, inner: bool) { p.bump(T![!]); } - if p.eat(T!['[']) { + if p.expect(T!['[']) { meta(p); - - if !p.eat(T![']']) { - p.error("expected `]`"); - } - } else { - p.error("expected `[`"); + p.expect(T![']']); } + attr.complete(p, ATTR); } @@ -74,7 +70,7 @@ pub(super) fn meta(p: &mut Parser<'_>) { paths::attr_path(p); match p.current() { - T![=] => { + T![=] if !p.at(T![=>]) && !p.at(T![==]) => { p.bump(T![=]); if expressions::expr(p).is_none() { p.error("expected expression"); diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs index ab1830930854..b75474ee2b86 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/expressions/atom.rs @@ -278,14 +278,20 @@ fn builtin_expr(p: &mut Parser<'_>) -> Option { } Some(m.complete(p, OFFSET_OF_EXPR)) } else if p.eat_contextual_kw(T![format_args]) { + // test format_args_named_arg_keyword + // fn main() { + // builtin#format_args("{type}", type=1); + // } p.expect(T!['(']); expr(p); if p.eat(T![,]) { while !p.at(EOF) && !p.at(T![')']) { let m = p.start(); - if p.at(IDENT) && p.nth_at(1, T![=]) && !p.nth_at(2, T![=]) { - name(p); + if p.current().is_any_identifier() && p.nth_at(1, T![=]) && !p.nth_at(2, T![=]) { + let m = p.start(); + p.bump_any(); p.bump(T![=]); + m.complete(p, FORMAT_ARGS_ARG_NAME); } if expr(p).is_none() { m.abandon(p); @@ -970,11 +976,17 @@ fn break_expr(p: &mut Parser<'_>, r: Restrictions) -> CompletedMarker { // test try_block_expr // fn foo() { // let _ = try {}; +// let _ = try bikeshed T {}; // } fn try_block_expr(p: &mut Parser<'_>, m: Option) -> CompletedMarker { assert!(p.at(T![try])); let m = m.unwrap_or_else(|| p.start()); + let try_modifier = p.start(); p.bump(T![try]); + if p.eat_contextual_kw(T![bikeshed]) { + type_(p); + } + try_modifier.complete(p, TRY_BLOCK_MODIFIER); if p.at(T!['{']) { stmt_list(p); } else { diff --git a/src/tools/rust-analyzer/crates/parser/src/input.rs b/src/tools/rust-analyzer/crates/parser/src/input.rs index 57eeb431cdc2..42e8a400edd1 100644 --- a/src/tools/rust-analyzer/crates/parser/src/input.rs +++ b/src/tools/rust-analyzer/crates/parser/src/input.rs @@ -97,7 +97,7 @@ impl Input { let b_idx = n % (bits::BITS as usize); (idx, b_idx) } - fn len(&self) -> usize { + pub fn len(&self) -> usize { self.kind.len() } } diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index 7c78ba8faf5f..d7eec6cde8c0 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -150,7 +150,12 @@ struct Converter<'a> { impl<'a> Converter<'a> { fn new(edition: Edition, text: &'a str) -> Self { Self { - res: LexedStr { text, kind: Vec::new(), start: Vec::new(), error: Vec::new() }, + res: LexedStr { + text, + kind: Vec::with_capacity(text.len() / 3), + start: Vec::with_capacity(text.len() / 3), + error: Vec::new(), + }, offset: 0, edition, } diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs index b15bf0cd0105..4478bf4e3733 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lib.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs @@ -24,6 +24,8 @@ #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; #[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; +#[cfg(feature = "in-rust-tree")] extern crate rustc_lexer; mod event; diff --git a/src/tools/rust-analyzer/crates/parser/src/parser.rs b/src/tools/rust-analyzer/crates/parser/src/parser.rs index c41bd593c6a2..4557078de991 100644 --- a/src/tools/rust-analyzer/crates/parser/src/parser.rs +++ b/src/tools/rust-analyzer/crates/parser/src/parser.rs @@ -32,7 +32,7 @@ const PARSER_STEP_LIMIT: usize = if cfg!(debug_assertions) { 150_000 } else { 15 impl<'t> Parser<'t> { pub(super) fn new(inp: &'t Input) -> Parser<'t> { - Parser { inp, pos: 0, events: Vec::new(), steps: Cell::new(0) } + Parser { inp, pos: 0, events: Vec::with_capacity(2 * inp.len()), steps: Cell::new(0) } } pub(crate) fn finish(self) -> Vec { diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index 6a38044e3b57..a2295e449550 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -114,6 +114,7 @@ pub enum SyntaxKind { ATT_SYNTAX_KW, AUTO_KW, AWAIT_KW, + BIKESHED_KW, BUILTIN_KW, CLOBBER_ABI_KW, DEFAULT_KW, @@ -201,6 +202,7 @@ pub enum SyntaxKind { FN, FN_PTR_TYPE, FORMAT_ARGS_ARG, + FORMAT_ARGS_ARG_NAME, FORMAT_ARGS_EXPR, FOR_BINDER, FOR_EXPR, @@ -284,6 +286,7 @@ pub enum SyntaxKind { STRUCT, TOKEN_TREE, TRAIT, + TRY_BLOCK_MODIFIER, TRY_EXPR, TUPLE_EXPR, TUPLE_FIELD, @@ -373,6 +376,7 @@ impl SyntaxKind { | FN | FN_PTR_TYPE | FORMAT_ARGS_ARG + | FORMAT_ARGS_ARG_NAME | FORMAT_ARGS_EXPR | FOR_BINDER | FOR_EXPR @@ -456,6 +460,7 @@ impl SyntaxKind { | STRUCT | TOKEN_TREE | TRAIT + | TRY_BLOCK_MODIFIER | TRY_EXPR | TUPLE_EXPR | TUPLE_FIELD @@ -594,6 +599,7 @@ impl SyntaxKind { ASM_KW => "asm", ATT_SYNTAX_KW => "att_syntax", AUTO_KW => "auto", + BIKESHED_KW => "bikeshed", BUILTIN_KW => "builtin", CLOBBER_ABI_KW => "clobber_abi", DEFAULT_KW => "default", @@ -696,6 +702,7 @@ impl SyntaxKind { ASM_KW => true, ATT_SYNTAX_KW => true, AUTO_KW => true, + BIKESHED_KW => true, BUILTIN_KW => true, CLOBBER_ABI_KW => true, DEFAULT_KW => true, @@ -786,6 +793,7 @@ impl SyntaxKind { ASM_KW => true, ATT_SYNTAX_KW => true, AUTO_KW => true, + BIKESHED_KW => true, BUILTIN_KW => true, CLOBBER_ABI_KW => true, DEFAULT_KW => true, @@ -939,6 +947,7 @@ impl SyntaxKind { "asm" => ASM_KW, "att_syntax" => ATT_SYNTAX_KW, "auto" => AUTO_KW, + "bikeshed" => BIKESHED_KW, "builtin" => BUILTIN_KW, "clobber_abi" => CLOBBER_ABI_KW, "default" => DEFAULT_KW, @@ -1005,6 +1014,7 @@ impl SyntaxKind { Some(tok) } } +#[doc = r" `T![]`"] #[macro_export] macro_rules ! T_ { [$] => { $ crate :: SyntaxKind :: DOLLAR }; @@ -1109,6 +1119,7 @@ macro_rules ! T_ { [asm] => { $ crate :: SyntaxKind :: ASM_KW }; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW }; [auto] => { $ crate :: SyntaxKind :: AUTO_KW }; + [bikeshed] => { $ crate :: SyntaxKind :: BIKESHED_KW }; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW }; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW }; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW }; diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index 7b0d32d9d1e4..9f919f6cea42 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs @@ -265,6 +265,10 @@ mod ok { #[test] fn for_type() { run_and_expect_no_errors("test_data/parser/inline/ok/for_type.rs"); } #[test] + fn format_args_named_arg_keyword() { + run_and_expect_no_errors("test_data/parser/inline/ok/format_args_named_arg_keyword.rs"); + } + #[test] fn frontmatter() { run_and_expect_no_errors("test_data/parser/inline/ok/frontmatter.rs"); } #[test] fn full_range_expr() { diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast index 7ee1ecfbb159..60cc690f7c98 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0002_duplicate_shebang.rast @@ -28,7 +28,7 @@ SOURCE_FILE NAME_REF IDENT "rusti" WHITESPACE "\n" -error 23: expected `[` +error 23: expected L_BRACK error 23: expected an item error 27: expected one of `*`, `::`, `{`, `self`, `super` or an identifier error 28: expected SEMICOLON diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0005_attribute_recover.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0005_attribute_recover.rast index 6ff072e207cd..77b4d06321d5 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0005_attribute_recover.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0005_attribute_recover.rast @@ -58,5 +58,5 @@ SOURCE_FILE R_CURLY "}" WHITESPACE "\n" error 53: expected R_PAREN -error 53: expected `]` +error 53: expected R_BRACK error 53: expected an item diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast index 327bf94a49e6..b657e9834156 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0032_match_arms_inner_attrs.rast @@ -192,14 +192,14 @@ SOURCE_FILE WHITESPACE "\n" R_CURLY "}" WHITESPACE "\n" -error 52: expected `[` +error 52: expected L_BRACK error 52: expected pattern error 53: expected FAT_ARROW error 78: expected `,` -error 161: expected `[` +error 161: expected L_BRACK error 161: expected pattern error 162: expected FAT_ARROW -error 232: expected `[` +error 232: expected L_BRACK error 232: expected pattern error 233: expected FAT_ARROW error 250: expected `,` diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast index d6d2e75cca67..9e4e9dbf9d25 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0042_weird_blocks.rast @@ -45,7 +45,8 @@ SOURCE_FILE WHITESPACE " " EXPR_STMT BLOCK_EXPR - TRY_KW "try" + TRY_BLOCK_MODIFIER + TRY_KW "try" WHITESPACE " " LITERAL INT_NUMBER "92" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rast index 19a84ac54096..78c3bee4c88a 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/builtin_expr.rast @@ -44,10 +44,10 @@ SOURCE_FILE COMMA "," WHITESPACE " " FORMAT_ARGS_ARG - NAME + FORMAT_ARGS_ARG_NAME IDENT "a" - WHITESPACE " " - EQ "=" + WHITESPACE " " + EQ "=" WHITESPACE " " BIN_EXPR LITERAL diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/format_args_named_arg_keyword.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/format_args_named_arg_keyword.rast new file mode 100644 index 000000000000..03bc2ecf7c21 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/format_args_named_arg_keyword.rast @@ -0,0 +1,35 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "main" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + WHITESPACE "\n " + EXPR_STMT + FORMAT_ARGS_EXPR + BUILTIN_KW "builtin" + POUND "#" + FORMAT_ARGS_KW "format_args" + L_PAREN "(" + LITERAL + STRING "\"{type}\"" + COMMA "," + WHITESPACE " " + FORMAT_ARGS_ARG + FORMAT_ARGS_ARG_NAME + TYPE_KW "type" + EQ "=" + LITERAL + INT_NUMBER "1" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n" + R_CURLY "}" + WHITESPACE "\n" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/format_args_named_arg_keyword.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/format_args_named_arg_keyword.rs new file mode 100644 index 000000000000..7af45894ed67 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/format_args_named_arg_keyword.rs @@ -0,0 +1,3 @@ +fn main() { + builtin#format_args("{type}", type=1); +} diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rast index aec8fbf4775c..472ce711c5fe 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rast @@ -21,7 +21,42 @@ SOURCE_FILE EQ "=" WHITESPACE " " BLOCK_EXPR - TRY_KW "try" + TRY_BLOCK_MODIFIER + TRY_KW "try" + WHITESPACE " " + STMT_LIST + L_CURLY "{" + R_CURLY "}" + SEMICOLON ";" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + WILDCARD_PAT + UNDERSCORE "_" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BLOCK_EXPR + TRY_BLOCK_MODIFIER + TRY_KW "try" + WHITESPACE " " + BIKESHED_KW "bikeshed" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + GENERIC_ARG_LIST + L_ANGLE "<" + TYPE_ARG + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "U" + R_ANGLE ">" WHITESPACE " " STMT_LIST L_CURLY "{" diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rs index 0f1b41eb64b4..719980473c3b 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/try_block_expr.rs @@ -1,3 +1,4 @@ fn foo() { let _ = try {}; + let _ = try bikeshed T {}; } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml index 18a2408c4035..a135a469e87e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml @@ -31,9 +31,12 @@ span = { path = "../span", version = "0.0.0", default-features = false} intern.workspace = true postcard.workspace = true semver.workspace = true +rayon.workspace = true [features] sysroot-abi = ["proc-macro-srv", "proc-macro-srv/sysroot-abi"] +default = [] +in-rust-tree = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs new file mode 100644 index 000000000000..ba59cb219b9a --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -0,0 +1,227 @@ +//! Bidirectional protocol methods + +use std::{ + io::{self, BufRead, Write}, + panic::{AssertUnwindSafe, catch_unwind}, + sync::Arc, +}; + +use paths::AbsPath; +use span::Span; + +use crate::{ + ProcMacro, ProcMacroKind, ServerError, + bidirectional_protocol::msg::{ + BidirectionalMessage, ExpandMacro, ExpandMacroData, ExpnGlobals, Request, Response, + SubRequest, SubResponse, + }, + legacy_protocol::{ + SpanMode, + msg::{ + FlatTree, ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map, + serialize_span_data_index_map, + }, + }, + process::ProcMacroServerProcess, + transport::postcard, +}; + +pub mod msg; + +pub type SubCallback<'a> = &'a dyn Fn(SubRequest) -> Result; + +pub fn run_conversation( + writer: &mut dyn Write, + reader: &mut dyn BufRead, + buf: &mut Vec, + msg: BidirectionalMessage, + callback: SubCallback<'_>, +) -> Result { + let encoded = postcard::encode(&msg).map_err(wrap_encode)?; + postcard::write(writer, &encoded).map_err(wrap_io("failed to write initial request"))?; + + loop { + let maybe_buf = postcard::read(reader, buf).map_err(wrap_io("failed to read message"))?; + let Some(b) = maybe_buf else { + return Err(ServerError { + message: "proc-macro server closed the stream".into(), + io: Some(Arc::new(io::Error::new(io::ErrorKind::UnexpectedEof, "closed"))), + }); + }; + + let msg: BidirectionalMessage = postcard::decode(b).map_err(wrap_decode)?; + + match msg { + BidirectionalMessage::Response(response) => { + return Ok(BidirectionalMessage::Response(response)); + } + BidirectionalMessage::SubRequest(sr) => { + // TODO: Avoid `AssertUnwindSafe` by making the callback `UnwindSafe` once `ExpandDatabase` + // becomes unwind-safe (currently blocked by `parking_lot::RwLock` in the VFS). + let resp = match catch_unwind(AssertUnwindSafe(|| callback(sr))) { + Ok(Ok(resp)) => BidirectionalMessage::SubResponse(resp), + Ok(Err(err)) => BidirectionalMessage::SubResponse(SubResponse::Cancel { + reason: err.to_string(), + }), + Err(_) => BidirectionalMessage::SubResponse(SubResponse::Cancel { + reason: "callback panicked or was cancelled".into(), + }), + }; + + let encoded = postcard::encode(&resp).map_err(wrap_encode)?; + postcard::write(writer, &encoded) + .map_err(wrap_io("failed to write sub-response"))?; + } + _ => { + return Err(ServerError { + message: format!("unexpected message {:?}", msg), + io: None, + }); + } + } + } +} + +fn wrap_io(msg: &'static str) -> impl Fn(io::Error) -> ServerError { + move |err| ServerError { message: msg.into(), io: Some(Arc::new(err)) } +} + +fn wrap_encode(err: io::Error) -> ServerError { + ServerError { message: "failed to encode message".into(), io: Some(Arc::new(err)) } +} + +fn wrap_decode(err: io::Error) -> ServerError { + ServerError { message: "failed to decode message".into(), io: Some(Arc::new(err)) } +} + +pub(crate) fn version_check( + srv: &ProcMacroServerProcess, + callback: SubCallback<'_>, +) -> Result { + let request = BidirectionalMessage::Request(Request::ApiVersionCheck {}); + + let response_payload = run_request(srv, request, callback)?; + + match response_payload { + BidirectionalMessage::Response(Response::ApiVersionCheck(version)) => Ok(version), + other => { + Err(ServerError { message: format!("unexpected response: {:?}", other), io: None }) + } + } +} + +/// Enable support for rust-analyzer span mode if the server supports it. +pub(crate) fn enable_rust_analyzer_spans( + srv: &ProcMacroServerProcess, + callback: SubCallback<'_>, +) -> Result { + let request = BidirectionalMessage::Request(Request::SetConfig(ServerConfig { + span_mode: SpanMode::RustAnalyzer, + })); + + let response_payload = run_request(srv, request, callback)?; + + match response_payload { + BidirectionalMessage::Response(Response::SetConfig(ServerConfig { span_mode })) => { + Ok(span_mode) + } + _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), + } +} + +/// Finds proc-macros in a given dynamic library. +pub(crate) fn find_proc_macros( + srv: &ProcMacroServerProcess, + dylib_path: &AbsPath, + callback: SubCallback<'_>, +) -> Result, String>, ServerError> { + let request = BidirectionalMessage::Request(Request::ListMacros { + dylib_path: dylib_path.to_path_buf().into(), + }); + + let response_payload = run_request(srv, request, callback)?; + + match response_payload { + BidirectionalMessage::Response(Response::ListMacros(it)) => Ok(it), + _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), + } +} + +pub(crate) fn expand( + proc_macro: &ProcMacro, + process: &ProcMacroServerProcess, + subtree: tt::SubtreeView<'_>, + attr: Option>, + env: Vec<(String, String)>, + def_site: Span, + call_site: Span, + mixed_site: Span, + current_dir: String, + callback: SubCallback<'_>, +) -> Result, crate::ServerError> { + let version = process.version(); + let mut span_data_table = SpanDataIndexMap::default(); + let def_site = span_data_table.insert_full(def_site).0; + let call_site = span_data_table.insert_full(call_site).0; + let mixed_site = span_data_table.insert_full(mixed_site).0; + let task = BidirectionalMessage::Request(Request::ExpandMacro(Box::new(ExpandMacro { + data: ExpandMacroData { + macro_body: FlatTree::from_subtree(subtree, version, &mut span_data_table), + macro_name: proc_macro.name.to_string(), + attributes: attr + .map(|subtree| FlatTree::from_subtree(subtree, version, &mut span_data_table)), + has_global_spans: ExpnGlobals { def_site, call_site, mixed_site }, + span_data_table: if process.rust_analyzer_spans() { + serialize_span_data_index_map(&span_data_table) + } else { + Vec::new() + }, + }, + lib: proc_macro.dylib_path.to_path_buf().into(), + env, + current_dir: Some(current_dir), + }))); + + let response_payload = run_request(process, task, callback)?; + + match response_payload { + BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it + .map(|tree| { + let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table); + if proc_macro.needs_fixup_change() { + proc_macro.change_fixup_to_match_old_server(&mut expanded); + } + expanded + }) + .map_err(|msg| msg.0)), + BidirectionalMessage::Response(Response::ExpandMacroExtended(it)) => Ok(it + .map(|resp| { + let mut expanded = FlatTree::to_subtree_resolved( + resp.tree, + version, + &deserialize_span_data_index_map(&resp.span_data_table), + ); + if proc_macro.needs_fixup_change() { + proc_macro.change_fixup_to_match_old_server(&mut expanded); + } + expanded + }) + .map_err(|msg| msg.0)), + _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), + } +} + +fn run_request( + srv: &ProcMacroServerProcess, + msg: BidirectionalMessage, + callback: SubCallback<'_>, +) -> Result { + if let Some(err) = srv.exited() { + return Err(err.clone()); + } + srv.run_bidirectional(msg, callback) +} + +pub fn reject_subrequests(req: SubRequest) -> Result { + Err(ServerError { message: format!("{req:?} sub-request not supported here"), io: None }) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs new file mode 100644 index 000000000000..3f0422dc5bc8 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -0,0 +1,120 @@ +//! Bidirectional protocol messages + +use std::{ + io::{self, BufRead, Write}, + ops::Range, +}; + +use paths::Utf8PathBuf; +use serde::{Deserialize, Serialize}; + +use crate::{ + ProcMacroKind, + legacy_protocol::msg::{FlatTree, Message, PanicMessage, ServerConfig}, + transport::postcard, +}; + +#[derive(Debug, Serialize, Deserialize)] +pub enum SubRequest { + FilePath { file_id: u32 }, + SourceText { file_id: u32, ast_id: u32, start: u32, end: u32 }, + LocalFilePath { file_id: u32 }, + LineColumn { file_id: u32, ast_id: u32, offset: u32 }, + ByteRange { file_id: u32, ast_id: u32, start: u32, end: u32 }, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum SubResponse { + FilePathResult { + name: String, + }, + SourceTextResult { + text: Option, + }, + LocalFilePathResult { + name: Option, + }, + /// Line and column are 1-based. + LineColumnResult { + line: u32, + column: u32, + }, + ByteRangeResult { + range: Range, + }, + Cancel { + reason: String, + }, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum BidirectionalMessage { + Request(Request), + Response(Response), + SubRequest(SubRequest), + SubResponse(SubResponse), +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum Request { + ListMacros { dylib_path: Utf8PathBuf }, + ExpandMacro(Box), + ApiVersionCheck {}, + SetConfig(ServerConfig), +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum Response { + ListMacros(Result, String>), + ExpandMacro(Result), + ApiVersionCheck(u32), + SetConfig(ServerConfig), + ExpandMacroExtended(Result), +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ExpandMacro { + pub lib: Utf8PathBuf, + pub env: Vec<(String, String)>, + pub current_dir: Option, + pub data: ExpandMacroData, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ExpandMacroExtended { + pub tree: FlatTree, + pub span_data_table: Vec, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct ExpandMacroData { + pub macro_body: FlatTree, + pub macro_name: String, + pub attributes: Option, + #[serde(default)] + pub has_global_spans: ExpnGlobals, + #[serde(default)] + pub span_data_table: Vec, +} + +#[derive(Clone, Copy, Default, Debug, Serialize, Deserialize)] +pub struct ExpnGlobals { + pub def_site: usize, + pub call_site: usize, + pub mixed_site: usize, +} + +impl Message for BidirectionalMessage { + type Buf = Vec; + + fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result> { + Ok(match postcard::read(inp, buf)? { + None => None, + Some(buf) => Some(postcard::decode(buf)?), + }) + } + fn write(self, out: &mut dyn Write) -> io::Result<()> { + let value = postcard::encode(&self)?; + postcard::write(out, &value) + } +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/codec.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/codec.rs deleted file mode 100644 index baccaa6be4c2..000000000000 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/codec.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Protocol codec - -use std::io; - -use serde::de::DeserializeOwned; - -use crate::framing::Framing; - -pub trait Codec: Framing { - fn encode(msg: &T) -> io::Result; - fn decode(buf: &mut Self::Buf) -> io::Result; -} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/framing.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/framing.rs deleted file mode 100644 index a1e6fc05ca11..000000000000 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/framing.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! Protocol framing - -use std::io::{self, BufRead, Write}; - -pub trait Framing { - type Buf: Default; - - fn read<'a, R: BufRead>( - inp: &mut R, - buf: &'a mut Self::Buf, - ) -> io::Result>; - - fn write(out: &mut W, buf: &Self::Buf) -> io::Result<()>; -} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs index c2b132ddcc1d..ee1795d39c2e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol.rs @@ -1,8 +1,6 @@ //! The initial proc-macro-srv protocol, soon to be deprecated. -pub mod json; pub mod msg; -pub mod postcard; use std::{ io::{BufRead, Write}, @@ -14,15 +12,10 @@ use span::Span; use crate::{ ProcMacro, ProcMacroKind, ServerError, - codec::Codec, - legacy_protocol::{ - json::JsonProtocol, - msg::{ - ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, Message, Request, Response, - ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map, - flat::serialize_span_data_index_map, - }, - postcard::PostcardProtocol, + legacy_protocol::msg::{ + ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, Message, Request, Response, + ServerConfig, SpanDataIndexMap, deserialize_span_data_index_map, + flat::serialize_span_data_index_map, }, process::ProcMacroServerProcess, version, @@ -82,16 +75,16 @@ pub(crate) fn find_proc_macros( pub(crate) fn expand( proc_macro: &ProcMacro, - subtree: tt::SubtreeView<'_, Span>, - attr: Option>, + process: &ProcMacroServerProcess, + subtree: tt::SubtreeView<'_>, + attr: Option>, env: Vec<(String, String)>, def_site: Span, call_site: Span, mixed_site: Span, current_dir: String, -) -> Result>, String>, crate::ServerError> -{ - let version = proc_macro.process.version(); +) -> Result, crate::ServerError> { + let version = process.version(); let mut span_data_table = SpanDataIndexMap::default(); let def_site = span_data_table.insert_full(def_site).0; let call_site = span_data_table.insert_full(call_site).0; @@ -108,7 +101,7 @@ pub(crate) fn expand( call_site, mixed_site, }, - span_data_table: if proc_macro.process.rust_analyzer_spans() { + span_data_table: if process.rust_analyzer_spans() { serialize_span_data_index_map(&span_data_table) } else { Vec::new() @@ -119,7 +112,7 @@ pub(crate) fn expand( current_dir: Some(current_dir), }; - let response = send_task(&proc_macro.process, Request::ExpandMacro(Box::new(task)))?; + let response = send_task(process, Request::ExpandMacro(Box::new(task)))?; match response { Response::ExpandMacro(it) => Ok(it @@ -154,25 +147,21 @@ fn send_task(srv: &ProcMacroServerProcess, req: Request) -> Result, req) - } else { - srv.send_task(send_request::, req) - } + srv.send_task_legacy::<_, _>(send_request, req) } /// Sends a request to the server and reads the response. -fn send_request( +fn send_request( mut writer: &mut dyn Write, mut reader: &mut dyn BufRead, req: Request, - buf: &mut P::Buf, + buf: &mut String, ) -> Result, ServerError> { - req.write::<_, P>(&mut writer).map_err(|err| ServerError { + req.write(&mut writer).map_err(|err| ServerError { message: "failed to write request".into(), io: Some(Arc::new(err)), })?; - let res = Response::read::<_, P>(&mut reader, buf).map_err(|err| ServerError { + let res = Response::read(&mut reader, buf).map_err(|err| ServerError { message: "failed to read response".into(), io: Some(Arc::new(err)), })?; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs deleted file mode 100644 index 1359c0568402..000000000000 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/json.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! Protocol functions for json. -use std::io::{self, BufRead, Write}; - -use serde::{Serialize, de::DeserializeOwned}; - -use crate::{codec::Codec, framing::Framing}; - -pub struct JsonProtocol; - -impl Framing for JsonProtocol { - type Buf = String; - - fn read<'a, R: BufRead>( - inp: &mut R, - buf: &'a mut String, - ) -> io::Result> { - loop { - buf.clear(); - - inp.read_line(buf)?; - buf.pop(); // Remove trailing '\n' - - if buf.is_empty() { - return Ok(None); - } - - // Some ill behaved macro try to use stdout for debugging - // We ignore it here - if !buf.starts_with('{') { - tracing::error!("proc-macro tried to print : {}", buf); - continue; - } - - return Ok(Some(buf)); - } - } - - fn write(out: &mut W, buf: &String) -> io::Result<()> { - tracing::debug!("> {}", buf); - out.write_all(buf.as_bytes())?; - out.write_all(b"\n")?; - out.flush() - } -} - -impl Codec for JsonProtocol { - fn encode(msg: &T) -> io::Result { - Ok(serde_json::to_string(msg)?) - } - - fn decode(buf: &mut String) -> io::Result { - let mut deserializer = serde_json::Deserializer::from_str(buf); - // Note that some proc-macro generate very deep syntax tree - // We have to disable the current limit of serde here - deserializer.disable_recursion_limit(); - Ok(T::deserialize(&mut deserializer)?) - } -} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs index a6e228d977db..bb0dde472860 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg.rs @@ -8,7 +8,7 @@ use paths::Utf8PathBuf; use serde::de::DeserializeOwned; use serde_derive::{Deserialize, Serialize}; -use crate::{ProcMacroKind, codec::Codec}; +use crate::{ProcMacroKind, transport::json}; /// Represents requests sent from the client to the proc-macro-srv. #[derive(Debug, Serialize, Deserialize)] @@ -155,24 +155,44 @@ impl ExpnGlobals { } pub trait Message: serde::Serialize + DeserializeOwned { - fn read(inp: &mut R, buf: &mut C::Buf) -> io::Result> { - Ok(match C::read(inp, buf)? { + type Buf; + fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result>; + fn write(self, out: &mut dyn Write) -> io::Result<()>; +} + +impl Message for Request { + type Buf = String; + + fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result> { + Ok(match json::read(inp, buf)? { None => None, - Some(buf) => Some(C::decode(buf)?), + Some(buf) => Some(json::decode(buf)?), }) } - fn write(self, out: &mut W) -> io::Result<()> { - let value = C::encode(&self)?; - C::write(out, &value) + fn write(self, out: &mut dyn Write) -> io::Result<()> { + let value = json::encode(&self)?; + json::write(out, &value) } } -impl Message for Request {} -impl Message for Response {} +impl Message for Response { + type Buf = String; + + fn read(inp: &mut dyn BufRead, buf: &mut Self::Buf) -> io::Result> { + Ok(match json::read(inp, buf)? { + None => None, + Some(buf) => Some(json::decode(buf)?), + }) + } + fn write(self, out: &mut dyn Write) -> io::Result<()> { + let value = json::encode(&self)?; + json::write(out, &value) + } +} #[cfg(test)] mod tests { - use intern::{Symbol, sym}; + use intern::Symbol; use span::{ Edition, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, TextRange, TextSize, }; @@ -185,7 +205,7 @@ mod tests { use super::*; - fn fixture_token_tree_top_many_none() -> TopSubtree { + fn fixture_token_tree_top_many_none() -> TopSubtree { let anchor = SpanAnchor { file_id: span::EditionedFileId::new( span::FileId::from_raw(0xe4e4e), @@ -232,16 +252,15 @@ mod tests { } .into(), ); - builder.push(Leaf::Literal(Literal { - symbol: Symbol::intern("Foo"), - span: Span { + builder.push(Leaf::Literal(Literal::new_no_suffix( + "Foo", + Span { range: TextRange::at(TextSize::new(10), TextSize::of("\"Foo\"")), anchor, ctx: SyntaxContext::root(Edition::CURRENT), }, - kind: tt::LitKind::Str, - suffix: None, - })); + tt::LitKind::Str, + ))); builder.push(Leaf::Punct(Punct { char: '@', span: Span { @@ -267,16 +286,16 @@ mod tests { ctx: SyntaxContext::root(Edition::CURRENT), }, ); - builder.push(Leaf::Literal(Literal { - symbol: sym::INTEGER_0, - span: Span { + builder.push(Leaf::Literal(Literal::new( + "0", + Span { range: TextRange::at(TextSize::new(16), TextSize::of("0u32")), anchor, ctx: SyntaxContext::root(Edition::CURRENT), }, - kind: tt::LitKind::Integer, - suffix: Some(sym::u32), - })); + tt::LitKind::Integer, + "u32", + ))); builder.close(Span { range: TextRange::at(TextSize::new(20), TextSize::of(']')), anchor, @@ -292,7 +311,7 @@ mod tests { builder.build() } - fn fixture_token_tree_top_empty_none() -> TopSubtree { + fn fixture_token_tree_top_empty_none() -> TopSubtree { let anchor = SpanAnchor { file_id: span::EditionedFileId::new( span::FileId::from_raw(0xe4e4e), @@ -318,7 +337,7 @@ mod tests { builder.build() } - fn fixture_token_tree_top_empty_brace() -> TopSubtree { + fn fixture_token_tree_top_empty_brace() -> TopSubtree { let anchor = SpanAnchor { file_id: span::EditionedFileId::new( span::FileId::from_raw(0xe4e4e), diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs index 1ac8cd4006a0..cd8944aa6170 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/msg/flat.rs @@ -123,7 +123,7 @@ struct IdentRepr { impl FlatTree { pub fn from_subtree( - subtree: tt::SubtreeView<'_, Span>, + subtree: tt::SubtreeView<'_>, version: u32, span_data_table: &mut SpanDataIndexMap, ) -> FlatTree { @@ -168,7 +168,7 @@ impl FlatTree { self, version: u32, span_data_table: &SpanDataIndexMap, - ) -> tt::TopSubtree { + ) -> tt::TopSubtree { Reader:: { subtree: if version >= ENCODE_CLOSE_SPAN_VERSION { read_vec(self.subtree, SubtreeRepr::read_with_close_span) @@ -486,16 +486,16 @@ struct Writer<'a, 'span, S: SpanTransformer, W> { text: Vec, } -impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIter<'a, T::Span>> { - fn write_subtree(&mut self, root: tt::SubtreeView<'a, T::Span>) { +impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIter<'a>> { + fn write_subtree(&mut self, root: tt::SubtreeView<'a>) { let subtree = root.top_subtree(); - self.enqueue(subtree, root.iter()); + self.enqueue(&subtree, root.iter()); while let Some((idx, len, subtree)) = self.work.pop_front() { self.subtree(idx, len, subtree); } } - fn subtree(&mut self, idx: usize, n_tt: usize, subtree: tt::iter::TtIter<'a, T::Span>) { + fn subtree(&mut self, idx: usize, n_tt: usize, subtree: tt::iter::TtIter<'a>) { let mut first_tt = self.token_tree.len(); self.token_tree.resize(first_tt + n_tt, !0); @@ -504,7 +504,7 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIter<'a, T::Span>> { for child in subtree { let idx_tag = match child { tt::iter::TtElement::Subtree(subtree, subtree_iter) => { - let idx = self.enqueue(subtree, subtree_iter); + let idx = self.enqueue(&subtree, subtree_iter); idx << 2 } tt::iter::TtElement::Leaf(leaf) => match leaf { @@ -512,9 +512,14 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIter<'a, T::Span>> { let idx = self.literal.len() as u32; let id = self.token_id_of(lit.span); let (text, suffix) = if self.version >= EXTENDED_LEAF_DATA { + let (text, suffix) = lit.text_and_suffix(); ( - self.intern(lit.symbol.as_str()), - lit.suffix.as_ref().map(|s| self.intern(s.as_str())).unwrap_or(!0), + self.intern_owned(text.to_owned()), + if suffix.is_empty() { + !0 + } else { + self.intern_owned(suffix.to_owned()) + }, ) } else { (self.intern_owned(format!("{lit}")), !0) @@ -549,11 +554,11 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIter<'a, T::Span>> { let idx = self.ident.len() as u32; let id = self.token_id_of(ident.span); let text = if self.version >= EXTENDED_LEAF_DATA { - self.intern(ident.sym.as_str()) + self.intern_owned(ident.sym.as_str().to_owned()) } else if ident.is_raw.yes() { self.intern_owned(format!("r#{}", ident.sym.as_str(),)) } else { - self.intern(ident.sym.as_str()) + self.intern_owned(ident.sym.as_str().to_owned()) }; self.ident.push(IdentRepr { id, text, is_raw: ident.is_raw.yes() }); (idx << 2) | 0b11 @@ -565,11 +570,7 @@ impl<'a, T: SpanTransformer> Writer<'a, '_, T, tt::iter::TtIter<'a, T::Span>> { } } - fn enqueue( - &mut self, - subtree: &'a tt::Subtree, - contents: tt::iter::TtIter<'a, T::Span>, - ) -> u32 { + fn enqueue(&mut self, subtree: &tt::Subtree, contents: tt::iter::TtIter<'a>) -> u32 { let idx = self.subtree.len(); let open = self.token_id_of(subtree.delimiter.open); let close = self.token_id_of(subtree.delimiter.close); @@ -586,6 +587,7 @@ impl<'a, T: SpanTransformer, U> Writer<'a, '_, T, U> { T::token_id_of(self.span_data_table, span) } + #[cfg(feature = "sysroot-abi")] pub(crate) fn intern(&mut self, text: &'a str) -> u32 { let table = &mut self.text; *self.string_table.entry(text.into()).or_insert_with(|| { @@ -739,9 +741,9 @@ struct Reader<'span, S: SpanTransformer> { span_data_table: &'span S::Table, } -impl Reader<'_, T> { - pub(crate) fn read_subtree(self) -> tt::TopSubtree { - let mut res: Vec, Vec>)>> = +impl> Reader<'_, T> { + pub(crate) fn read_subtree(self) -> tt::TopSubtree { + let mut res: Vec)>> = vec![None; self.subtree.len()]; let read_span = |id| T::span_for_token_id(self.span_data_table, id); for i in (0..self.subtree.len()).rev() { @@ -774,10 +776,10 @@ impl Reader<'_, T> { let span = read_span(repr.id); s.push( tt::Leaf::Literal(if self.version >= EXTENDED_LEAF_DATA { - tt::Literal { - symbol: Symbol::intern(text), + tt::Literal::new( + text, span, - kind: match u16::to_le_bytes(repr.kind) { + match u16::to_le_bytes(repr.kind) { [0, _] => Err(()), [1, _] => Byte, [2, _] => Char, @@ -791,14 +793,12 @@ impl Reader<'_, T> { [10, r] => CStrRaw(r), _ => unreachable!(), }, - suffix: if repr.suffix != !0 { - Some(Symbol::intern( - self.text[repr.suffix as usize].as_str(), - )) + if repr.suffix != !0 { + self.text[repr.suffix as usize].as_str() } else { - None + "" }, - } + ) } else { tt::token_to_literal(text, span) }) @@ -844,7 +844,7 @@ impl Reader<'_, T> { let (delimiter, mut res) = res[0].take().unwrap(); res.insert(0, tt::TokenTree::Subtree(tt::Subtree { delimiter, len: res.len() as u32 })); - tt::TopSubtree(res.into_boxed_slice()) + tt::TopSubtree::from_serialized(res) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/postcard.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/postcard.rs deleted file mode 100644 index c28a9bfe3a1a..000000000000 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/legacy_protocol/postcard.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Postcard encode and decode implementations. - -use std::io::{self, BufRead, Write}; - -use serde::{Serialize, de::DeserializeOwned}; - -use crate::{codec::Codec, framing::Framing}; - -pub struct PostcardProtocol; - -impl Framing for PostcardProtocol { - type Buf = Vec; - - fn read<'a, R: BufRead>( - inp: &mut R, - buf: &'a mut Vec, - ) -> io::Result>> { - buf.clear(); - let n = inp.read_until(0, buf)?; - if n == 0 { - return Ok(None); - } - Ok(Some(buf)) - } - - fn write(out: &mut W, buf: &Vec) -> io::Result<()> { - out.write_all(buf)?; - out.flush() - } -} - -impl Codec for PostcardProtocol { - fn encode(msg: &T) -> io::Result> { - postcard::to_allocvec_cobs(msg).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - } - - fn decode(buf: &mut Self::Buf) -> io::Result { - postcard::from_bytes_cobs(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - } -} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs index f0c7ce7efd1c..68b3afc3e841 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs @@ -11,19 +11,25 @@ feature(proc_macro_internals, proc_macro_diagnostic, proc_macro_span) )] #![allow(internal_features)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] -mod codec; -mod framing; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + +pub mod bidirectional_protocol; pub mod legacy_protocol; -mod process; +pub mod pool; +pub mod process; +pub mod transport; use paths::{AbsPath, AbsPathBuf}; use semver::Version; use span::{ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, Span}; use std::{fmt, io, sync::Arc, time::SystemTime}; -pub use crate::codec::Codec; -use crate::process::ProcMacroServerProcess; +use crate::{ + bidirectional_protocol::SubCallback, pool::ProcMacroServerPool, process::ProcMacroServerProcess, +}; /// The versions of the server protocol pub mod version { @@ -40,6 +46,26 @@ pub mod version { pub const CURRENT_API_VERSION: u32 = HASHED_AST_ID; } +/// Protocol format for communication between client and server. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum ProtocolFormat { + /// JSON-based legacy protocol (newline-delimited JSON). + JsonLegacy, + /// Bidirectional postcard protocol with sub-request support. + BidirectionalPostcardPrototype, +} + +impl fmt::Display for ProtocolFormat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ProtocolFormat::JsonLegacy => write!(f, "json-legacy"), + ProtocolFormat::BidirectionalPostcardPrototype => { + write!(f, "bidirectional-postcard-prototype") + } + } + } +} + /// Represents different kinds of procedural macros that can be expanded by the external server. #[derive(Copy, Clone, Eq, PartialEq, Debug, serde_derive::Serialize, serde_derive::Deserialize)] pub enum ProcMacroKind { @@ -61,7 +87,7 @@ pub struct ProcMacroClient { /// /// That means that concurrent salsa requests may block each other when expanding proc macros, /// which is unfortunate, but simple and good enough for the time being. - process: Arc, + pool: Arc, path: AbsPathBuf, } @@ -83,7 +109,7 @@ impl MacroDylib { /// we share a single expander process for all macros within a workspace. #[derive(Debug, Clone)] pub struct ProcMacro { - process: Arc, + pool: ProcMacroServerPool, dylib_path: Arc, name: Box, kind: ProcMacroKind, @@ -97,7 +123,6 @@ impl PartialEq for ProcMacro { && self.kind == other.kind && self.dylib_path == other.dylib_path && self.dylib_last_modified == other.dylib_last_modified - && Arc::ptr_eq(&self.process, &other.process) } } @@ -127,9 +152,44 @@ impl ProcMacroClient { Item = (impl AsRef, &'a Option>), > + Clone, version: Option<&Version>, + num_process: usize, ) -> io::Result { - let process = ProcMacroServerProcess::run(process_path, env, version)?; - Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) + let pool_size = num_process; + let mut workers = Vec::with_capacity(pool_size); + for _ in 0..pool_size { + let worker = ProcMacroServerProcess::spawn(process_path, env.clone(), version)?; + workers.push(worker); + } + + let pool = ProcMacroServerPool::new(workers); + Ok(ProcMacroClient { pool: Arc::new(pool), path: process_path.to_owned() }) + } + + /// Invokes `spawn` and returns a client connected to the resulting read and write handles. + /// + /// The `process_path` is used for `Self::server_path`. This function is mainly used for testing. + pub fn with_io_channels( + process_path: &AbsPath, + spawn: impl Fn( + Option, + ) -> io::Result<( + Box, + Box, + Box, + )> + Clone, + version: Option<&Version>, + num_process: usize, + ) -> io::Result { + let pool_size = num_process; + let mut workers = Vec::with_capacity(pool_size); + for _ in 0..pool_size { + let worker = + ProcMacroServerProcess::run(spawn.clone(), version, || "".to_owned())?; + workers.push(worker); + } + + let pool = ProcMacroServerPool::new(workers); + Ok(ProcMacroClient { pool: Arc::new(pool), path: process_path.to_owned() }) } /// Returns the absolute path to the proc-macro server. @@ -139,31 +199,12 @@ impl ProcMacroClient { /// Loads a proc-macro dylib into the server process returning a list of `ProcMacro`s loaded. pub fn load_dylib(&self, dylib: MacroDylib) -> Result, ServerError> { - let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); - let macros = self.process.find_proc_macros(&dylib.path)?; - - let dylib_path = Arc::new(dylib.path); - let dylib_last_modified = std::fs::metadata(dylib_path.as_path()) - .ok() - .and_then(|metadata| metadata.modified().ok()); - match macros { - Ok(macros) => Ok(macros - .into_iter() - .map(|(name, kind)| ProcMacro { - process: self.process.clone(), - name: name.into(), - kind, - dylib_path: dylib_path.clone(), - dylib_last_modified, - }) - .collect()), - Err(message) => Err(ServerError { message, io: None }), - } + self.pool.load_dylib(&dylib) } /// Checks if the proc-macro server has exited. pub fn exited(&self) -> Option<&ServerError> { - self.process.exited() + self.pool.exited() } } @@ -179,49 +220,36 @@ impl ProcMacro { } fn needs_fixup_change(&self) -> bool { - let version = self.process.version(); + let version = self.pool.version(); (version::RUST_ANALYZER_SPAN_SUPPORT..version::HASHED_AST_ID).contains(&version) } /// On some server versions, the fixup ast id is different than ours. So change it to match. - fn change_fixup_to_match_old_server(&self, tt: &mut tt::TopSubtree) { + fn change_fixup_to_match_old_server(&self, tt: &mut tt::TopSubtree) { const OLD_FIXUP_AST_ID: ErasedFileAstId = ErasedFileAstId::from_raw(!0 - 1); - let change_ast_id = |ast_id: &mut ErasedFileAstId| { + tt.change_every_ast_id(|ast_id| { if *ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { *ast_id = OLD_FIXUP_AST_ID; } else if *ast_id == OLD_FIXUP_AST_ID { // Swap between them, that means no collision plus the change can be reversed by doing itself. *ast_id = FIXUP_ERASED_FILE_AST_ID_MARKER; } - }; - - for tt in &mut tt.0 { - match tt { - tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident { span, .. })) - | tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { span, .. })) - | tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { span, .. })) => { - change_ast_id(&mut span.anchor.ast_id); - } - tt::TokenTree::Subtree(subtree) => { - change_ast_id(&mut subtree.delimiter.open.anchor.ast_id); - change_ast_id(&mut subtree.delimiter.close.anchor.ast_id); - } - } - } + }); } /// Expands the procedural macro by sending an expansion request to the server. /// This includes span information and environmental context. pub fn expand( &self, - subtree: tt::SubtreeView<'_, Span>, - attr: Option>, + subtree: tt::SubtreeView<'_>, + attr: Option>, env: Vec<(String, String)>, def_site: Span, call_site: Span, mixed_site: Span, current_dir: String, - ) -> Result, String>, ServerError> { + callback: Option>, + ) -> Result, ServerError> { let (mut subtree, mut attr) = (subtree, attr); let (mut subtree_changed, mut attr_changed); if self.needs_fixup_change() { @@ -236,7 +264,7 @@ impl ProcMacro { } } - legacy_protocol::expand( + self.pool.pick_process()?.expand( self, subtree, attr, @@ -245,6 +273,7 @@ impl ProcMacro { call_site, mixed_site, current_dir, + callback, ) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs new file mode 100644 index 000000000000..e6541823da58 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/pool.rs @@ -0,0 +1,89 @@ +//! A pool of proc-macro server processes +use std::sync::Arc; + +use rayon::iter::{IntoParallelIterator, ParallelIterator}; + +use crate::{MacroDylib, ProcMacro, ServerError, process::ProcMacroServerProcess}; + +#[derive(Debug, Clone)] +pub(crate) struct ProcMacroServerPool { + workers: Arc<[ProcMacroServerProcess]>, + version: u32, +} + +impl ProcMacroServerPool { + pub(crate) fn new(workers: Vec) -> Self { + let version = workers[0].version(); + Self { workers: workers.into(), version } + } +} + +impl ProcMacroServerPool { + pub(crate) fn exited(&self) -> Option<&ServerError> { + for worker in &*self.workers { + worker.exited()?; + } + self.workers[0].exited() + } + + pub(crate) fn pick_process(&self) -> Result<&ProcMacroServerProcess, ServerError> { + let mut best: Option<&ProcMacroServerProcess> = None; + let mut best_load = u32::MAX; + + for w in self.workers.iter().filter(|w| w.exited().is_none()) { + let load = w.number_of_active_req(); + + if load == 0 { + return Ok(w); + } + + if load < best_load { + best = Some(w); + best_load = load; + } + } + + best.ok_or_else(|| ServerError { + message: "all proc-macro server workers have exited".into(), + io: None, + }) + } + + pub(crate) fn load_dylib(&self, dylib: &MacroDylib) -> Result, ServerError> { + let _span = tracing::info_span!("ProcMacroServer::load_dylib").entered(); + + let dylib_path = Arc::new(dylib.path.clone()); + let dylib_last_modified = + std::fs::metadata(dylib_path.as_path()).ok().and_then(|m| m.modified().ok()); + + let (first, rest) = self.workers.split_first().expect("worker pool must not be empty"); + + let macros = first + .find_proc_macros(&dylib.path)? + .map_err(|e| ServerError { message: e, io: None })?; + + rest.into_par_iter() + .map(|worker| { + worker + .find_proc_macros(&dylib.path)? + .map(|_| ()) + .map_err(|e| ServerError { message: e, io: None }) + }) + .collect::>()?; + + Ok(macros + .into_iter() + .map(|(name, kind)| ProcMacro { + pool: self.clone(), + name: name.into(), + kind, + dylib_path: dylib_path.clone(), + dylib_last_modified, + }) + .collect()) + } + + pub(crate) fn version(&self) -> u32 { + self.version + } +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs index d6a8d27bfc42..80e4ed05c36d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs @@ -1,24 +1,33 @@ //! Handle process life-time and message passing for proc-macro client use std::{ + fmt::Debug, io::{self, BufRead, BufReader, Read, Write}, panic::AssertUnwindSafe, process::{Child, ChildStdin, ChildStdout, Command, Stdio}, - sync::{Arc, Mutex, OnceLock}, + sync::{ + Arc, Mutex, OnceLock, + atomic::{AtomicU32, Ordering}, + }, }; use paths::AbsPath; use semver::Version; +use span::Span; use stdx::JodChild; use crate::{ - ProcMacroKind, ServerError, + ProcMacro, ProcMacroKind, ProtocolFormat, ServerError, + bidirectional_protocol::{ + self, SubCallback, + msg::{BidirectionalMessage, SubResponse}, + reject_subrequests, + }, legacy_protocol::{self, SpanMode}, version, }; /// Represents a process handling proc-macro communication. -#[derive(Debug)] pub(crate) struct ProcMacroServerProcess { /// The state of the proc-macro server process, the protocol is currently strictly sequential /// hence the lock on the state. @@ -27,30 +36,102 @@ pub(crate) struct ProcMacroServerProcess { protocol: Protocol, /// Populated when the server exits. exited: OnceLock>, + active: AtomicU32, +} + +impl std::fmt::Debug for ProcMacroServerProcess { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ProcMacroServerProcess") + .field("version", &self.version) + .field("protocol", &self.protocol) + .field("exited", &self.exited) + .finish() + } } #[derive(Debug, Clone)] pub(crate) enum Protocol { LegacyJson { mode: SpanMode }, - LegacyPostcard { mode: SpanMode }, + BidirectionalPostcardPrototype { mode: SpanMode }, +} + +pub trait ProcessExit: Send + Sync { + fn exit_err(&mut self) -> Option; +} + +impl ProcessExit for Process { + fn exit_err(&mut self) -> Option { + match self.child.try_wait() { + Ok(None) | Err(_) => None, + Ok(Some(status)) => { + let mut msg = String::new(); + if !status.success() + && let Some(stderr) = self.child.stderr.as_mut() + { + _ = stderr.read_to_string(&mut msg); + } + Some(ServerError { + message: format!( + "proc-macro server exited with {status}{}{msg}", + if msg.is_empty() { "" } else { ": " } + ), + io: None, + }) + } + } + } } /// Maintains the state of the proc-macro server process. -#[derive(Debug)] -struct ProcessSrvState { - process: Process, - stdin: ChildStdin, - stdout: BufReader, +pub(crate) struct ProcessSrvState { + process: Box, + stdin: Box, + stdout: Box, } impl ProcMacroServerProcess { /// Starts the proc-macro server and performs a version check - pub(crate) fn run<'a>( + pub(crate) fn spawn<'a>( process_path: &AbsPath, env: impl IntoIterator< Item = (impl AsRef, &'a Option>), > + Clone, version: Option<&Version>, + ) -> io::Result { + Self::run( + |format| { + let mut process = Process::run( + process_path, + env.clone(), + format.map(|format| format.to_string()).as_deref(), + )?; + let (stdin, stdout) = process.stdio().expect("couldn't access child stdio"); + + Ok((Box::new(process), Box::new(stdin), Box::new(stdout))) + }, + version, + || { + #[expect(clippy::disallowed_methods)] + Command::new(process_path) + .arg("--version") + .output() + .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned()) + .unwrap_or_else(|_| "unknown version".to_owned()) + }, + ) + } + + /// Invokes `spawn` and performs a version check. + pub(crate) fn run( + spawn: impl Fn( + Option, + ) -> io::Result<( + Box, + Box, + Box, + )>, + version: Option<&Version>, + binary_server_version: impl Fn() -> String, ) -> io::Result { const VERSION: Version = Version::new(1, 93, 0); // we do `>` for nightly as this started working in the middle of the 1.93 nightly release, so we dont want to break on half of the nightlies @@ -62,36 +143,38 @@ impl ProcMacroServerProcess { && has_working_format_flag { &[ - (Some("postcard-legacy"), Protocol::LegacyPostcard { mode: SpanMode::Id }), - (Some("json-legacy"), Protocol::LegacyJson { mode: SpanMode::Id }), + Some(ProtocolFormat::BidirectionalPostcardPrototype), + Some(ProtocolFormat::JsonLegacy), ] } else { - &[(None, Protocol::LegacyJson { mode: SpanMode::Id })] + &[None] }; let mut err = None; - for &(format, ref protocol) in formats { + for &format in formats { let create_srv = || { - let mut process = Process::run(process_path, env.clone(), format)?; - let (stdin, stdout) = process.stdio().expect("couldn't access child stdio"); + let (process, stdin, stdout) = spawn(format)?; io::Result::Ok(ProcMacroServerProcess { state: Mutex::new(ProcessSrvState { process, stdin, stdout }), version: 0, - protocol: protocol.clone(), + protocol: match format { + Some(ProtocolFormat::BidirectionalPostcardPrototype) => { + Protocol::BidirectionalPostcardPrototype { mode: SpanMode::Id } + } + Some(ProtocolFormat::JsonLegacy) | None => { + Protocol::LegacyJson { mode: SpanMode::Id } + } + }, exited: OnceLock::new(), + active: AtomicU32::new(0), }) }; let mut srv = create_srv()?; tracing::info!("sending proc-macro server version check"); - match srv.version_check() { + match srv.version_check(Some(&reject_subrequests)) { Ok(v) if v > version::CURRENT_API_VERSION => { - #[allow(clippy::disallowed_methods)] - let process_version = Command::new(process_path) - .arg("--version") - .output() - .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned()) - .unwrap_or_else(|_| "unknown version".to_owned()); + let process_version = binary_server_version(); err = Some(io::Error::other(format!( "Your installed proc-macro server is too new for your rust-analyzer. API version: {}, server version: {process_version}. \ This will prevent proc-macro expansion from working. Please consider updating your rust-analyzer to ensure compatibility with your current toolchain.", @@ -102,12 +185,12 @@ impl ProcMacroServerProcess { tracing::info!("Proc-macro server version: {v}"); srv.version = v; if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT - && let Ok(new_mode) = srv.enable_rust_analyzer_spans() + && let Ok(new_mode) = + srv.enable_rust_analyzer_spans(Some(&reject_subrequests)) { match &mut srv.protocol { - Protocol::LegacyJson { mode } | Protocol::LegacyPostcard { mode } => { - *mode = new_mode - } + Protocol::LegacyJson { mode } + | Protocol::BidirectionalPostcardPrototype { mode } => *mode = new_mode, } } tracing::info!("Proc-macro server protocol: {:?}", srv.protocol); @@ -124,15 +207,31 @@ impl ProcMacroServerProcess { Err(err.unwrap()) } + /// Finds proc-macros in a given dynamic library. + pub(crate) fn find_proc_macros( + &self, + dylib_path: &AbsPath, + ) -> Result, String>, ServerError> { + match self.protocol { + Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path), + + Protocol::BidirectionalPostcardPrototype { .. } => { + bidirectional_protocol::find_proc_macros(self, dylib_path, &|_| { + Ok(SubResponse::Cancel { + reason: String::from( + "Server should not do a sub request when loading proc-macros", + ), + }) + }) + } + } + } + /// Returns the server error if the process has exited. pub(crate) fn exited(&self) -> Option<&ServerError> { self.exited.get().map(|it| &it.0) } - pub(crate) fn use_postcard(&self) -> bool { - matches!(self.protocol, Protocol::LegacyPostcard { .. }) - } - /// Retrieves the API version of the proc-macro server. pub(crate) fn version(&self) -> u32 { self.version @@ -142,54 +241,90 @@ impl ProcMacroServerProcess { pub(crate) fn rust_analyzer_spans(&self) -> bool { match self.protocol { Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer, - Protocol::LegacyPostcard { mode } => mode == SpanMode::RustAnalyzer, + Protocol::BidirectionalPostcardPrototype { mode } => mode == SpanMode::RustAnalyzer, } } /// Checks the API version of the running proc-macro server. - fn version_check(&self) -> Result { + fn version_check(&self, callback: Option>) -> Result { match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::version_check(self), - Protocol::LegacyPostcard { .. } => legacy_protocol::version_check(self), + Protocol::BidirectionalPostcardPrototype { .. } => { + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::version_check(self, cb) + } } } /// Enable support for rust-analyzer span mode if the server supports it. - fn enable_rust_analyzer_spans(&self) -> Result { + fn enable_rust_analyzer_spans( + &self, + callback: Option>, + ) -> Result { match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::enable_rust_analyzer_spans(self), - Protocol::LegacyPostcard { .. } => legacy_protocol::enable_rust_analyzer_spans(self), + Protocol::BidirectionalPostcardPrototype { .. } => { + let cb = callback.expect("callback required for bidirectional protocol"); + bidirectional_protocol::enable_rust_analyzer_spans(self, cb) + } } } - /// Finds proc-macros in a given dynamic library. - pub(crate) fn find_proc_macros( + pub(crate) fn expand( &self, - dylib_path: &AbsPath, - ) -> Result, String>, ServerError> { - match self.protocol { - Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path), - Protocol::LegacyPostcard { .. } => legacy_protocol::find_proc_macros(self, dylib_path), - } + proc_macro: &ProcMacro, + subtree: tt::SubtreeView<'_>, + attr: Option>, + env: Vec<(String, String)>, + def_site: Span, + call_site: Span, + mixed_site: Span, + current_dir: String, + callback: Option>, + ) -> Result, ServerError> { + self.active.fetch_add(1, Ordering::AcqRel); + let result = match self.protocol { + Protocol::LegacyJson { .. } => legacy_protocol::expand( + proc_macro, + self, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + ), + Protocol::BidirectionalPostcardPrototype { .. } => bidirectional_protocol::expand( + proc_macro, + self, + subtree, + attr, + env, + def_site, + call_site, + mixed_site, + current_dir, + callback.expect("callback required for bidirectional protocol"), + ), + }; + + self.active.fetch_sub(1, Ordering::AcqRel); + result } - pub(crate) fn send_task( + pub(crate) fn send_task_legacy( &self, - serialize_req: impl FnOnce( + send: impl FnOnce( &mut dyn Write, &mut dyn BufRead, Request, - &mut Buf, + &mut String, ) -> Result, ServerError>, req: Request, - ) -> Result - where - Buf: Default, - { - let state = &mut *self.state.lock().unwrap(); - let mut buf = Buf::default(); - serialize_req(&mut state.stdin, &mut state.stdout, req, &mut buf) - .and_then(|res| { + ) -> Result { + self.with_locked_io(String::new(), |writer, reader, buf| { + send(writer, reader, req, buf).and_then(|res| { res.ok_or_else(|| { let message = "proc-macro server did not respond with data".to_owned(); ServerError { @@ -201,33 +336,41 @@ impl ProcMacroServerProcess { } }) }) - .map_err(|e| { - if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) { - match state.process.child.try_wait() { - Ok(None) | Err(_) => e, - Ok(Some(status)) => { - let mut msg = String::new(); - if !status.success() - && let Some(stderr) = state.process.child.stderr.as_mut() - { - _ = stderr.read_to_string(&mut msg); - } - let server_error = ServerError { - message: format!( - "proc-macro server exited with {status}{}{msg}", - if msg.is_empty() { "" } else { ": " } - ), - io: None, - }; - // `AssertUnwindSafe` is fine here, we already correct initialized - // server_error at this point. - self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() - } + }) + } + + fn with_locked_io( + &self, + mut buf: B, + f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut B) -> Result, + ) -> Result { + let state = &mut *self.state.lock().unwrap(); + f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| { + if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) { + match state.process.exit_err() { + None => e, + Some(server_error) => { + self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() } - } else { - e } - }) + } else { + e + } + }) + } + + pub(crate) fn run_bidirectional( + &self, + initial: BidirectionalMessage, + callback: SubCallback<'_>, + ) -> Result { + self.with_locked_io(Vec::new(), |writer, reader, buf| { + bidirectional_protocol::run_conversation(writer, reader, buf, initial, callback) + }) + } + + pub(crate) fn number_of_active_req(&self) -> u32 { + self.active.load(Ordering::Acquire) } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/transport.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport.rs new file mode 100644 index 000000000000..f383edb0cbbb --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport.rs @@ -0,0 +1,3 @@ +//! Contains construct for transport of messages. +pub(crate) mod json; +pub(crate) mod postcard; diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/json.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/json.rs new file mode 100644 index 000000000000..f433bb7de033 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/json.rs @@ -0,0 +1,48 @@ +//! Protocol functions for json. +use std::io::{self, BufRead, Write}; + +use serde::{Serialize, de::DeserializeOwned}; + +pub(crate) fn read<'a, R: BufRead + ?Sized>( + inp: &mut R, + buf: &'a mut String, +) -> io::Result> { + loop { + buf.clear(); + + inp.read_line(buf)?; + buf.pop(); // Remove trailing '\n' + + if buf.is_empty() { + return Ok(None); + } + + // Some ill behaved macro try to use stdout for debugging + // We ignore it here + if !buf.starts_with('{') { + tracing::error!("proc-macro tried to print : {}", buf); + continue; + } + + return Ok(Some(buf)); + } +} + +pub(crate) fn write(out: &mut W, buf: &String) -> io::Result<()> { + tracing::debug!("> {}", buf); + out.write_all(buf.as_bytes())?; + out.write_all(b"\n")?; + out.flush() +} + +pub(crate) fn encode(msg: &T) -> io::Result { + Ok(serde_json::to_string(msg)?) +} + +pub(crate) fn decode(buf: &mut str) -> io::Result { + let mut deserializer = serde_json::Deserializer::from_str(buf); + // Note that some proc-macro generate very deep syntax tree + // We have to disable the current limit of serde here + deserializer.disable_recursion_limit(); + Ok(T::deserialize(&mut deserializer)?) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/postcard.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/postcard.rs new file mode 100644 index 000000000000..75aa90e4c480 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/transport/postcard.rs @@ -0,0 +1,30 @@ +//! Postcard encode and decode implementations. + +use std::io::{self, BufRead, Write}; + +use serde::{Serialize, de::DeserializeOwned}; + +pub(crate) fn read<'a, R: BufRead + ?Sized>( + inp: &mut R, + buf: &'a mut Vec, +) -> io::Result>> { + buf.clear(); + let n = inp.read_until(0, buf)?; + if n == 0 { + return Ok(None); + } + Ok(Some(buf)) +} + +pub(crate) fn write(out: &mut W, buf: &[u8]) -> io::Result<()> { + out.write_all(buf)?; + out.flush() +} + +pub(crate) fn encode(msg: &T) -> io::Result> { + postcard::to_allocvec_cobs(msg).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) +} + +pub(crate) fn decode(buf: &mut [u8]) -> io::Result { + postcard::from_bytes_cobs(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml index aa153897fa96..f586fe7644d7 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml @@ -10,15 +10,28 @@ license.workspace = true rust-version.workspace = true publish = false +[lib] +doctest = false + [dependencies] proc-macro-srv.workspace = true proc-macro-api.workspace = true -tt.workspace = true -postcard.workspace = true clap = {version = "4.5.42", default-features = false, features = ["std"]} +[dev-dependencies] +expect-test.workspace = true +paths.workspace = true +# span = {workspace = true, default-features = false} does not work +span = { path = "../span", default-features = false} +tt.workspace = true +intern.workspace = true + +# used as proc macro test target +proc-macro-test.path = "../proc-macro-srv/proc-macro-test" + [features] default = [] +# default = ["sysroot-abi"] sysroot-abi = ["proc-macro-srv/sysroot-abi", "proc-macro-api/sysroot-abi"] in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"] diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/README.md b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/README.md new file mode 100644 index 000000000000..02a67ac3ecc1 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/README.md @@ -0,0 +1,65 @@ +# proc-macro-srv-cli + +A standalone binary for the `proc-macro-srv` crate that provides procedural macro expansion for rust-analyzer. + +## Overview + +rust-analyzer uses a RPC (via stdio) client-server architecture for procedural macro expansion. This is necessary because: + +1. Proc macros are dynamic libraries that can segfault, bringing down the entire process, so running them out of process allows rust-analyzer to recover from fatal errors. +2. Proc macro dylibs are compiled against a specific rustc version and require matching internal APIs to load and execute, as such having this binary shipped as a rustup component allows us to always match the rustc version irrespective of the rust-analyzer version used. + +## The `sysroot-abi` Feature + +**The `sysroot-abi` feature is required for the binary to actually function.** Without it, the binary will return an error: + +``` +proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function +``` + +This feature is necessary because the proc-macro server needs access to unstable rustc internals (`proc_macro_internals`, `proc_macro_diagnostic`, `proc_macro_span`) which are only available on nightly or with `RUSTC_BOOTSTRAP=1`. +rust-analyzer is a stable toolchain project though, so the feature flag is used to have it remain compilable on stable by default. + +### Building + +```bash +# Using nightly toolchain +cargo build -p proc-macro-srv-cli --features sysroot-abi + +# Or with RUSTC_BOOTSTRAP on stable +RUSTC_BOOTSTRAP=1 cargo build -p proc-macro-srv-cli --features sysroot-abi +``` + +### Installing the proc-macro server + +For local testing purposes, you can install the proc-macro server using the xtask command: + +```bash +# Recommended: use the xtask command +cargo xtask install --proc-macro-server +``` + +## Testing + +```bash +cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api +``` + +The tests use a test proc macro dylib built by the `proc-macro-test` crate, which compiles a small proc macro implementation during build time. + +**Note**: Tests only compile on nightly toolchains (or with `RUSTC_BOOTSTRAP=1`). + +## Usage + +The binary requires the `RUST_ANALYZER_INTERNALS_DO_NOT_USE` environment variable to be set. This is intentional—the binary is an implementation detail of rust-analyzer and its API is still unstable: + +```bash +RUST_ANALYZER_INTERNALS_DO_NOT_USE=1 rust-analyzer-proc-macro-srv --version +``` + +## Related Crates + +- `proc-macro-srv`: The core server library that handles loading dylibs and expanding macros, but not the RPC protocol. +- `proc-macro-api`: The client library used by rust-analyzer to communicate with this server as well as the protocol definitions. +- `proc-macro-test`: Test harness with sample proc macros for testing +- `proc-macro-srv-cli`: The actual server binary that handles the RPC protocol. diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/lib.rs new file mode 100644 index 000000000000..8475c05ae8a1 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/lib.rs @@ -0,0 +1,11 @@ +//! Library interface for `proc-macro-srv-cli`. +//! +//! This module exposes the server main loop and protocol format for integration testing. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + +#[cfg(feature = "sysroot-abi")] +pub mod main_loop; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs index 813ac339a91d..928753659f1c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs @@ -9,11 +9,11 @@ extern crate rustc_driver as _; mod version; -#[cfg(feature = "sysroot-abi")] -mod main_loop; use clap::{Command, ValueEnum}; +use proc_macro_api::ProtocolFormat; + #[cfg(feature = "sysroot-abi")] -use main_loop::run; +use proc_macro_srv_cli::main_loop::run; fn main() -> std::io::Result<()> { let v = std::env::var("RUST_ANALYZER_INTERNALS_DO_NOT_USE"); @@ -32,7 +32,7 @@ fn main() -> std::io::Result<()> { .long("format") .action(clap::ArgAction::Set) .default_value("json-legacy") - .value_parser(clap::builder::EnumValueParser::::new()), + .value_parser(clap::builder::EnumValueParser::::new()), clap::Arg::new("version") .long("version") .action(clap::ArgAction::SetTrue) @@ -43,41 +43,60 @@ fn main() -> std::io::Result<()> { println!("rust-analyzer-proc-macro-srv {}", version::version()); return Ok(()); } - let &format = - matches.get_one::("format").expect("format value should always be present"); - run(format) + let &format = matches + .get_one::("format") + .expect("format value should always be present"); + + let mut stdin = std::io::BufReader::new(std::io::stdin()); + let mut stdout = std::io::stdout(); + + run(&mut stdin, &mut stdout, format.into()) } +/// Wrapper for CLI argument parsing that implements `ValueEnum`. #[derive(Copy, Clone)] -enum ProtocolFormat { - JsonLegacy, - PostcardLegacy, +struct ProtocolFormatArg(ProtocolFormat); + +impl From for ProtocolFormat { + fn from(arg: ProtocolFormatArg) -> Self { + arg.0 + } } -impl ValueEnum for ProtocolFormat { +impl ValueEnum for ProtocolFormatArg { fn value_variants<'a>() -> &'a [Self] { - &[ProtocolFormat::JsonLegacy, ProtocolFormat::PostcardLegacy] + &[ + ProtocolFormatArg(ProtocolFormat::JsonLegacy), + ProtocolFormatArg(ProtocolFormat::BidirectionalPostcardPrototype), + ] } fn to_possible_value(&self) -> Option { - match self { + match self.0 { ProtocolFormat::JsonLegacy => Some(clap::builder::PossibleValue::new("json-legacy")), - ProtocolFormat::PostcardLegacy => { - Some(clap::builder::PossibleValue::new("postcard-legacy")) + ProtocolFormat::BidirectionalPostcardPrototype => { + Some(clap::builder::PossibleValue::new("bidirectional-postcard-prototype")) } } } + fn from_str(input: &str, _ignore_case: bool) -> Result { match input { - "json-legacy" => Ok(ProtocolFormat::JsonLegacy), - "postcard-legacy" => Ok(ProtocolFormat::PostcardLegacy), + "json-legacy" => Ok(ProtocolFormatArg(ProtocolFormat::JsonLegacy)), + "bidirectional-postcard-prototype" => { + Ok(ProtocolFormatArg(ProtocolFormat::BidirectionalPostcardPrototype)) + } _ => Err(format!("unknown protocol format: {input}")), } } } #[cfg(not(feature = "sysroot-abi"))] -fn run(_: ProtocolFormat) -> std::io::Result<()> { +fn run( + _: &mut std::io::BufReader, + _: &mut std::io::Stdout, + _: ProtocolFormat, +) -> std::io::Result<()> { Err(std::io::Error::new( std::io::ErrorKind::Unsupported, "proc-macro-srv-cli needs to be compiled with the `sysroot-abi` feature to function" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index df54f38cbccb..9be3199a3836 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs @@ -1,24 +1,21 @@ //! The main loop of the proc-macro server. -use std::io; - use proc_macro_api::{ - Codec, - legacy_protocol::{ - json::JsonProtocol, - msg::{ - self, ExpandMacroData, ExpnGlobals, Message, SpanMode, SpanTransformer, - deserialize_span_data_index_map, serialize_span_data_index_map, - }, - postcard::PostcardProtocol, - }, + ProtocolFormat, bidirectional_protocol::msg as bidirectional, legacy_protocol::msg as legacy, version::CURRENT_API_VERSION, }; -use proc_macro_srv::{EnvSnapshot, SpanId}; +use std::panic::{panic_any, resume_unwind}; +use std::{ + io::{self, BufRead, Write}, + ops::Range, +}; + +use legacy::Message; + +use proc_macro_srv::{EnvSnapshot, ProcMacroClientError, ProcMacroPanicMarker, SpanId}; -use crate::ProtocolFormat; struct SpanTrans; -impl SpanTransformer for SpanTrans { +impl legacy::SpanTransformer for SpanTrans { type Table = (); type Span = SpanId; fn token_id_of( @@ -35,14 +32,21 @@ impl SpanTransformer for SpanTrans { } } -pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> { +pub fn run( + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), + format: ProtocolFormat, +) -> io::Result<()> { match format { - ProtocolFormat::JsonLegacy => run_::(), - ProtocolFormat::PostcardLegacy => run_::(), + ProtocolFormat::JsonLegacy => run_old(stdin, stdout), + ProtocolFormat::BidirectionalPostcardPrototype => run_new(stdin, stdout), } } -fn run_() -> io::Result<()> { +fn run_new( + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), +) -> io::Result<()> { fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { match kind { proc_macro_srv::ProcMacroKind::CustomDerive => { @@ -53,39 +57,339 @@ fn run_() -> io::Result<()> { } } - let mut buf = C::Buf::default(); - let mut read_request = || msg::Request::read::<_, C>(&mut io::stdin().lock(), &mut buf); - let write_response = |msg: msg::Response| msg.write::<_, C>(&mut io::stdout().lock()); + let mut buf = Vec::default(); + + let env_snapshot = EnvSnapshot::default(); + let srv = proc_macro_srv::ProcMacroSrv::new(&env_snapshot); + + let mut span_mode = legacy::SpanMode::Id; + + 'outer: loop { + let req_opt = bidirectional::BidirectionalMessage::read(stdin, &mut buf)?; + let Some(req) = req_opt else { + break 'outer; + }; + + match req { + bidirectional::BidirectionalMessage::Request(request) => match request { + bidirectional::Request::ListMacros { dylib_path } => { + let res = srv.list_macros(&dylib_path).map(|macros| { + macros + .into_iter() + .map(|(name, kind)| (name, macro_kind_to_api(kind))) + .collect() + }); + + send_response(stdout, bidirectional::Response::ListMacros(res))?; + } + + bidirectional::Request::ApiVersionCheck {} => { + send_response( + stdout, + bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), + )?; + } + + bidirectional::Request::SetConfig(config) => { + span_mode = config.span_mode; + send_response(stdout, bidirectional::Response::SetConfig(config))?; + } + bidirectional::Request::ExpandMacro(task) => { + handle_expand(&srv, stdin, stdout, &mut buf, span_mode, *task)?; + } + }, + _ => continue, + } + } + + Ok(()) +} + +fn handle_expand( + srv: &proc_macro_srv::ProcMacroSrv<'_>, + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), + buf: &mut Vec, + span_mode: legacy::SpanMode, + task: bidirectional::ExpandMacro, +) -> io::Result<()> { + match span_mode { + legacy::SpanMode::Id => handle_expand_id(srv, stdout, task), + legacy::SpanMode::RustAnalyzer => handle_expand_ra(srv, stdin, stdout, buf, task), + } +} + +fn handle_expand_id( + srv: &proc_macro_srv::ProcMacroSrv<'_>, + stdout: &mut dyn Write, + task: bidirectional::ExpandMacro, +) -> io::Result<()> { + let bidirectional::ExpandMacro { lib, env, current_dir, data } = task; + let bidirectional::ExpandMacroData { + macro_body, + macro_name, + attributes, + has_global_spans: bidirectional::ExpnGlobals { def_site, call_site, mixed_site, .. }, + .. + } = data; + + let def_site = SpanId(def_site as u32); + let call_site = SpanId(call_site as u32); + let mixed_site = SpanId(mixed_site as u32); + + let macro_body = + macro_body.to_tokenstream_unresolved::(CURRENT_API_VERSION, |_, b| b); + let attributes = attributes + .map(|it| it.to_tokenstream_unresolved::(CURRENT_API_VERSION, |_, b| b)); + + let res = srv + .expand( + lib, + &env, + current_dir, + ¯o_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + None, + ) + .map(|it| { + legacy::FlatTree::from_tokenstream_raw::(it, call_site, CURRENT_API_VERSION) + }) + .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); + + send_response(stdout, bidirectional::Response::ExpandMacro(res)) +} + +struct ProcMacroClientHandle<'a> { + stdin: &'a mut (dyn BufRead + Send + Sync), + stdout: &'a mut (dyn Write + Send + Sync), + buf: &'a mut Vec, +} + +impl<'a> ProcMacroClientHandle<'a> { + fn roundtrip( + &mut self, + req: bidirectional::SubRequest, + ) -> Result { + let msg = bidirectional::BidirectionalMessage::SubRequest(req); + + msg.write(&mut *self.stdout).map_err(ProcMacroClientError::Io)?; + + let msg = bidirectional::BidirectionalMessage::read(&mut *self.stdin, self.buf) + .map_err(ProcMacroClientError::Io)? + .ok_or(ProcMacroClientError::Eof)?; + + match msg { + bidirectional::BidirectionalMessage::SubResponse(resp) => match resp { + bidirectional::SubResponse::Cancel { reason } => { + Err(ProcMacroClientError::Cancelled { reason }) + } + other => Ok(other), + }, + other => { + Err(ProcMacroClientError::Protocol(format!("expected SubResponse, got {other:?}"))) + } + } + } +} + +fn handle_failure(failure: Result) -> ! { + match failure { + Err(ProcMacroClientError::Cancelled { reason }) => { + resume_unwind(Box::new(ProcMacroPanicMarker::Cancelled { reason })); + } + Err(err) => { + panic_any(ProcMacroPanicMarker::Internal { + reason: format!("proc-macro IPC error: {err:?}"), + }); + } + Ok(other) => { + panic_any(ProcMacroPanicMarker::Internal { + reason: format!("unexpected SubResponse {other:?}"), + }); + } + } +} + +impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { + fn file(&mut self, file_id: proc_macro_srv::span::FileId) -> String { + match self.roundtrip(bidirectional::SubRequest::FilePath { file_id: file_id.index() }) { + Ok(bidirectional::SubResponse::FilePathResult { name }) => name, + other => handle_failure(other), + } + } + + fn source_text( + &mut self, + proc_macro_srv::span::Span { range, anchor, ctx: _ }: proc_macro_srv::span::Span, + ) -> Option { + match self.roundtrip(bidirectional::SubRequest::SourceText { + file_id: anchor.file_id.as_u32(), + ast_id: anchor.ast_id.into_raw(), + start: range.start().into(), + end: range.end().into(), + }) { + Ok(bidirectional::SubResponse::SourceTextResult { text }) => text, + other => handle_failure(other), + } + } + + fn local_file(&mut self, file_id: proc_macro_srv::span::FileId) -> Option { + match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id: file_id.index() }) + { + Ok(bidirectional::SubResponse::LocalFilePathResult { name }) => name, + other => handle_failure(other), + } + } + + fn line_column(&mut self, span: proc_macro_srv::span::Span) -> Option<(u32, u32)> { + let proc_macro_srv::span::Span { range, anchor, ctx: _ } = span; + match self.roundtrip(bidirectional::SubRequest::LineColumn { + file_id: anchor.file_id.as_u32(), + ast_id: anchor.ast_id.into_raw(), + offset: range.start().into(), + }) { + Ok(bidirectional::SubResponse::LineColumnResult { line, column }) => { + Some((line, column)) + } + other => handle_failure(other), + } + } + + fn byte_range( + &mut self, + proc_macro_srv::span::Span { range, anchor, ctx: _ }: proc_macro_srv::span::Span, + ) -> Range { + match self.roundtrip(bidirectional::SubRequest::ByteRange { + file_id: anchor.file_id.as_u32(), + ast_id: anchor.ast_id.into_raw(), + start: range.start().into(), + end: range.end().into(), + }) { + Ok(bidirectional::SubResponse::ByteRangeResult { range }) => range, + other => handle_failure(other), + } + } +} + +fn handle_expand_ra( + srv: &proc_macro_srv::ProcMacroSrv<'_>, + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), + buf: &mut Vec, + task: bidirectional::ExpandMacro, +) -> io::Result<()> { + let bidirectional::ExpandMacro { + lib, + env, + current_dir, + data: + bidirectional::ExpandMacroData { + macro_body, + macro_name, + attributes, + has_global_spans: bidirectional::ExpnGlobals { def_site, call_site, mixed_site, .. }, + span_data_table, + }, + } = task; + + let mut span_data_table = legacy::deserialize_span_data_index_map(&span_data_table); + + let def_site = span_data_table[def_site]; + let call_site = span_data_table[call_site]; + let mixed_site = span_data_table[mixed_site]; + + let macro_body = + macro_body.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { + srv.join_spans(a, b).unwrap_or(b) + }); + + let attributes = attributes.map(|it| { + it.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { + srv.join_spans(a, b).unwrap_or(b) + }) + }); + + let res = srv + .expand( + lib, + &env, + current_dir, + ¯o_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + Some(&mut ProcMacroClientHandle { stdin, stdout, buf }), + ) + .map(|it| { + ( + legacy::FlatTree::from_tokenstream( + it, + CURRENT_API_VERSION, + call_site, + &mut span_data_table, + ), + legacy::serialize_span_data_index_map(&span_data_table), + ) + }) + .map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { tree, span_data_table }) + .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); + + send_response(stdout, bidirectional::Response::ExpandMacroExtended(res)) +} + +fn run_old( + stdin: &mut (dyn BufRead + Send + Sync), + stdout: &mut (dyn Write + Send + Sync), +) -> io::Result<()> { + fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { + match kind { + proc_macro_srv::ProcMacroKind::CustomDerive => { + proc_macro_api::ProcMacroKind::CustomDerive + } + proc_macro_srv::ProcMacroKind::Bang => proc_macro_api::ProcMacroKind::Bang, + proc_macro_srv::ProcMacroKind::Attr => proc_macro_api::ProcMacroKind::Attr, + } + } + + let mut buf = String::default(); + let mut read_request = || legacy::Request::read(stdin, &mut buf); + let mut write_response = |msg: legacy::Response| msg.write(stdout); let env = EnvSnapshot::default(); let srv = proc_macro_srv::ProcMacroSrv::new(&env); - let mut span_mode = SpanMode::Id; + let mut span_mode = legacy::SpanMode::Id; while let Some(req) = read_request()? { let res = match req { - msg::Request::ListMacros { dylib_path } => { - msg::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| { + legacy::Request::ListMacros { dylib_path } => { + legacy::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| { macros.into_iter().map(|(name, kind)| (name, macro_kind_to_api(kind))).collect() })) } - msg::Request::ExpandMacro(task) => { - let msg::ExpandMacro { + legacy::Request::ExpandMacro(task) => { + let legacy::ExpandMacro { lib, env, current_dir, data: - ExpandMacroData { + legacy::ExpandMacroData { macro_body, macro_name, attributes, has_global_spans: - ExpnGlobals { serialize: _, def_site, call_site, mixed_site }, + legacy::ExpnGlobals { serialize: _, def_site, call_site, mixed_site }, span_data_table, }, } = *task; match span_mode { - SpanMode::Id => msg::Response::ExpandMacro({ + legacy::SpanMode::Id => legacy::Response::ExpandMacro({ let def_site = SpanId(def_site as u32); let call_site = SpanId(call_site as u32); let mixed_site = SpanId(mixed_site as u32); @@ -106,19 +410,21 @@ fn run_() -> io::Result<()> { def_site, call_site, mixed_site, + None, ) .map(|it| { - msg::FlatTree::from_tokenstream_raw::( + legacy::FlatTree::from_tokenstream_raw::( it, call_site, CURRENT_API_VERSION, ) }) .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(msg::PanicMessage) + .map_err(legacy::PanicMessage) }), - SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({ - let mut span_data_table = deserialize_span_data_index_map(&span_data_table); + legacy::SpanMode::RustAnalyzer => legacy::Response::ExpandMacroExtended({ + let mut span_data_table = + legacy::deserialize_span_data_index_map(&span_data_table); let def_site = span_data_table[def_site]; let call_site = span_data_table[call_site]; @@ -146,31 +452,34 @@ fn run_() -> io::Result<()> { def_site, call_site, mixed_site, + None, ) .map(|it| { ( - msg::FlatTree::from_tokenstream( + legacy::FlatTree::from_tokenstream( it, CURRENT_API_VERSION, call_site, &mut span_data_table, ), - serialize_span_data_index_map(&span_data_table), + legacy::serialize_span_data_index_map(&span_data_table), ) }) - .map(|(tree, span_data_table)| msg::ExpandMacroExtended { + .map(|(tree, span_data_table)| legacy::ExpandMacroExtended { tree, span_data_table, }) .map_err(|e| e.into_string().unwrap_or_default()) - .map_err(msg::PanicMessage) + .map_err(legacy::PanicMessage) }), } } - msg::Request::ApiVersionCheck {} => msg::Response::ApiVersionCheck(CURRENT_API_VERSION), - msg::Request::SetConfig(config) => { + legacy::Request::ApiVersionCheck {} => { + legacy::Response::ApiVersionCheck(CURRENT_API_VERSION) + } + legacy::Request::SetConfig(config) => { span_mode = config.span_mode; - msg::Response::SetConfig(config) + legacy::Response::SetConfig(config) } }; write_response(res)? @@ -178,3 +487,8 @@ fn run_() -> io::Result<()> { Ok(()) } + +fn send_response(stdout: &mut dyn Write, resp: bidirectional::Response) -> io::Result<()> { + let resp = bidirectional::BidirectionalMessage::Response(resp); + resp.write(stdout) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs new file mode 100644 index 000000000000..ba9657a9bb45 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/bidirectional_postcard.rs @@ -0,0 +1,229 @@ +#![cfg(feature = "sysroot-abi")] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + +mod common { + pub(crate) mod utils; +} + +use common::utils::{ + create_empty_token_tree, proc_macro_test_dylib_path, request_bidirectional, with_server, +}; +use expect_test::expect; +use proc_macro_api::{ + ProtocolFormat::BidirectionalPostcardPrototype, + bidirectional_protocol::{ + msg::{ExpandMacro, ExpandMacroData, ExpnGlobals, Request, Response}, + reject_subrequests, + }, + legacy_protocol::msg::{PanicMessage, ServerConfig, SpanDataIndexMap, SpanMode}, + version::CURRENT_API_VERSION, +}; + +#[test] +fn test_bidi_version_check_bidirectional() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let response = + request_bidirectional(writer, reader, Request::ApiVersionCheck {}, reject_subrequests); + + match response { + Response::ApiVersionCheck(version) => { + assert_eq!(version, CURRENT_API_VERSION); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_list_macros() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + let response = request_bidirectional( + writer, + reader, + Request::ListMacros { dylib_path }, + &reject_subrequests, + ); + + let Response::ListMacros(Ok(macros)) = response else { + panic!("expected successful ListMacros response"); + }; + + let mut macro_list: Vec<_> = + macros.iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect(); + macro_list.sort(); + let macro_list_str = macro_list.join("\n"); + + expect![[r#" + DeriveEmpty [CustomDerive] + DeriveError [CustomDerive] + DerivePanic [CustomDerive] + DeriveReemit [CustomDerive] + attr_error [Attr] + attr_noop [Attr] + attr_panic [Attr] + fn_like_clone_tokens [Bang] + fn_like_error [Bang] + fn_like_mk_idents [Bang] + fn_like_mk_literals [Bang] + fn_like_noop [Bang] + fn_like_panic [Bang] + fn_like_span_join [Bang] + fn_like_span_line_column [Bang] + fn_like_span_ops [Bang]"#]] + .assert_eq(¯o_list_str); + }); +} + +#[test] +fn test_bidi_list_macros_invalid_path() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let response = request_bidirectional( + writer, + reader, + Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, + reject_subrequests, + ); + + match response { + Response::ListMacros(Err(e)) => assert!( + e.starts_with("Cannot create expander for /nonexistent/path/to/dylib.so"), + "{e}" + ), + other => panic!("expected error response, got: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_set_config() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::Id }; + let response = + request_bidirectional(writer, reader, Request::SetConfig(config), reject_subrequests); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::Id); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_set_config_rust_analyzer_mode() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; + let response = + request_bidirectional(writer, reader, Request::SetConfig(config), reject_subrequests); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::RustAnalyzer); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_expand_macro_panic() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = + common::utils::create_empty_token_tree(CURRENT_API_VERSION, &mut span_data_table); + + let request1 = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "fn_like_panic".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { def_site: 0, call_site: 0, mixed_site: 0 }, + span_data_table: vec![], + }, + })); + + let response = request_bidirectional(writer, reader, request1, reject_subrequests); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + assert!(msg.contains("fn_like_panic"), "panic message should mention macro name"); + } + other => panic!("expected panic response, got: {other:?}"), + } + }); +} + +#[test] +fn test_bidi_basic_call_flow() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let response1 = + request_bidirectional(writer, reader, Request::ApiVersionCheck {}, reject_subrequests); + assert!(matches!(response1, Response::ApiVersionCheck(_))); + + let response2 = request_bidirectional( + writer, + reader, + Request::SetConfig(ServerConfig { span_mode: SpanMode::Id }), + reject_subrequests, + ); + assert!(matches!(response2, Response::SetConfig(_))); + + let response3 = request_bidirectional( + writer, + reader, + Request::ListMacros { dylib_path: dylib_path.clone() }, + reject_subrequests, + ); + assert!(matches!(response3, Response::ListMacros(Ok(_)))); + }); +} + +#[test] +fn test_bidi_expand_nonexistent_macro() { + with_server(BidirectionalPostcardPrototype, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = + request_bidirectional(writer, reader, Request::ApiVersionCheck {}, reject_subrequests); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "NonexistentMacro".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { def_site: 0, call_site: 0, mixed_site: 0 }, + span_data_table: vec![], + }, + })); + + let response = request_bidirectional(writer, reader, expand_request, reject_subrequests); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + expect!["proc-macro `NonexistentMacro` is missing"].assert_eq(&msg) + } + other => panic!("expected error for nonexistent macro, got: {other:?}"), + } + }); +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs new file mode 100644 index 000000000000..3049e9800405 --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/common/utils.rs @@ -0,0 +1,288 @@ +use std::{ + collections::VecDeque, + io::{self, BufRead, Read, Write}, + sync::{Arc, Condvar, Mutex}, + thread, +}; + +use paths::Utf8PathBuf; +use proc_macro_api::{ + ServerError, + bidirectional_protocol::msg::{ + BidirectionalMessage, Request as BiRequest, Response as BiResponse, SubRequest, SubResponse, + }, + legacy_protocol::msg::{FlatTree, Message, Request, Response, SpanDataIndexMap}, +}; +use span::{Edition, EditionedFileId, FileId, Span, SpanAnchor, SyntaxContext, TextRange}; +use tt::{Delimiter, DelimiterKind, TopSubtreeBuilder}; + +/// Shared state for an in-memory byte channel. +#[derive(Default)] +struct ChannelState { + buffer: VecDeque, + closed: bool, +} + +type InMemoryChannel = Arc<(Mutex, Condvar)>; + +/// Writer end of an in-memory channel. +pub(crate) struct ChannelWriter { + state: InMemoryChannel, +} + +impl Write for ChannelWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + if state.closed { + return Err(io::Error::new(io::ErrorKind::BrokenPipe, "channel closed")); + } + state.buffer.extend(buf); + cvar.notify_all(); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl Drop for ChannelWriter { + fn drop(&mut self) { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + state.closed = true; + cvar.notify_all(); + } +} + +/// Reader end of an in-memory channel. +pub(crate) struct ChannelReader { + state: InMemoryChannel, + internal_buf: Vec, +} + +impl Read for ChannelReader { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + + while state.buffer.is_empty() && !state.closed { + state = cvar.wait(state).unwrap(); + } + + if state.buffer.is_empty() && state.closed { + return Ok(0); + } + + let to_read = buf.len().min(state.buffer.len()); + for (dst, src) in buf.iter_mut().zip(state.buffer.drain(..to_read)) { + *dst = src; + } + Ok(to_read) + } +} + +impl BufRead for ChannelReader { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + let (lock, cvar) = &*self.state; + let mut state = lock.lock().unwrap(); + + while state.buffer.is_empty() && !state.closed { + state = cvar.wait(state).unwrap(); + } + + self.internal_buf.clear(); + self.internal_buf.extend(&state.buffer); + Ok(&self.internal_buf) + } + + fn consume(&mut self, amt: usize) { + let (lock, _) = &*self.state; + let mut state = lock.lock().unwrap(); + let to_drain = amt.min(state.buffer.len()); + drop(state.buffer.drain(..to_drain)); + } +} + +/// Creates a connected pair of channels for bidirectional communication. +fn create_channel_pair() -> (ChannelWriter, ChannelReader, ChannelWriter, ChannelReader) { + // Channel for client -> server communication + let client_to_server = Arc::new(( + Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), + Condvar::new(), + )); + let client_writer = ChannelWriter { state: client_to_server.clone() }; + let server_reader = ChannelReader { state: client_to_server, internal_buf: Vec::new() }; + + // Channel for server -> client communication + let server_to_client = Arc::new(( + Mutex::new(ChannelState { buffer: VecDeque::new(), closed: false }), + Condvar::new(), + )); + + let server_writer = ChannelWriter { state: server_to_client.clone() }; + let client_reader = ChannelReader { state: server_to_client, internal_buf: Vec::new() }; + + (client_writer, client_reader, server_writer, server_reader) +} + +pub(crate) fn proc_macro_test_dylib_path() -> Utf8PathBuf { + let path = proc_macro_test::PROC_MACRO_TEST_LOCATION; + if path.is_empty() { + panic!("proc-macro-test dylib not available (requires nightly toolchain)"); + } + path.into() +} + +/// Creates a simple empty token tree suitable for testing. +pub(crate) fn create_empty_token_tree( + version: u32, + span_data_table: &mut SpanDataIndexMap, +) -> FlatTree { + let anchor = SpanAnchor { + file_id: EditionedFileId::new(FileId::from_raw(0), Edition::CURRENT), + ast_id: span::ROOT_ERASED_FILE_AST_ID, + }; + let span = Span { + range: TextRange::empty(0.into()), + anchor, + ctx: SyntaxContext::root(Edition::CURRENT), + }; + + let builder = TopSubtreeBuilder::new(Delimiter { + open: span, + close: span, + kind: DelimiterKind::Invisible, + }); + let tt = builder.build(); + + FlatTree::from_subtree(tt.view(), version, span_data_table) +} + +pub(crate) fn with_server(format: proc_macro_api::ProtocolFormat, test_fn: F) -> R +where + F: FnOnce(&mut dyn Write, &mut dyn BufRead) -> R, +{ + let (mut client_writer, mut client_reader, mut server_writer, mut server_reader) = + create_channel_pair(); + + let server_handle = thread::spawn(move || { + proc_macro_srv_cli::main_loop::run(&mut server_reader, &mut server_writer, format) + }); + + let result = test_fn(&mut client_writer, &mut client_reader); + + drop(client_writer); + + match server_handle.join() { + Ok(Ok(())) => {} + Ok(Err(e)) => { + if !matches!( + e.kind(), + io::ErrorKind::BrokenPipe + | io::ErrorKind::UnexpectedEof + | io::ErrorKind::InvalidData + ) { + panic!("Server error: {e}"); + } + } + Err(e) => std::panic::resume_unwind(e), + } + + result +} + +trait TestProtocol { + type Request; + type Response; + + fn request(&self, writer: &mut dyn Write, req: Self::Request); + fn receive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> Self::Response; +} + +#[allow(dead_code)] +struct JsonLegacy; + +impl TestProtocol for JsonLegacy { + type Request = Request; + type Response = Response; + + fn request(&self, writer: &mut dyn Write, req: Request) { + req.write(writer).expect("failed to write request"); + } + + fn receive(&self, reader: &mut dyn BufRead, _writer: &mut dyn Write) -> Response { + let mut buf = String::new(); + Response::read(reader, &mut buf) + .expect("failed to read response") + .expect("no response received") + } +} + +#[allow(dead_code)] +struct PostcardBidirectional +where + F: Fn(SubRequest) -> Result, +{ + callback: F, +} + +impl TestProtocol for PostcardBidirectional +where + F: Fn(SubRequest) -> Result, +{ + type Request = BiRequest; + type Response = BiResponse; + + fn request(&self, writer: &mut dyn Write, req: BiRequest) { + let msg = BidirectionalMessage::Request(req); + msg.write(writer).expect("failed to write request"); + } + + fn receive(&self, reader: &mut dyn BufRead, writer: &mut dyn Write) -> BiResponse { + let mut buf = Vec::new(); + + loop { + let msg = BidirectionalMessage::read(reader, &mut buf) + .expect("failed to read message") + .expect("no message received"); + + match msg { + BidirectionalMessage::Response(resp) => return resp, + BidirectionalMessage::SubRequest(sr) => { + let reply = (self.callback)(sr).expect("subrequest callback failed"); + let msg = BidirectionalMessage::SubResponse(reply); + msg.write(writer).expect("failed to write subresponse"); + } + other => panic!("unexpected message: {other:?}"), + } + } + } +} + +#[allow(dead_code)] +pub(crate) fn request_legacy( + writer: &mut dyn Write, + reader: &mut dyn BufRead, + request: Request, +) -> Response { + let protocol = JsonLegacy; + protocol.request(writer, request); + protocol.receive(reader, writer) +} + +#[allow(dead_code)] +pub(crate) fn request_bidirectional( + writer: &mut dyn Write, + reader: &mut dyn BufRead, + request: BiRequest, + callback: F, +) -> BiResponse +where + F: Fn(SubRequest) -> Result, +{ + let protocol = PostcardBidirectional { callback }; + protocol.request(writer, request); + protocol.receive(reader, writer) +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs new file mode 100644 index 000000000000..562cf0c2516f --- /dev/null +++ b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/tests/legacy_json.rs @@ -0,0 +1,234 @@ +//! Integration tests for the proc-macro-srv-cli main loop. +//! +//! These tests exercise the full client-server RPC procedure using in-memory +//! channels without needing to spawn the actual server and client processes. + +#![cfg(feature = "sysroot-abi")] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + +mod common { + pub(crate) mod utils; +} + +use common::utils::{ + create_empty_token_tree, proc_macro_test_dylib_path, request_legacy, with_server, +}; +use expect_test::expect; +use proc_macro_api::{ + ProtocolFormat::JsonLegacy, + legacy_protocol::msg::{ + ExpandMacro, ExpandMacroData, ExpnGlobals, PanicMessage, Request, Response, ServerConfig, + SpanDataIndexMap, SpanMode, + }, + version::CURRENT_API_VERSION, +}; + +#[test] +fn test_version_check() { + with_server(JsonLegacy, |writer, reader| { + let response = request_legacy(writer, reader, Request::ApiVersionCheck {}); + + match response { + Response::ApiVersionCheck(version) => { + assert_eq!(version, CURRENT_API_VERSION); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_list_macros() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + let response = request_legacy(writer, reader, Request::ListMacros { dylib_path }); + + let Response::ListMacros(Ok(macros)) = response else { + panic!("expected successful ListMacros response"); + }; + + let mut macro_list: Vec<_> = + macros.iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect(); + macro_list.sort(); + let macro_list_str = macro_list.join("\n"); + + expect![[r#" + DeriveEmpty [CustomDerive] + DeriveError [CustomDerive] + DerivePanic [CustomDerive] + DeriveReemit [CustomDerive] + attr_error [Attr] + attr_noop [Attr] + attr_panic [Attr] + fn_like_clone_tokens [Bang] + fn_like_error [Bang] + fn_like_mk_idents [Bang] + fn_like_mk_literals [Bang] + fn_like_noop [Bang] + fn_like_panic [Bang] + fn_like_span_join [Bang] + fn_like_span_line_column [Bang] + fn_like_span_ops [Bang]"#]] + .assert_eq(¯o_list_str); + }); +} + +#[test] +fn test_list_macros_invalid_path() { + with_server(JsonLegacy, |writer, reader| { + let response = request_legacy( + writer, + reader, + Request::ListMacros { dylib_path: "/nonexistent/path/to/dylib.so".into() }, + ); + + match response { + Response::ListMacros(Err(e)) => assert!( + e.starts_with("Cannot create expander for /nonexistent/path/to/dylib.so"), + "{e}" + ), + other => panic!("expected error response, got: {other:?}"), + } + }); +} + +#[test] +fn test_set_config() { + with_server(JsonLegacy, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::Id }; + let response = request_legacy(writer, reader, Request::SetConfig(config)); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::Id); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_set_config_rust_analyzer_mode() { + with_server(JsonLegacy, |writer, reader| { + let config = ServerConfig { span_mode: SpanMode::RustAnalyzer }; + let response = request_legacy(writer, reader, Request::SetConfig(config)); + + match response { + Response::SetConfig(returned_config) => { + assert_eq!(returned_config.span_mode, SpanMode::RustAnalyzer); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_expand_macro_panic() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = request_legacy(writer, reader, Request::ApiVersionCheck {}); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "fn_like_panic".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { + serialize: version >= 3, + def_site: 0, + call_site: 0, + mixed_site: 0, + }, + span_data_table: vec![], + }, + })); + + let response = request_legacy(writer, reader, expand_request); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + assert!(msg.contains("fn_like_panic"), "panic message should mention the macro"); + } + Response::ExpandMacro(Ok(_)) => { + panic!("expected panic, but macro succeeded"); + } + other => panic!("unexpected response: {other:?}"), + } + }); +} + +#[test] +fn test_basic_call_flow() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let response1 = request_legacy(writer, reader, Request::ApiVersionCheck {}); + assert!(matches!(response1, Response::ApiVersionCheck(_))); + + let response2 = request_legacy( + writer, + reader, + Request::SetConfig(ServerConfig { span_mode: SpanMode::Id }), + ); + assert!(matches!(response2, Response::SetConfig(_))); + + let response3 = + request_legacy(writer, reader, Request::ListMacros { dylib_path: dylib_path.clone() }); + assert!(matches!(response3, Response::ListMacros(Ok(_)))); + }); +} + +#[test] +fn test_expand_nonexistent_macro() { + with_server(JsonLegacy, |writer, reader| { + let dylib_path = proc_macro_test_dylib_path(); + + let version_response = request_legacy(writer, reader, Request::ApiVersionCheck {}); + let Response::ApiVersionCheck(version) = version_response else { + panic!("expected version check response"); + }; + + let mut span_data_table = SpanDataIndexMap::default(); + let macro_body = create_empty_token_tree(version, &mut span_data_table); + + let expand_request = Request::ExpandMacro(Box::new(ExpandMacro { + lib: dylib_path, + env: vec![], + current_dir: None, + data: ExpandMacroData { + macro_body, + macro_name: "NonexistentMacro".to_owned(), + attributes: None, + has_global_spans: ExpnGlobals { + serialize: version >= 3, + def_site: 0, + call_site: 0, + mixed_site: 0, + }, + span_data_table: vec![], + }, + })); + + let response = request_legacy(writer, reader, expand_request); + + match response { + Response::ExpandMacro(Err(PanicMessage(msg))) => { + expect!["proc-macro `NonexistentMacro` is missing"].assert_eq(&msg) + } + other => panic!("expected error for nonexistent macro, got: {other:?}"), + } + }); +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index 361017178409..8e5617f8a20e 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -31,6 +31,7 @@ libc.workspace = true [dev-dependencies] expect-test.workspace = true +line-index.workspace = true # used as proc macro test targets proc-macro-test.path = "./proc-macro-test" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs index b4fac26d6e72..06c76b6d0381 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs @@ -79,6 +79,16 @@ pub fn fn_like_span_ops(args: TokenStream) -> TokenStream { TokenStream::from_iter(vec![first, second, third]) } +/// Returns the line and column of the first token's span as two integer literals. +#[proc_macro] +pub fn fn_like_span_line_column(args: TokenStream) -> TokenStream { + let first = args.into_iter().next().unwrap(); + let span = first.span(); + let line = Literal::usize_unsuffixed(span.line()); + let column = Literal::usize_unsuffixed(span.column()); + TokenStream::from_iter(vec![TokenTree::Literal(line), TokenTree::Literal(column)]) +} + #[proc_macro_attribute] pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream { item diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs index fc063a07b5f8..fc62f9413a34 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/bridge.rs @@ -1,6 +1,6 @@ //! `proc_macro::bridge` newtypes. -use proc_macro::bridge as pm_bridge; +use rustc_proc_macro::bridge as pm_bridge; pub use pm_bridge::{DelimSpan, Diagnostic, ExpnGlobals, LitKind}; diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs index 03433197b779..9a65538675fe 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs @@ -3,7 +3,7 @@ mod proc_macros; mod version; -use proc_macro::bridge; +use rustc_proc_macro::bridge; use std::{fmt, fs, io, time::SystemTime}; use temp_dir::TempDir; @@ -12,8 +12,8 @@ use object::Object; use paths::{Utf8Path, Utf8PathBuf}; use crate::{ - PanicMessage, ProcMacroKind, ProcMacroSrvSpan, dylib::proc_macros::ProcMacros, - token_stream::TokenStream, + PanicMessage, ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan, + dylib::proc_macros::ProcMacros, token_stream::TokenStream, }; pub(crate) struct Expander { @@ -37,7 +37,7 @@ impl Expander { Ok(Expander { inner: library, modified_time }) } - pub(crate) fn expand( + pub(crate) fn expand<'a, S: ProcMacroSrvSpan + 'a>( &self, macro_name: &str, macro_body: TokenStream, @@ -45,13 +45,14 @@ impl Expander { def_site: S, call_site: S, mixed_site: S, + callback: Option>, ) -> Result, PanicMessage> where - ::TokenStream: Default, + as bridge::server::Server>::TokenStream: Default, { self.inner .proc_macros - .expand(macro_name, macro_body, attribute, def_site, call_site, mixed_site) + .expand(macro_name, macro_body, attribute, def_site, call_site, mixed_site, callback) } pub(crate) fn list_macros(&self) -> impl Iterator { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs index c879c7609d91..4065dbd0b49b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs @@ -1,8 +1,6 @@ //! Proc macro ABI - -use proc_macro::bridge; - -use crate::{ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream}; +use crate::{ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream}; +use rustc_proc_macro::bridge; #[repr(transparent)] pub(crate) struct ProcMacros([bridge::client::ProcMacro]); @@ -22,6 +20,7 @@ impl ProcMacros { def_site: S, call_site: S, mixed_site: S, + callback: Option>, ) -> Result, crate::PanicMessage> { let parsed_attributes = attribute.unwrap_or_default(); @@ -31,8 +30,8 @@ impl ProcMacros { if *trait_name == macro_name => { let res = client.run( - &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site), + &bridge::server::SAME_THREAD, + S::make_server(call_site, def_site, mixed_site, callback), macro_body, cfg!(debug_assertions), ); @@ -40,8 +39,8 @@ impl ProcMacros { } bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { let res = client.run( - &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site), + &bridge::server::SAME_THREAD, + S::make_server(call_site, def_site, mixed_site, callback), macro_body, cfg!(debug_assertions), ); @@ -49,8 +48,8 @@ impl ProcMacros { } bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { let res = client.run( - &bridge::server::SameThread, - S::make_server(call_site, def_site, mixed_site), + &bridge::server::SAME_THREAD, + S::make_server(call_site, def_site, mixed_site, callback), parsed_attributes, macro_body, cfg!(debug_assertions), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 93319df824c0..c548dc620ad1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs @@ -22,9 +22,12 @@ )] #![deny(deprecated_safe, clippy::undocumented_unsafe_blocks)] -extern crate proc_macro; +#[cfg(not(feature = "in-rust-tree"))] +extern crate proc_macro as rustc_proc_macro; #[cfg(feature = "in-rust-tree")] extern crate rustc_driver as _; +#[cfg(feature = "in-rust-tree")] +extern crate rustc_proc_macro; #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; @@ -41,6 +44,7 @@ use std::{ env, ffi::OsString, fs, + ops::Range, path::{Path, PathBuf}, sync::{Arc, Mutex, PoisonError}, thread, @@ -52,7 +56,8 @@ use temp_dir::TempDir; pub use crate::server_impl::token_id::SpanId; -pub use proc_macro::Delimiter; +pub use rustc_proc_macro::Delimiter; +pub use span; pub use crate::bridge::*; pub use crate::server_impl::literal_from_str; @@ -91,8 +96,50 @@ impl<'env> ProcMacroSrv<'env> { } } +#[derive(Debug)] +pub enum ProcMacroClientError { + Cancelled { reason: String }, + Io(std::io::Error), + Protocol(String), + Eof, +} + +#[derive(Debug)] +pub enum ProcMacroPanicMarker { + Cancelled { reason: String }, + Internal { reason: String }, +} + +pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); + +pub trait ProcMacroClientInterface { + fn file(&mut self, file_id: span::FileId) -> String; + fn source_text(&mut self, span: Span) -> Option; + fn local_file(&mut self, file_id: span::FileId) -> Option; + /// Line and column are 1-based. + fn line_column(&mut self, span: Span) -> Option<(u32, u32)>; + + fn byte_range(&mut self, span: Span) -> Range; +} + const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; +pub enum ExpandError { + Panic(PanicMessage), + Cancelled { reason: Option }, + Internal { reason: Option }, +} + +impl ExpandError { + pub fn into_string(self) -> Option { + match self { + ExpandError::Panic(panic_message) => panic_message.into_string(), + ExpandError::Cancelled { reason } => reason, + ExpandError::Internal { reason } => reason, + } + } +} + impl ProcMacroSrv<'_> { pub fn expand( &self, @@ -105,10 +152,11 @@ impl ProcMacroSrv<'_> { def_site: S, call_site: S, mixed_site: S, - ) -> Result, PanicMessage> { + callback: Option>, + ) -> Result, ExpandError> { let snapped_env = self.env; - let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { - message: Some(format!("failed to load macro: {err}")), + let expander = self.expander(lib.as_ref()).map_err(|err| ExpandError::Internal { + reason: Some(format!("failed to load macro: {err}")), })?; let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); @@ -120,12 +168,28 @@ impl ProcMacroSrv<'_> { .stack_size(EXPANDER_STACK_SIZE) .name(macro_name.to_owned()) .spawn_scoped(s, move || { - expander - .expand(macro_name, macro_body, attribute, def_site, call_site, mixed_site) + expander.expand( + macro_name, macro_body, attribute, def_site, call_site, mixed_site, + callback, + ) }); match thread.unwrap().join() { - Ok(res) => res, - Err(e) => std::panic::resume_unwind(e), + Ok(res) => res.map_err(ExpandError::Panic), + + Err(payload) => { + if let Some(marker) = payload.downcast_ref::() { + return match marker { + ProcMacroPanicMarker::Cancelled { reason } => { + Err(ExpandError::Cancelled { reason: Some(reason.clone()) }) + } + ProcMacroPanicMarker::Internal { reason } => { + Err(ExpandError::Internal { reason: Some(reason.clone()) }) + } + }; + } + + std::panic::resume_unwind(payload) + } } }); prev_env.rollback(); @@ -169,30 +233,50 @@ impl ProcMacroSrv<'_> { } pub trait ProcMacroSrvSpan: Copy + Send + Sync { - type Server: proc_macro::bridge::server::Server>; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server; + type Server<'a>: rustc_proc_macro::bridge::server::Server< + TokenStream = crate::token_stream::TokenStream, + >; + fn make_server<'a>( + call_site: Self, + def_site: Self, + mixed_site: Self, + callback: Option>, + ) -> Self::Server<'a>; } impl ProcMacroSrvSpan for SpanId { - type Server = server_impl::token_id::SpanIdServer; + type Server<'a> = server_impl::token_id::SpanIdServer<'a>; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { + fn make_server<'a>( + call_site: Self, + def_site: Self, + mixed_site: Self, + callback: Option>, + ) -> Self::Server<'a> { Self::Server { call_site, def_site, mixed_site, + callback, tracked_env_vars: Default::default(), tracked_paths: Default::default(), } } } + impl ProcMacroSrvSpan for Span { - type Server = server_impl::rust_analyzer_span::RaSpanServer; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { + type Server<'a> = server_impl::rust_analyzer_span::RaSpanServer<'a>; + fn make_server<'a>( + call_site: Self, + def_site: Self, + mixed_site: Self, + callback: Option>, + ) -> Self::Server<'a> { Self::Server { call_site, def_site, mixed_site, + callback, tracked_env_vars: Default::default(), tracked_paths: Default::default(), } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 7c685c2da734..c114d52ec33c 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -10,17 +10,16 @@ use std::{ }; use intern::Symbol; -use proc_macro::bridge::server; +use rustc_proc_macro::bridge::server; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize}; use crate::{ + ProcMacroClientHandle, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; -pub struct FreeFunctions; - -pub struct RaSpanServer { +pub struct RaSpanServer<'a> { // FIXME: Report this back to the caller to track as dependencies pub tracked_env_vars: HashMap, Option>>, // FIXME: Report this back to the caller to track as dependencies @@ -28,16 +27,30 @@ pub struct RaSpanServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, + pub callback: Option>, } -impl server::Types for RaSpanServer { - type FreeFunctions = FreeFunctions; +impl server::Server for RaSpanServer<'_> { type TokenStream = crate::token_stream::TokenStream; type Span = Span; type Symbol = Symbol; -} -impl server::FreeFunctions for RaSpanServer { + fn globals(&mut self) -> ExpnGlobals { + ExpnGlobals { + def_site: self.def_site, + call_site: self.call_site, + mixed_site: self.mixed_site, + } + } + + fn intern_symbol(ident: &str) -> Self::Symbol { + Symbol::intern(ident) + } + + fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { + f(symbol.as_str()) + } + fn injected_env_var(&mut self, _: &str) -> Option { None } @@ -56,13 +69,19 @@ impl server::FreeFunctions for RaSpanServer { fn emit_diagnostic(&mut self, _: Diagnostic) { // FIXME handle diagnostic } -} -impl server::TokenStream for RaSpanServer { - fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { + fn ts_drop(&mut self, stream: Self::TokenStream) { + drop(stream); + } + + fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + stream.clone() + } + + fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } - fn from_str(&mut self, src: &str) -> Self::TokenStream { + fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { Self::TokenStream::from_str( &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), @@ -71,15 +90,15 @@ impl server::TokenStream for RaSpanServer { .unwrap() }) } - fn to_string(&mut self, stream: &Self::TokenStream) -> String { + fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() } - fn from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { + fn ts_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { Self::TokenStream::new(vec![tree]) } - fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result { + fn ts_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { // FIXME: requires db, more importantly this requires name resolution so we would need to // eagerly expand this proc-macro, but we can't know that this proc-macro is eager until we // expand it ... @@ -88,7 +107,7 @@ impl server::TokenStream for RaSpanServer { Ok(self_.clone()) } - fn concat_trees( + fn ts_concat_trees( &mut self, base: Option, trees: Vec>, @@ -104,7 +123,7 @@ impl server::TokenStream for RaSpanServer { } } - fn concat_streams( + fn ts_concat_streams( &mut self, base: Option, streams: Vec, @@ -116,30 +135,26 @@ impl server::TokenStream for RaSpanServer { stream } - fn into_trees(&mut self, stream: Self::TokenStream) -> Vec> { + fn ts_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { (*stream.0).clone() } -} -impl server::Span for RaSpanServer { - fn debug(&mut self, span: Self::Span) -> String { + fn span_debug(&mut self, span: Self::Span) -> String { format!("{:?}", span) } - fn file(&mut self, _: Self::Span) -> String { - // FIXME - String::new() + fn span_file(&mut self, span: Self::Span) -> String { + self.callback.as_mut().map(|cb| cb.file(span.anchor.file_id.file_id())).unwrap_or_default() } - fn local_file(&mut self, _: Self::Span) -> Option { - // FIXME - None + fn span_local_file(&mut self, span: Self::Span) -> Option { + self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id())) } - fn save_span(&mut self, _span: Self::Span) -> usize { + fn span_save_span(&mut self, _span: Self::Span) -> usize { // FIXME, quote is incompatible with third-party tools // This is called by the quote proc-macro which is expanded when the proc-macro is compiled // As such, r-a will never observe this 0 } - fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { + fn span_recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { // FIXME, quote is incompatible with third-party tools // This is called by the expansion of quote!, r-a will observe this, but we don't have // access to the spans that were encoded @@ -149,24 +164,25 @@ impl server::Span for RaSpanServer { /// /// See PR: /// https://github.com/rust-lang/rust/pull/55780 - fn source_text(&mut self, _span: Self::Span) -> Option { - // FIXME requires db, needs special handling wrt fixup spans - None + fn span_source_text(&mut self, span: Self::Span) -> Option { + self.callback.as_mut()?.source_text(span) } - fn parent(&mut self, _span: Self::Span) -> Option { + fn span_parent(&mut self, _span: Self::Span) -> Option { // FIXME requires db, looks up the parent call site None } - fn source(&mut self, span: Self::Span) -> Self::Span { + fn span_source(&mut self, span: Self::Span) -> Self::Span { // FIXME requires db, returns the top level call site span } - fn byte_range(&mut self, span: Self::Span) -> Range { - // FIXME requires db to resolve the ast id, THIS IS NOT INCREMENTAL + fn span_byte_range(&mut self, span: Self::Span) -> Range { + if let Some(cb) = self.callback.as_mut() { + return cb.byte_range(span); + } Range { start: span.range.start().into(), end: span.range.end().into() } } - fn join(&mut self, first: Self::Span, second: Self::Span) -> Option { + fn span_join(&mut self, first: Self::Span, second: Self::Span) -> Option { // We can't modify the span range for fixup spans, those are meaningful to fixup, so just // prefer the non-fixup span. if first.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { @@ -194,7 +210,7 @@ impl server::Span for RaSpanServer { ctx: second.ctx, }) } - fn subspan( + fn span_subspan( &mut self, span: Self::Span, start: Bound, @@ -238,11 +254,11 @@ impl server::Span for RaSpanServer { }) } - fn resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span { + fn span_resolved_at(&mut self, span: Self::Span, at: Self::Span) -> Self::Span { Span { ctx: at.ctx, ..span } } - fn end(&mut self, span: Self::Span) -> Self::Span { + fn span_end(&mut self, span: Self::Span) -> Self::Span { // We can't modify the span range for fixup spans, those are meaningful to fixup. if span.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { return span; @@ -250,7 +266,7 @@ impl server::Span for RaSpanServer { Span { range: TextRange::empty(span.range.end()), ..span } } - fn start(&mut self, span: Self::Span) -> Self::Span { + fn span_start(&mut self, span: Self::Span) -> Self::Span { // We can't modify the span range for fixup spans, those are meaningful to fixup. if span.anchor.ast_id == FIXUP_ERASED_FILE_AST_ID_MARKER { return span; @@ -258,38 +274,16 @@ impl server::Span for RaSpanServer { Span { range: TextRange::empty(span.range.start()), ..span } } - fn line(&mut self, _span: Self::Span) -> usize { - // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL - 1 + fn span_line(&mut self, span: Self::Span) -> usize { + self.callback.as_mut().and_then(|cb| cb.line_column(span)).map_or(1, |(l, _)| l as usize) } - fn column(&mut self, _span: Self::Span) -> usize { - // FIXME requires db to resolve line index, THIS IS NOT INCREMENTAL - 1 + fn span_column(&mut self, span: Self::Span) -> usize { + self.callback.as_mut().and_then(|cb| cb.line_column(span)).map_or(1, |(_, c)| c as usize) } -} -impl server::Symbol for RaSpanServer { - fn normalize_and_validate_ident(&mut self, string: &str) -> Result { + fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result { // FIXME: nfc-normalize and validate idents Ok(::intern_symbol(string)) } } - -impl server::Server for RaSpanServer { - fn globals(&mut self) -> ExpnGlobals { - ExpnGlobals { - def_site: self.def_site, - call_site: self.call_site, - mixed_site: self.mixed_site, - } - } - - fn intern_symbol(ident: &str) -> Self::Symbol { - Symbol::intern(ident) - } - - fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - f(symbol.as_str()) - } -} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs index 5ac263b9d5f6..70484c4dc28f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -6,9 +6,10 @@ use std::{ }; use intern::Symbol; -use proc_macro::bridge::server; +use rustc_proc_macro::bridge::server; use crate::{ + ProcMacroClientHandle, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -24,9 +25,7 @@ impl std::fmt::Debug for SpanId { type Span = SpanId; -pub struct FreeFunctions; - -pub struct SpanIdServer { +pub struct SpanIdServer<'a> { // FIXME: Report this back to the caller to track as dependencies pub tracked_env_vars: HashMap, Option>>, // FIXME: Report this back to the caller to track as dependencies @@ -34,165 +33,14 @@ pub struct SpanIdServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, + pub callback: Option>, } -impl server::Types for SpanIdServer { - type FreeFunctions = FreeFunctions; +impl server::Server for SpanIdServer<'_> { type TokenStream = crate::token_stream::TokenStream; type Span = Span; type Symbol = Symbol; -} -impl server::FreeFunctions for SpanIdServer { - fn injected_env_var(&mut self, _: &str) -> Option { - None - } - fn track_env_var(&mut self, var: &str, value: Option<&str>) { - self.tracked_env_vars.insert(var.into(), value.map(Into::into)); - } - fn track_path(&mut self, path: &str) { - self.tracked_paths.insert(path.into()); - } - - fn literal_from_str(&mut self, s: &str) -> Result, ()> { - literal_from_str(s, self.call_site) - } - - fn emit_diagnostic(&mut self, _: Diagnostic) {} -} - -impl server::TokenStream for SpanIdServer { - fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { - stream.is_empty() - } - fn from_str(&mut self, src: &str) -> Self::TokenStream { - Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { - Self::TokenStream::from_str( - &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), - self.call_site, - ) - .unwrap() - }) - } - fn to_string(&mut self, stream: &Self::TokenStream) -> String { - stream.to_string() - } - fn from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { - Self::TokenStream::new(vec![tree]) - } - - fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result { - Ok(self_.clone()) - } - - fn concat_trees( - &mut self, - base: Option, - trees: Vec>, - ) -> Self::TokenStream { - match base { - Some(mut base) => { - for tt in trees { - base.push_tree(tt); - } - base - } - None => Self::TokenStream::new(trees), - } - } - - fn concat_streams( - &mut self, - base: Option, - streams: Vec, - ) -> Self::TokenStream { - let mut stream = base.unwrap_or_default(); - for s in streams { - stream.push_stream(s); - } - stream - } - - fn into_trees(&mut self, stream: Self::TokenStream) -> Vec> { - (*stream.0).clone() - } -} - -impl server::Span for SpanIdServer { - fn debug(&mut self, span: Self::Span) -> String { - format!("{:?}", span.0) - } - fn file(&mut self, _span: Self::Span) -> String { - String::new() - } - fn local_file(&mut self, _span: Self::Span) -> Option { - None - } - fn save_span(&mut self, _span: Self::Span) -> usize { - 0 - } - fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { - self.call_site - } - /// Recent feature, not yet in the proc_macro - /// - /// See PR: - /// https://github.com/rust-lang/rust/pull/55780 - fn source_text(&mut self, _span: Self::Span) -> Option { - None - } - - fn parent(&mut self, _span: Self::Span) -> Option { - None - } - fn source(&mut self, span: Self::Span) -> Self::Span { - span - } - fn byte_range(&mut self, _span: Self::Span) -> Range { - Range { start: 0, end: 0 } - } - fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option { - // Just return the first span again, because some macros will unwrap the result. - Some(first) - } - fn subspan( - &mut self, - span: Self::Span, - _start: Bound, - _end: Bound, - ) -> Option { - // Just return the span again, because some macros will unwrap the result. - Some(span) - } - fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span { - self.call_site - } - - fn end(&mut self, _self_: Self::Span) -> Self::Span { - self.call_site - } - - fn start(&mut self, _self_: Self::Span) -> Self::Span { - self.call_site - } - - fn line(&mut self, _span: Self::Span) -> usize { - 1 - } - - fn column(&mut self, _span: Self::Span) -> usize { - 1 - } -} - -impl server::Symbol for SpanIdServer { - fn normalize_and_validate_ident(&mut self, string: &str) -> Result { - // FIXME: nfc-normalize and validate idents - Ok(::intern_symbol(string)) - } -} - -impl server::Server for SpanIdServer { fn globals(&mut self) -> ExpnGlobals { ExpnGlobals { def_site: self.def_site, @@ -208,4 +56,153 @@ impl server::Server for SpanIdServer { fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { f(symbol.as_str()) } + + fn injected_env_var(&mut self, _: &str) -> Option { + None + } + fn track_env_var(&mut self, var: &str, value: Option<&str>) { + self.tracked_env_vars.insert(var.into(), value.map(Into::into)); + } + fn track_path(&mut self, path: &str) { + self.tracked_paths.insert(path.into()); + } + + fn literal_from_str(&mut self, s: &str) -> Result, ()> { + literal_from_str(s, self.call_site) + } + + fn emit_diagnostic(&mut self, _: Diagnostic) {} + + fn ts_drop(&mut self, stream: Self::TokenStream) { + drop(stream); + } + + fn ts_clone(&mut self, stream: &Self::TokenStream) -> Self::TokenStream { + stream.clone() + } + + fn ts_is_empty(&mut self, stream: &Self::TokenStream) -> bool { + stream.is_empty() + } + fn ts_from_str(&mut self, src: &str) -> Self::TokenStream { + Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { + Self::TokenStream::from_str( + &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), + self.call_site, + ) + .unwrap() + }) + } + fn ts_to_string(&mut self, stream: &Self::TokenStream) -> String { + stream.to_string() + } + fn ts_from_token_tree(&mut self, tree: TokenTree) -> Self::TokenStream { + Self::TokenStream::new(vec![tree]) + } + + fn ts_expand_expr(&mut self, self_: &Self::TokenStream) -> Result { + Ok(self_.clone()) + } + + fn ts_concat_trees( + &mut self, + base: Option, + trees: Vec>, + ) -> Self::TokenStream { + match base { + Some(mut base) => { + for tt in trees { + base.push_tree(tt); + } + base + } + None => Self::TokenStream::new(trees), + } + } + + fn ts_concat_streams( + &mut self, + base: Option, + streams: Vec, + ) -> Self::TokenStream { + let mut stream = base.unwrap_or_default(); + for s in streams { + stream.push_stream(s); + } + stream + } + + fn ts_into_trees(&mut self, stream: Self::TokenStream) -> Vec> { + (*stream.0).clone() + } + + fn span_debug(&mut self, span: Self::Span) -> String { + format!("{:?}", span.0) + } + fn span_file(&mut self, _span: Self::Span) -> String { + String::new() + } + fn span_local_file(&mut self, _span: Self::Span) -> Option { + None + } + fn span_save_span(&mut self, _span: Self::Span) -> usize { + 0 + } + fn span_recover_proc_macro_span(&mut self, _id: usize) -> Self::Span { + self.call_site + } + /// Recent feature, not yet in the proc_macro + /// + /// See PR: + /// https://github.com/rust-lang/rust/pull/55780 + fn span_source_text(&mut self, _span: Self::Span) -> Option { + None + } + + fn span_parent(&mut self, _span: Self::Span) -> Option { + None + } + fn span_source(&mut self, span: Self::Span) -> Self::Span { + span + } + fn span_byte_range(&mut self, _span: Self::Span) -> Range { + Range { start: 0, end: 0 } + } + fn span_join(&mut self, first: Self::Span, _second: Self::Span) -> Option { + // Just return the first span again, because some macros will unwrap the result. + Some(first) + } + fn span_subspan( + &mut self, + span: Self::Span, + _start: Bound, + _end: Bound, + ) -> Option { + // Just return the span again, because some macros will unwrap the result. + Some(span) + } + fn span_resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span { + self.call_site + } + + fn span_end(&mut self, _self_: Self::Span) -> Self::Span { + self.call_site + } + + fn span_start(&mut self, _self_: Self::Span) -> Self::Span { + self.call_site + } + + fn span_line(&mut self, _span: Self::Span) -> usize { + 1 + } + + fn span_column(&mut self, _span: Self::Span) -> usize { + 1 + } + + fn symbol_normalize_and_validate_ident(&mut self, string: &str) -> Result { + // FIXME: nfc-normalize and validate idents + Ok(::intern_symbol(string)) + } } diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs index 20507a6def54..ebef9a9a519a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/mod.rs @@ -703,6 +703,7 @@ fn list_test_macros() { fn_like_mk_idents [Bang] fn_like_span_join [Bang] fn_like_span_ops [Bang] + fn_like_span_line_column [Bang] attr_noop [Attr] attr_panic [Attr] attr_error [Attr] @@ -712,3 +713,17 @@ fn list_test_macros() { DeriveError [CustomDerive]"#]] .assert_eq(&res); } + +#[test] +fn test_fn_like_span_line_column() { + assert_expand_with_callback( + "fn_like_span_line_column", + // Input text with known position: "hello" starts at offset 1 (line 2, column 1 in 1-based) + " +hello", + expect![[r#" + LITER 42:Root[0000, 0]@0..100#ROOT2024 Integer 2 + LITER 42:Root[0000, 0]@0..100#ROOT2024 Integer 1 + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs index 1b12308ad6c5..b7c5c4fdd21f 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/tests/utils.rs @@ -4,9 +4,11 @@ use expect_test::Expect; use span::{ EditionedFileId, FileId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, TextRange, }; +use std::ops::Range; use crate::{ - EnvSnapshot, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path, token_stream::TokenStream, + EnvSnapshot, ProcMacroClientInterface, ProcMacroSrv, SpanId, dylib, proc_macro_test_dylib_path, + token_stream::TokenStream, }; fn parse_string(call_site: SpanId, src: &str) -> TokenStream { @@ -59,8 +61,9 @@ fn assert_expand_impl( let input_ts_string = format!("{input_ts:?}"); let attr_ts_string = attr_ts.as_ref().map(|it| format!("{it:?}")); - let res = - expander.expand(macro_name, input_ts, attr_ts, def_site, call_site, mixed_site).unwrap(); + let res = expander + .expand(macro_name, input_ts, attr_ts, def_site, call_site, mixed_site, None) + .unwrap(); expect.assert_eq(&format!( "{input_ts_string}{}{}{}", if attr_ts_string.is_some() { "\n\n" } else { "" }, @@ -91,7 +94,8 @@ fn assert_expand_impl( let fixture_string = format!("{fixture:?}"); let attr_string = attr.as_ref().map(|it| format!("{it:?}")); - let res = expander.expand(macro_name, fixture, attr, def_site, call_site, mixed_site).unwrap(); + let res = + expander.expand(macro_name, fixture, attr, def_site, call_site, mixed_site, None).unwrap(); expect_spanned.assert_eq(&format!( "{fixture_string}{}{}{}", if attr_string.is_some() { "\n\n" } else { "" }, @@ -107,3 +111,70 @@ pub(crate) fn list() -> Vec { let res = srv.list_macros(&dylib_path).unwrap(); res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect() } + +/// A mock callback for testing that computes line/column from the input text. +struct MockCallback<'a> { + text: &'a str, +} + +impl ProcMacroClientInterface for MockCallback<'_> { + fn source_text(&mut self, span: Span) -> Option { + self.text + .get(usize::from(span.range.start())..usize::from(span.range.end())) + .map(ToOwned::to_owned) + } + + fn file(&mut self, _file_id: FileId) -> String { + String::new() + } + + fn local_file(&mut self, _file_id: FileId) -> Option { + None + } + + fn line_column(&mut self, span: Span) -> Option<(u32, u32)> { + let line_index = line_index::LineIndex::new(self.text); + let line_col = line_index.try_line_col(span.range.start())?; + // proc_macro uses 1-based line/column + Some((line_col.line as u32 + 1, line_col.col as u32 + 1)) + } + + fn byte_range(&mut self, span: Span) -> Range { + Range { start: span.range.start().into(), end: span.range.end().into() } + } +} + +pub fn assert_expand_with_callback( + macro_name: &str, + #[rust_analyzer::rust_fixture] ra_fixture: &str, + expect_spanned: Expect, +) { + let path = proc_macro_test_dylib_path(); + let expander = dylib::Expander::new(&temp_dir::TempDir::new().unwrap(), &path).unwrap(); + + let def_site = Span { + range: TextRange::new(0.into(), 150.into()), + anchor: SpanAnchor { + file_id: EditionedFileId::current_edition(FileId::from_raw(41)), + ast_id: ROOT_ERASED_FILE_AST_ID, + }, + ctx: SyntaxContext::root(span::Edition::CURRENT), + }; + let call_site = Span { + range: TextRange::new(0.into(), 100.into()), + anchor: SpanAnchor { + file_id: EditionedFileId::current_edition(FileId::from_raw(42)), + ast_id: ROOT_ERASED_FILE_AST_ID, + }, + ctx: SyntaxContext::root(span::Edition::CURRENT), + }; + let mixed_site = call_site; + + let fixture = parse_string_spanned(call_site.anchor, call_site.ctx, ra_fixture); + + let mut callback = MockCallback { text: ra_fixture }; + let res = expander + .expand(macro_name, fixture, None, def_site, call_site, mixed_site, Some(&mut callback)) + .unwrap(); + expect_spanned.assert_eq(&format!("{res:?}")); +} diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs index 36827d2561f9..2358f6963c79 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/token_stream.rs @@ -4,8 +4,8 @@ use core::fmt; use std::{mem, sync::Arc}; use intern::Symbol; -use proc_macro::Delimiter; use rustc_lexer::{DocStyle, LiteralKind}; +use rustc_proc_macro::Delimiter; use crate::bridge::{DelimSpan, Group, Ident, LitKind, Literal, Punct, TokenTree}; @@ -52,7 +52,7 @@ impl TokenStream { S: SpanLike + Copy, { let mut groups = Vec::new(); - groups.push((proc_macro::Delimiter::None, 0..0, vec![])); + groups.push((rustc_proc_macro::Delimiter::None, 0..0, vec![])); let mut offset = 0; let mut tokens = rustc_lexer::tokenize(s, rustc_lexer::FrontmatterAllowed::No).peekable(); while let Some(token) = tokens.next() { @@ -102,7 +102,7 @@ impl TokenStream { }; match token.kind { rustc_lexer::TokenKind::OpenParen => { - groups.push((proc_macro::Delimiter::Parenthesis, range, vec![])) + groups.push((rustc_proc_macro::Delimiter::Parenthesis, range, vec![])) } rustc_lexer::TokenKind::CloseParen if *open_delim != Delimiter::Parenthesis => { return if *open_delim == Delimiter::None { @@ -130,7 +130,7 @@ impl TokenStream { ); } rustc_lexer::TokenKind::OpenBrace => { - groups.push((proc_macro::Delimiter::Brace, range, vec![])) + groups.push((rustc_proc_macro::Delimiter::Brace, range, vec![])) } rustc_lexer::TokenKind::CloseBrace if *open_delim != Delimiter::Brace => { return if *open_delim == Delimiter::None { @@ -158,7 +158,7 @@ impl TokenStream { ); } rustc_lexer::TokenKind::OpenBracket => { - groups.push((proc_macro::Delimiter::Bracket, range, vec![])) + groups.push((rustc_proc_macro::Delimiter::Bracket, range, vec![])) } rustc_lexer::TokenKind::CloseBracket if *open_delim != Delimiter::Bracket => { return if *open_delim == Delimiter::None { @@ -460,10 +460,10 @@ fn display_token_tree( f, "{}", match delimiter { - proc_macro::Delimiter::Parenthesis => "(", - proc_macro::Delimiter::Brace => "{", - proc_macro::Delimiter::Bracket => "[", - proc_macro::Delimiter::None => "", + rustc_proc_macro::Delimiter::Parenthesis => "(", + rustc_proc_macro::Delimiter::Brace => "{", + rustc_proc_macro::Delimiter::Bracket => "[", + rustc_proc_macro::Delimiter::None => "", } )?; if let Some(stream) = stream { @@ -473,10 +473,10 @@ fn display_token_tree( f, "{}", match delimiter { - proc_macro::Delimiter::Parenthesis => ")", - proc_macro::Delimiter::Brace => "}", - proc_macro::Delimiter::Bracket => "]", - proc_macro::Delimiter::None => "", + rustc_proc_macro::Delimiter::Parenthesis => ")", + rustc_proc_macro::Delimiter::Brace => "}", + rustc_proc_macro::Delimiter::Bracket => "]", + rustc_proc_macro::Delimiter::None => "", } )?; } @@ -587,16 +587,16 @@ fn debug_token_tree( f, "GROUP {}{} {:#?} {:#?} {:#?}", match delimiter { - proc_macro::Delimiter::Parenthesis => "(", - proc_macro::Delimiter::Brace => "{", - proc_macro::Delimiter::Bracket => "[", - proc_macro::Delimiter::None => "$", + rustc_proc_macro::Delimiter::Parenthesis => "(", + rustc_proc_macro::Delimiter::Brace => "{", + rustc_proc_macro::Delimiter::Bracket => "[", + rustc_proc_macro::Delimiter::None => "$", }, match delimiter { - proc_macro::Delimiter::Parenthesis => ")", - proc_macro::Delimiter::Brace => "}", - proc_macro::Delimiter::Bracket => "]", - proc_macro::Delimiter::None => "$", + rustc_proc_macro::Delimiter::Parenthesis => ")", + rustc_proc_macro::Delimiter::Brace => "}", + rustc_proc_macro::Delimiter::Bracket => "]", + rustc_proc_macro::Delimiter::None => "$", }, span.open, span.close, diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml index 7e0b1f75f72c..f825a456dea7 100644 --- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml +++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml @@ -39,5 +39,9 @@ toolchain.workspace = true [dev-dependencies] expect-test = "1.5.1" +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index 6e1a3f37ff1c..483ab2845045 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -640,7 +640,7 @@ impl FetchMetadata { /// Builds a command to fetch metadata for the given `cargo_toml` manifest. /// /// Performs a lightweight pre-fetch using the `--no-deps` option, - /// available via [`FetchMetadata::no_deps_metadata`], to gather basic + /// available via `FetchMetadata::no_deps_metadata`, to gather basic /// information such as the `target-dir`. /// /// The provided sysroot is used to set the `RUSTUP_TOOLCHAIN` diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index 8eee3d1455c1..3414b52d4514 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -17,6 +17,10 @@ // It's useful to refer to code that is private in doc comments. #![allow(rustdoc::private_intra_doc_links)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; pub mod project_json; pub mod toolchain_info { diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs index 041b9accf41d..6938010cbd70 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs @@ -78,6 +78,13 @@ pub struct ProjectJson { runnables: Vec, } +impl std::ops::Index for ProjectJson { + type Output = Crate; + fn index(&self, index: CrateArrayIdx) -> &Self::Output { + &self.crates[index.0] + } +} + impl ProjectJson { /// Create a new ProjectJson instance. /// @@ -163,6 +170,7 @@ impl ProjectJson { cfg, target: crate_data.target, env: crate_data.env, + crate_attrs: crate_data.crate_attrs, proc_macro_dylib_path: crate_data .proc_macro_dylib_path .map(absolutize_on_base), @@ -194,12 +202,11 @@ impl ProjectJson { &self.project_root } - pub fn crate_by_root(&self, root: &AbsPath) -> Option { + pub fn crate_by_root(&self, root: &AbsPath) -> Option<&Crate> { self.crates .iter() .filter(|krate| krate.is_workspace_member) .find(|krate| krate.root_module == root) - .cloned() } /// Returns the path to the project's manifest, if it exists. @@ -213,8 +220,17 @@ impl ProjectJson { self.crates .iter() .filter(|krate| krate.is_workspace_member) - .filter_map(|krate| krate.build.clone()) + .filter_map(|krate| krate.build.as_ref()) .find(|build| build.build_file.as_std_path() == path) + .cloned() + } + + pub fn crate_by_label(&self, label: &str) -> Option<&Crate> { + // this is fast enough for now, but it's unfortunate that this is O(crates). + self.crates + .iter() + .filter(|krate| krate.is_workspace_member) + .find(|krate| krate.build.as_ref().is_some_and(|build| build.label == label)) } /// Returns the path to the project's manifest or root folder, if no manifest exists. @@ -230,6 +246,10 @@ impl ProjectJson { pub fn runnables(&self) -> &[Runnable] { &self.runnables } + + pub fn runnable_template(&self, kind: RunnableKind) -> Option<&Runnable> { + self.runnables().iter().find(|r| r.kind == kind) + } } /// A crate points to the root module of a crate and lists the dependencies of the crate. This is @@ -244,6 +264,8 @@ pub struct Crate { pub(crate) cfg: Vec, pub(crate) target: Option, pub(crate) env: FxHashMap, + // Extra crate-level attributes, without the surrounding `#![]`. + pub(crate) crate_attrs: Vec, pub(crate) proc_macro_dylib_path: Option, pub(crate) is_workspace_member: bool, pub(crate) include: Vec, @@ -255,6 +277,12 @@ pub struct Crate { pub build: Option, } +impl Crate { + pub fn iter_deps(&self) -> impl ExactSizeIterator { + self.deps.iter().map(|dep| dep.krate) + } +} + /// Additional, build-specific data about a crate. #[derive(Clone, Debug, Eq, PartialEq)] pub struct Build { @@ -325,13 +353,21 @@ pub struct Runnable { /// The kind of runnable. #[derive(Debug, Clone, PartialEq, Eq)] pub enum RunnableKind { + /// `cargo check`, basically, with human-readable output. Check, /// Can run a binary. + /// May include {label} which will get the label from the `build` section of a crate. Run, /// Run a single test. + /// May include {label} which will get the label from the `build` section of a crate. + /// May include {test_id} which will get the test clicked on by the user. TestOne, + + /// Template for checking a target, emitting rustc JSON diagnostics. + /// May include {label} which will get the label from the `build` section of a crate. + Flycheck, } #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] @@ -365,6 +401,8 @@ struct CrateData { target: Option, #[serde(default)] env: FxHashMap, + #[serde(default)] + crate_attrs: Vec, proc_macro_dylib_path: Option, is_workspace_member: Option, source: Option, @@ -436,6 +474,7 @@ pub struct RunnableData { #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub enum RunnableKindData { + Flycheck, Check, Run, TestOne, @@ -506,6 +545,7 @@ impl From for RunnableKind { RunnableKindData::Check => RunnableKind::Check, RunnableKindData::Run => RunnableKind::Run, RunnableKindData::TestOne => RunnableKind::TestOne, + RunnableKindData::Flycheck => RunnableKind::Flycheck, } } } diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs index f244c9736c7c..546a1e05a063 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs @@ -275,7 +275,10 @@ impl Sysroot { } tracing::debug!("Stitching sysroot library: {src_root}"); - let mut stitched = stitched::Stitched { crates: Default::default() }; + let mut stitched = stitched::Stitched { + crates: Default::default(), + edition: span::Edition::Edition2024, + }; for path in stitched::SYSROOT_CRATES.trim().lines() { let name = path.split('/').next_back().unwrap(); @@ -511,6 +514,7 @@ pub(crate) mod stitched { #[derive(Debug, Clone, Eq, PartialEq)] pub struct Stitched { pub(super) crates: Arena, + pub(crate) edition: span::Edition, } impl ops::Index for Stitched { diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index 1908fc02904a..a03ed562e1be 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -198,6 +198,15 @@ fn rust_project_cfg_groups() { check_crate_graph(crate_graph, expect_file!["../test_data/output/rust_project_cfg_groups.txt"]); } +#[test] +fn rust_project_crate_attrs() { + let (crate_graph, _proc_macros) = load_rust_project("crate-attrs.json"); + check_crate_graph( + crate_graph, + expect_file!["../test_data/output/rust_project_crate_attrs.txt"], + ); +} + #[test] fn crate_graph_dedup_identical() { let (mut crate_graph, proc_macros) = load_cargo("regex-metadata.json"); diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 10abb21ace83..581b5fa51446 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -391,6 +391,7 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + workspace_dir, &targets, toolchain.clone(), )), @@ -500,6 +501,7 @@ impl ProjectWorkspace { sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + project_json.project_root(), &targets, toolchain.clone(), )), @@ -555,6 +557,7 @@ impl ProjectWorkspace { let loaded_sysroot = sysroot.load_workspace( &RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config( config, + dir, &targets, toolchain.clone(), )), @@ -1090,6 +1093,7 @@ fn project_json_to_crate_graph( cfg, target, env, + crate_attrs, proc_macro_dylib_path, is_proc_macro, repository, @@ -1157,9 +1161,12 @@ fn project_json_to_crate_graph( name: Some(name.canonical_name().to_owned()), } } + } else if is_sysroot { + CrateOrigin::Lang(LangCrateOrigin::Dependency) } else { CrateOrigin::Local { repo: None, name: None } }, + crate_attrs.clone(), *is_proc_macro, match proc_macro_cwd { Some(path) => Arc::new(path.clone()), @@ -1289,6 +1296,8 @@ fn cargo_to_crate_graph( name: Some(Symbol::intern(&pkg_data.name)), } } + } else if cargo.is_sysroot() { + CrateOrigin::Lang(LangCrateOrigin::Dependency) } else { CrateOrigin::Library { repo: pkg_data.repository.clone(), @@ -1464,6 +1473,7 @@ fn detached_file_to_crate_graph( repo: None, name: display_name.map(|n| n.canonical_name().to_owned()), }, + Vec::new(), false, Arc::new(detached_file.parent().to_path_buf()), crate_ws_data, @@ -1644,6 +1654,7 @@ fn add_target_crate_root( potential_cfg_options, env, origin, + Vec::new(), matches!(kind, TargetKind::Lib { is_proc_macro: true }), proc_macro_cwd, crate_ws_data, @@ -1710,7 +1721,7 @@ fn extend_crate_graph_with_sysroot( !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc), )), LangCrateOrigin::ProcMacro => libproc_macro = Some(cid), - LangCrateOrigin::Other => (), + LangCrateOrigin::Other | LangCrateOrigin::Dependency => (), } } } @@ -1820,13 +1831,14 @@ fn sysroot_to_crate_graph( let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name); let crate_id = crate_graph.add_crate_root( file_id, - Edition::CURRENT_FIXME, + stitched.edition, Some(display_name), None, cfg_options.clone(), None, Env::default(), CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)), + Vec::new(), false, Arc::new(stitched[krate].root.parent().to_path_buf()), crate_ws_data.clone(), @@ -1907,12 +1919,28 @@ fn add_dep_inner(graph: &mut CrateGraphBuilder, from: CrateBuilderId, dep: Depen fn sysroot_metadata_config( config: &CargoConfig, + workspace_root: &AbsPath, targets: &[String], toolchain_version: Option, ) -> CargoMetadataConfig { + // If the target is a JSON path, prefix it with workspace root directory. + // Since `cargo metadata` command for sysroot is run inside sysroots dir, it may fail to + // locate the target file if it is given as a relative path. + let targets = targets + .iter() + .map(|target| { + if target.ends_with(".json") { + // If `target` is an absolute path, this will replace the whole path. + workspace_root.join(target).to_string() + } else { + target.to_owned() + } + }) + .collect(); + CargoMetadataConfig { features: Default::default(), - targets: targets.to_vec(), + targets, extra_args: Default::default(), extra_env: config.extra_env.clone(), toolchain_version, diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/crate-attrs.json b/src/tools/rust-analyzer/crates/project-model/test_data/crate-attrs.json new file mode 100644 index 000000000000..b2a7e3715017 --- /dev/null +++ b/src/tools/rust-analyzer/crates/project-model/test_data/crate-attrs.json @@ -0,0 +1,13 @@ +{ + "sysroot_src": null, + "crates": [ + { + "display_name": "foo", + "root_module": "$ROOT$src/lib.rs", + "edition": "2024", + "deps": [], + "crate_attrs": ["no_std", "feature(f16,f128)", "crate_type = \"lib\""], + "is_workspace_member": true + } + ] +} diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt index 4f6ce4dc9537..a895ef53afa0 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt @@ -21,6 +21,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -106,6 +107,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -191,6 +193,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -276,6 +279,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -344,6 +348,7 @@ ), name: "libc", }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt index 4f6ce4dc9537..a895ef53afa0 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt @@ -21,6 +21,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -106,6 +107,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -191,6 +193,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -276,6 +279,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -344,6 +348,7 @@ ), name: "libc", }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt index 6862918e09ae..9eb47947b6fd 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt @@ -21,6 +21,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -105,6 +106,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -189,6 +191,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -273,6 +276,7 @@ "hello-world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$hello-world", @@ -340,6 +344,7 @@ ), name: "libc", }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.98", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 28ad3236ae81..32f9206a3e16 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -12,6 +12,7 @@ "hello_world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$", @@ -62,6 +63,7 @@ "other_crate", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$", diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_crate_attrs.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_crate_attrs.txt new file mode 100644 index 000000000000..21b484bc0c42 --- /dev/null +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_crate_attrs.txt @@ -0,0 +1,54 @@ +{ + 0: CrateBuilder { + basic: CrateData { + root_file_id: FileId( + 1, + ), + edition: Edition2024, + dependencies: [], + origin: Local { + repo: None, + name: Some( + "foo", + ), + }, + crate_attrs: [ + "#![no_std]", + "#![feature(f16,f128)]", + "#![crate_type = \"lib\"]", + ], + is_proc_macro: false, + proc_macro_cwd: AbsPathBuf( + "$ROOT$", + ), + }, + extra: ExtraCrateData { + version: None, + display_name: Some( + CrateDisplayName { + crate_name: CrateName( + "foo", + ), + canonical_name: "foo", + }, + ), + potential_cfg_options: None, + }, + cfg_options: CfgOptions( + [ + "rust_analyzer", + "test", + "true", + ], + ), + env: Env { + entries: {}, + }, + ws_data: CrateWorkspaceData { + target: Err( + "test has no target data", + ), + toolchain: None, + }, + }, +} \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index dabb3aa67441..de793115b9d5 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -12,6 +12,7 @@ "hello_world", ), }, + crate_attrs: [], is_proc_macro: false, proc_macro_cwd: AbsPathBuf( "$ROOT$", diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs index 7698ce5fff13..83ce8902d0c9 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs @@ -48,8 +48,7 @@ impl ToTokens for TrackedQuery { quote!(#(#options),*) }) .into_iter() - .chain(self.lru.map(|lru| quote!(lru = #lru))) - .chain(Some(quote!(unsafe(non_update_return_type)))); + .chain(self.lru.map(|lru| quote!(lru = #lru))); let annotation = quote!(#[salsa_macros::tracked( #(#options),* )]); let pat_and_tys = &self.pat_and_tys; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index 2e48c5a5a66c..d1283ca59e8c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -98,12 +98,16 @@ syntax-bridge.workspace = true jemalloc = ["jemallocator", "profile/jemalloc"] force-always-assert = ["stdx/force-always-assert"] in-rust-tree = [ - "syntax/in-rust-tree", - "parser/in-rust-tree", - "hir/in-rust-tree", + "cfg/in-rust-tree", "hir-def/in-rust-tree", "hir-ty/in-rust-tree", + "hir/in-rust-tree", + "ide-ssr/in-rust-tree", + "ide/in-rust-tree", "load-cargo/in-rust-tree", + "parser/in-rust-tree", + "proc-macro-api/in-rust-tree", + "syntax/in-rust-tree", ] dhat = ["dep:dhat"] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index ed0b64668559..1995d3889891 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -91,6 +91,7 @@ impl flags::AnalysisStats { } }, prefill_caches: false, + proc_macro_processes: 1, }; let build_scripts_time = if self.disable_build_scripts { @@ -206,7 +207,7 @@ impl flags::AnalysisStats { let mut visited_modules = FxHashSet::default(); let mut visit_queue = Vec::new(); for &krate in &krates { - let module = krate.root_module(); + let module = krate.root_module(db); let file_id = module.definition_source_file_id(db); let file_id = file_id.original_file(db); @@ -354,10 +355,10 @@ impl flags::AnalysisStats { self.run_term_search(&workspace, db, &vfs, &file_ids, verbosity); } - hir::clear_tls_solver_cache(); - let db = host.raw_database_mut(); db.trigger_lru_eviction(); + hir::clear_tls_solver_cache(); + unsafe { hir::collect_ty_garbage() }; let total_span = analysis_sw.elapsed(); eprintln!("{:<20} {total_span}", "Total:"); @@ -390,11 +391,12 @@ impl flags::AnalysisStats { all += 1; let Err(e) = db.layout_of_adt( hir_def::AdtId::from(a), - GenericArgs::new_from_iter(interner, []), + GenericArgs::empty(interner).store(), hir_ty::ParamEnvAndCrate { param_env: db.trait_environment(a.into()), krate: a.krate(db).into(), - }, + } + .store(), ) else { continue; }; @@ -691,21 +693,24 @@ impl flags::AnalysisStats { let mut sw = self.stop_watch(); let mut all = 0; let mut fail = 0; - for &body_id in bodies { + for &body in bodies { bar.set_message(move || { - format!("mir lowering: {}", full_name(db, body_id, body_id.module(db))) + format!("mir lowering: {}", full_name(db, body, body.module(db))) }); bar.inc(1); - if matches!(body_id, DefWithBody::Variant(_)) { + if matches!(body, DefWithBody::Variant(_)) { continue; } - let module = body_id.module(db); - if !self.should_process(db, body_id, module) { + let module = body.module(db); + if !self.should_process(db, body, module) { continue; } all += 1; - let Err(e) = db.mir_body(body_id.into()) else { + let Ok(body_id) = body.try_into() else { + continue; + }; + let Err(e) = db.mir_body(body_id) else { continue; }; if verbosity.is_spammy() { @@ -714,7 +719,7 @@ impl flags::AnalysisStats { .into_iter() .rev() .filter_map(|it| it.name(db)) - .chain(Some(body_id.name(db).unwrap_or_else(Name::missing))) + .chain(Some(body.name(db).unwrap_or_else(Name::missing))) .map(|it| it.display(db, Edition::LATEST).to_string()) .join("::"); bar.println(format!("Mir body for {full_name} failed due {e:?}")); @@ -745,11 +750,12 @@ impl flags::AnalysisStats { if self.parallel { let mut inference_sw = self.stop_watch(); + let bodies = bodies.iter().filter_map(|&body| body.try_into().ok()).collect::>(); bodies .par_iter() .map_with(db.clone(), |snap, &body| { - snap.body(body.into()); - InferenceResult::for_body(snap, body.into()); + snap.body(body); + InferenceResult::for_body(snap, body); }) .count(); eprintln!("{:<20} {}", "Parallel Inference:", inference_sw.elapsed()); @@ -767,9 +773,10 @@ impl flags::AnalysisStats { let mut num_pat_type_mismatches = 0; let mut panics = 0; for &body_id in bodies { + let Ok(body_def_id) = body_id.try_into() else { continue }; let name = body_id.name(db).unwrap_or_else(Name::missing); let module = body_id.module(db); - let display_target = module.krate().to_display_target(db); + let display_target = module.krate(db).to_display_target(db); if let Some(only_name) = self.only.as_deref() && name.display(db, Edition::LATEST).to_string() != only_name && full_name(db, body_id, module) != only_name @@ -805,9 +812,9 @@ impl flags::AnalysisStats { bar.println(msg()); } bar.set_message(msg); - let body = db.body(body_id.into()); + let body = db.body(body_def_id); let inference_result = - catch_unwind(AssertUnwindSafe(|| InferenceResult::for_body(db, body_id.into()))); + catch_unwind(AssertUnwindSafe(|| InferenceResult::for_body(db, body_def_id))); let inference_result = match inference_result { Ok(inference_result) => inference_result, Err(p) => { @@ -824,13 +831,13 @@ impl flags::AnalysisStats { } }; // This query is LRU'd, so actually calling it will skew the timing results. - let sm = || db.body_with_source_map(body_id.into()).1; + let sm = || db.body_with_source_map(body_def_id).1; // region:expressions let (previous_exprs, previous_unknown, previous_partially_unknown) = (num_exprs, num_exprs_unknown, num_exprs_partially_unknown); for (expr_id, _) in body.exprs() { - let ty = &inference_result[expr_id]; + let ty = inference_result.expr_ty(expr_id); num_exprs += 1; let unknown_or_partial = if ty.is_ty_error() { num_exprs_unknown += 1; @@ -897,15 +904,15 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } else { bar.println(format!( "{}: Expected {}, got {}", name.display(db, Edition::LATEST), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } } @@ -913,8 +920,8 @@ impl flags::AnalysisStats { println!( r#"{},mismatch,"{}","{}""#, location_csv_expr(db, vfs, &sm(), expr_id), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) ); } } @@ -934,7 +941,7 @@ impl flags::AnalysisStats { let (previous_pats, previous_unknown, previous_partially_unknown) = (num_pats, num_pats_unknown, num_pats_partially_unknown); for (pat_id, _) in body.pats() { - let ty = &inference_result[pat_id]; + let ty = inference_result.pat_ty(pat_id); num_pats += 1; let unknown_or_partial = if ty.is_ty_error() { num_pats_unknown += 1; @@ -999,15 +1006,15 @@ impl flags::AnalysisStats { start.col, end.line + 1, end.col, - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } else { bar.println(format!( "{}: Expected {}, got {}", name.display(db, Edition::LATEST), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) )); } } @@ -1015,8 +1022,8 @@ impl flags::AnalysisStats { println!( r#"{},mismatch,"{}","{}""#, location_csv_pat(db, vfs, &sm(), pat_id), - mismatch.expected.display(db, display_target), - mismatch.actual.display(db, display_target) + mismatch.expected.as_ref().display(db, display_target), + mismatch.actual.as_ref().display(db, display_target) ); } } @@ -1079,6 +1086,7 @@ impl flags::AnalysisStats { let mut sw = self.stop_watch(); bar.tick(); for &body_id in bodies { + let Ok(body_def_id) = body_id.try_into() else { continue }; let module = body_id.module(db); if !self.should_process(db, body_id, module) { continue; @@ -1112,7 +1120,7 @@ impl flags::AnalysisStats { bar.println(msg()); } bar.set_message(msg); - db.body(body_id.into()); + db.body(body_def_id); bar.inc(1); } @@ -1186,6 +1194,7 @@ impl flags::AnalysisStats { style_lints: false, term_search_fuel: 400, term_search_borrowck: true, + show_rename_conflicts: true, }, ide::AssistResolveStrategy::All, analysis.editioned_file_id_to_vfs(file_id), @@ -1205,6 +1214,7 @@ impl flags::AnalysisStats { sized_bound: false, discriminant_hints: ide::DiscriminantHints::Always, parameter_hints: true, + parameter_hints_for_missing_arguments: false, generic_parameter_hints: ide::GenericParameterHints { type_hints: true, lifetime_hints: true, @@ -1222,6 +1232,7 @@ impl flags::AnalysisStats { implied_dyn_trait_hints: true, lifetime_elision_hints: ide::LifetimeElisionHints::Always, param_names_for_lifetime_elision_hints: true, + hide_inferred_type_hints: false, hide_named_constructor_hints: false, hide_closure_initialization_hints: false, hide_closure_parameter_hints: false, @@ -1289,7 +1300,7 @@ impl flags::AnalysisStats { fn full_name(db: &RootDatabase, body_id: DefWithBody, module: hir::Module) -> String { module - .krate() + .krate(db) .display_name(db) .map(|it| it.canonical_name().as_str().to_owned()) .into_iter() diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs index 82590c8e707f..575c77f8428c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs @@ -41,6 +41,7 @@ impl flags::Diagnostics { load_out_dirs_from_check: !self.disable_build_scripts, with_proc_macro_server, prefill_caches: false, + proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; @@ -68,8 +69,12 @@ impl flags::Diagnostics { if !visited_files.contains(&file_id) { let message = format!("processing {}", _vfs.file_path(file_id.file_id(db))); bar.set_message(move || message.clone()); - let crate_name = - module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned(); + let crate_name = module + .krate(db) + .display_name(db) + .as_deref() + .unwrap_or(&sym::unknown) + .to_owned(); for diagnostic in analysis .full_diagnostics( &DiagnosticsConfig::test_sample(), @@ -122,7 +127,7 @@ impl flags::Diagnostics { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs index f3b0699d5515..e5e238db6361 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/lsif.rs @@ -293,6 +293,7 @@ impl flags::Lsif { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let path = AbsPathBuf::assert_utf8(env::current_dir()?.join(self.path)); let root = ProjectManifest::discover_single(&path)?; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs index 467d8a53884a..d5da6791797b 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/prime_caches.rs @@ -38,6 +38,7 @@ impl flags::PrimeCaches { // we want to ensure that this command, not `load_workspace_at`, // is responsible for that work. prefill_caches: false, + proc_macro_processes: config.proc_macro_num_processes(), }; let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root)); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs index 60b33f0a3086..d4a56d773e7d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/run_tests.rs @@ -23,6 +23,7 @@ impl flags::RunTests { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (ref db, _vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; @@ -78,7 +79,7 @@ fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = Crate::all(db) .into_iter() .filter(|x| x.origin(db).is_local()) - .map(|krate| krate.root_module()) + .map(|krate| krate.root_module(db)) .collect(); let mut modules = Vec::new(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index eb28a47ec0ad..e8c6c5f4d4f7 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -103,6 +103,7 @@ impl Tester { load_out_dirs_from_check: false, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (db, _vfs, _proc_macro) = load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?; @@ -185,7 +186,7 @@ impl Tester { if !worker.is_finished() { // attempt to cancel the worker, won't work for chalk hangs unfortunately - self.host.request_cancellation(); + self.host.trigger_garbage_collection(); } worker.join().and_then(identity) }); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs index fbf3082e1b89..ed0476697c9c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs @@ -52,6 +52,7 @@ impl flags::Scip { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + proc_macro_processes: config.proc_macro_num_processes(), }; let cargo_config = config.cargo(None); let (db, vfs, _) = load_workspace_at( @@ -603,6 +604,29 @@ pub mod example_mod { ); } + #[test] + fn operator_overload() { + check_symbol( + r#" +//- minicore: add +//- /workspace/lib.rs crate:main +use core::ops::AddAssign; + +struct S; + +impl AddAssign for S { + fn add_assign(&mut self, _rhs: Self) {} +} + +fn main() { + let mut s = S; + s +=$0 S; +} +"#, + "rust-analyzer cargo main . impl#[S][`AddAssign`]add_assign().", + ); + } + #[test] fn symbol_for_trait() { check_symbol( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs index 529cf120827d..5c69bda723fb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/ssr.rs @@ -20,6 +20,7 @@ impl flags::Ssr { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (ref db, vfs, _proc_macro) = load_workspace_at( &std::env::current_dir()?, @@ -56,6 +57,7 @@ impl flags::Search { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (ref db, _vfs, _proc_macro) = load_workspace_at( &std::env::current_dir()?, @@ -68,7 +70,7 @@ impl flags::Search { match_finder.add_search_pattern(pattern)?; } if let Some(debug_snippet) = &self.debug { - for &root in ide_db::symbol_index::LocalRoots::get(db).roots(db).iter() { + for &root in ide_db::LocalRoots::get(db).roots(db).iter() { let sr = db.source_root(root).source_root(db); for file_id in sr.iter() { for debug_info in match_finder.debug_where_text_equal( diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs index a400f86778f4..49c6fcb91ebf 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/unresolved_references.rs @@ -44,6 +44,7 @@ impl flags::UnresolvedReferences { load_out_dirs_from_check: !self.disable_build_scripts, with_proc_macro_server, prefill_caches: false, + proc_macro_processes: config.proc_macro_num_processes(), }; let (db, vfs, _proc_macro) = load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?; @@ -64,8 +65,12 @@ impl flags::UnresolvedReferences { let file_id = module.definition_source_file_id(db).original_file(db); let file_id = file_id.file_id(db); if !visited_files.contains(&file_id) { - let crate_name = - module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned(); + let crate_name = module + .krate(db) + .display_name(db) + .as_deref() + .unwrap_or(&sym::unknown) + .to_owned(); let file_path = vfs.file_path(file_id); eprintln!("processing crate: {crate_name}, module: {file_path}",); @@ -93,7 +98,7 @@ impl flags::UnresolvedReferences { fn all_modules(db: &dyn HirDatabase) -> Vec { let mut worklist: Vec<_> = - Crate::all(db).into_iter().map(|krate| krate.root_module()).collect(); + Crate::all(db).into_iter().map(|krate| krate.root_module(db)).collect(); let mut modules = Vec::new(); while let Some(module) = worklist.pop() { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs index 2f052618cdfa..49ce6db4ea9a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs @@ -10,6 +10,7 @@ use std::{ process::{ChildStderr, ChildStdout, Command, Stdio}, }; +use anyhow::Context; use crossbeam_channel::Sender; use paths::Utf8PathBuf; use process_wrap::std::{StdChildWrapper, StdCommandWrap}; @@ -156,7 +157,7 @@ impl CommandHandle { parser: impl JsonLinesParser, sender: Sender, out_file: Option, - ) -> std::io::Result { + ) -> anyhow::Result { command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null()); let program = command.get_program().into(); @@ -168,7 +169,10 @@ impl CommandHandle { child.wrap(process_wrap::std::ProcessSession); #[cfg(windows)] child.wrap(process_wrap::std::JobObject); - let mut child = child.spawn().map(JodGroupChild)?; + let mut child = child + .spawn() + .map(JodGroupChild) + .with_context(|| "Failed to spawn command: {child:?}")?; let stdout = child.0.stdout().take().unwrap(); let stderr = child.0.stderr().take().unwrap(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index c380621d81a1..0dda7f3cc276 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -280,6 +280,9 @@ config_data! { /// Show function parameter name inlay hints at the call site. inlayHints_parameterHints_enable: bool = true, + /// Show parameter name inlay hints for missing arguments at the call site. + inlayHints_parameterHints_missingArguments_enable: bool = false, + /// Show exclusive range inlay hints. inlayHints_rangeExclusiveHints_enable: bool = false, @@ -304,6 +307,9 @@ config_data! { /// Hide inlay parameter type hints for closures. inlayHints_typeHints_hideClosureParameter: bool = false, + /// Hide inlay type hints for inferred types. + inlayHints_typeHints_hideInferredTypes: bool = false, + /// Hide inlay type hints for constructors. inlayHints_typeHints_hideNamedConstructor: bool = false, @@ -381,6 +387,12 @@ config_data! { /// Enable support for procedural macros, implies `#rust-analyzer.cargo.buildScripts.enable#`. procMacro_enable: bool = true, + /// Number of proc-macro server processes to spawn. + /// + /// Controls how many independent `proc-macro-srv` processes rust-analyzer + /// runs in parallel to handle macro expansion. + procMacro_processes: NumProcesses = NumProcesses::Concrete(1), + /// Internal config, path to proc-macro server executable. procMacro_server: Option = None, @@ -472,33 +484,83 @@ config_data! { typing_triggerChars: Option = Some("=.".to_owned()), - /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. + /// Configure a command that rust-analyzer can invoke to + /// obtain configuration. /// - /// [`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`. - /// `progress_label` is used for the title in progress indicators, whereas `files_to_watch` - /// is used to determine which build system-specific files should be watched in order to - /// reload rust-analyzer. + /// This is an alternative to manually generating + /// `rust-project.json`: it enables rust-analyzer to generate + /// rust-project.json on the fly, and regenerate it when + /// switching or modifying projects. + /// + /// This is an object with three fields: + /// + /// * `command`: the shell command to invoke + /// + /// * `filesToWatch`: which build system-specific files should + /// be watched to trigger regenerating the configuration + /// + /// * `progressLabel`: the name of the command, used in + /// progress indicators in the IDE + /// + /// Here's an example of a valid configuration: /// - /// Below is an example of a valid configuration: /// ```json /// "rust-analyzer.workspace.discoverConfig": { /// "command": [ /// "rust-project", - /// "develop-json" + /// "develop-json", + /// "{arg}" /// ], - /// "progressLabel": "rust-analyzer", + /// "progressLabel": "buck2/rust-project", /// "filesToWatch": [ /// "BUCK" /// ] /// } /// ``` /// - /// ## On `DiscoverWorkspaceConfig::command` + /// ## Argument Substitutions + /// + /// If `command` includes the argument `{arg}`, that argument will be substituted + /// with the JSON-serialized form of the following enum: + /// + /// ```norun + /// #[derive(PartialEq, Clone, Debug, Serialize)] + /// #[serde(rename_all = "camelCase")] + /// pub enum DiscoverArgument { + /// Path(AbsPathBuf), + /// Buildfile(AbsPathBuf), + /// } + /// ``` + /// + /// rust-analyzer will use the path invocation to find and + /// generate a `rust-project.json` and therefore a + /// workspace. Example: + /// + /// + /// ```norun + /// rust-project develop-json '{ "path": "myproject/src/main.rs" }' + /// ``` + /// + /// rust-analyzer will use build file invocations to update an + /// existing workspace. Example: + /// + /// Or with a build file and the configuration above: + /// + /// ```norun + /// rust-project develop-json '{ "buildfile": "myproject/BUCK" }' + /// ``` + /// + /// As a reference for implementors, buck2's `rust-project` + /// will likely be useful: + /// . + /// + /// ## Discover Command Output /// /// **Warning**: This format is provisional and subject to change. /// - /// [`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to - /// `DiscoverProjectData::Finished`: + /// The discover command should output JSON objects, one per + /// line (JSONL format). These objects should correspond to + /// this Rust data type: /// /// ```norun /// #[derive(Debug, Clone, Deserialize, Serialize)] @@ -511,7 +573,14 @@ config_data! { /// } /// ``` /// - /// As JSON, `DiscoverProjectData::Finished` is: + /// For example, a progress event: + /// + /// ```json + /// {"kind":"progress","message":"generating rust-project.json"} + /// ``` + /// + /// A finished event can look like this (expanded and + /// commented for readability): /// /// ```json /// { @@ -519,7 +588,7 @@ config_data! { /// "kind": "finished", /// // the file used by a non-Cargo build system to define /// // a package or target. - /// "buildfile": "rust-analyzer/BUILD", + /// "buildfile": "rust-analyzer/BUCK", /// // the contents of a rust-project.json, elided for brevity /// "project": { /// "sysroot": "foo", @@ -528,41 +597,9 @@ config_data! { /// } /// ``` /// - /// It is encouraged, but not required, to use the other variants on `DiscoverProjectData` - /// to provide a more polished end-user experience. - /// - /// `DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be - /// substituted with the JSON-serialized form of the following enum: - /// - /// ```norun - /// #[derive(PartialEq, Clone, Debug, Serialize)] - /// #[serde(rename_all = "camelCase")] - /// pub enum DiscoverArgument { - /// Path(AbsPathBuf), - /// Buildfile(AbsPathBuf), - /// } - /// ``` - /// - /// The JSON representation of `DiscoverArgument::Path` is: - /// - /// ```json - /// { - /// "path": "src/main.rs" - /// } - /// ``` - /// - /// Similarly, the JSON representation of `DiscoverArgument::Buildfile` is: - /// - /// ```json - /// { - /// "buildfile": "BUILD" - /// } - /// ``` - /// - /// `DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and - /// therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an - /// existing workspace. As a reference for implementors, buck2's `rust-project` will likely - /// be useful: . + /// Only the finished event is required, but the other + /// variants are encouraged to give users more feedback about + /// progress or errors. workspace_discoverConfig: Option = None, } } @@ -719,6 +756,9 @@ config_data! { /// /// E.g. `use ::std::io::Read;`. imports_prefixExternPrelude: bool = false, + + /// Whether to warn when a rename will cause conflicts (change the meaning of the code). + rename_showConflicts: bool = true, } } @@ -861,10 +901,18 @@ config_data! { /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten /// by changing `#rust-analyzer.check.invocationStrategy#`. /// - /// If `$saved_file` is part of the command, rust-analyzer will pass - /// the absolute path of the saved file to the provided command. This is - /// intended to be used with non-Cargo build systems. - /// Note that `$saved_file` is experimental and may be removed in the future. + /// It supports two interpolation syntaxes, both mainly intended to be used with + /// [non-Cargo build systems](./non_cargo_based_projects.md): + /// + /// - If `{saved_file}` is part of the command, rust-analyzer will pass + /// the absolute path of the saved file to the provided command. + /// (A previous version, `$saved_file`, also works.) + /// - If `{label}` is part of the command, rust-analyzer will pass the + /// Cargo package ID, which can be used with `cargo check -p`, or a build label from + /// `rust-project.json`. If `{label}` is included, rust-analyzer behaves much like + /// [`"rust-analyzer.check.workspace": false`](#check.workspace). + /// + /// /// /// An example command would be: /// @@ -895,8 +943,24 @@ config_data! { /// This config takes a map of crate names with the exported proc-macro names to ignore as values. procMacro_ignored: FxHashMap, Box<[Box]>> = FxHashMap::default(), + /// Subcommand used for bench runnables instead of `bench`. + runnables_bench_command: String = "bench".to_owned(), + /// Override the command used for bench runnables. + /// The first element of the array should be the program to execute (for example, `cargo`). + /// + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// replace the package name, target option (such as `--bin` or `--example`), the target name and + /// the test name (name of test function or test mod path). + runnables_bench_overrideCommand: Option> = None, /// Command to be executed instead of 'cargo' for runnables. runnables_command: Option = None, + /// Override the command used for bench runnables. + /// The first element of the array should be the program to execute (for example, `cargo`). + /// + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// replace the package name, target option (such as `--bin` or `--example`), the target name and + /// the test name (name of test function or test mod path). + runnables_doctest_overrideCommand: Option> = None, /// Additional arguments to be passed to cargo for runnables such as /// tests or binaries. For example, it may be `--release`. runnables_extraArgs: Vec = vec![], @@ -908,6 +972,15 @@ config_data! { /// they will end up being interpreted as options to /// [`rustc`’s built-in test harness (“libtestâ€)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). runnables_extraTestBinaryArgs: Vec = vec!["--nocapture".to_owned()], + /// Subcommand used for test runnables instead of `test`. + runnables_test_command: String = "test".to_owned(), + /// Override the command used for test runnables. + /// The first element of the array should be the program to execute (for example, `cargo`). + /// + /// Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically + /// replace the package name, target option (such as `--bin` or `--example`), the target name and + /// the test name (name of test function or test mod path). + runnables_test_overrideCommand: Option> = None, /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private /// projects, or "discover" to try to automatically find it if the `rustc-dev` component @@ -1000,6 +1073,7 @@ pub struct Config { /// The workspace roots as registered by the LSP client workspace_roots: Vec, caps: ClientCapabilities, + /// The LSP root path, deprecated in favor of `workspace_roots` root_path: AbsPathBuf, snippets: Vec, client_info: Option, @@ -1323,6 +1397,10 @@ impl Config { self.discovered_projects_from_command.push(ProjectJsonFromCommand { data, buildfile }); } + + pub fn workspace_roots(&self) -> &[AbsPathBuf] { + &self.workspace_roots + } } #[derive(Default, Debug)] @@ -1559,6 +1637,16 @@ pub struct RunnablesConfig { pub cargo_extra_args: Vec, /// Additional arguments for the binary being run, if it is a test or benchmark. pub extra_test_binary_args: Vec, + /// Subcommand used for doctest runnables instead of `test`. + pub test_command: String, + /// Override the command used for test runnables. + pub test_override_command: Option>, + /// Subcommand used for doctest runnables instead of `bench`. + pub bench_command: String, + /// Override the command used for bench runnables. + pub bench_override_command: Option>, + /// Override the command used for doctest runnables. + pub doc_test_override_command: Option>, } /// Configuration for workspace symbol search requests. @@ -1689,15 +1777,14 @@ impl Config { } pub fn root_path(&self) -> &AbsPathBuf { + // We should probably use `workspace_roots` here if set &self.root_path } pub fn caps(&self) -> &ClientCapabilities { &self.caps } -} -impl Config { pub fn assist(&self, source_root: Option) -> AssistConfig { AssistConfig { snippet_cap: self.snippet_cap(), @@ -1716,6 +1803,7 @@ impl Config { ExprFillDefaultDef::Underscore => ExprFillDefaultMode::Underscore, }, prefer_self_ty: *self.assist_preferSelf(source_root), + show_rename_conflicts: *self.rename_showConflicts(source_root), } } @@ -1724,6 +1812,7 @@ impl Config { prefer_no_std: self.imports_preferNoStd(source_root).to_owned(), prefer_prelude: self.imports_preferPrelude(source_root).to_owned(), prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(), + show_conflicts: *self.rename_showConflicts(source_root), } } @@ -1823,6 +1912,7 @@ impl Config { style_lints: self.diagnostics_styleLints_enable(source_root).to_owned(), term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64, term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(), + show_rename_conflicts: *self.rename_showConflicts(source_root), } } @@ -1913,6 +2003,9 @@ impl Config { type_hints: self.inlayHints_typeHints_enable().to_owned(), sized_bound: self.inlayHints_implicitSizedBoundHints_enable().to_owned(), parameter_hints: self.inlayHints_parameterHints_enable().to_owned(), + parameter_hints_for_missing_arguments: self + .inlayHints_parameterHints_missingArguments_enable() + .to_owned(), generic_parameter_hints: GenericParameterHints { type_hints: self.inlayHints_genericParameterHints_type_enable().to_owned(), lifetime_hints: self.inlayHints_genericParameterHints_lifetime_enable().to_owned(), @@ -1937,6 +2030,7 @@ impl Config { hide_named_constructor_hints: self .inlayHints_typeHints_hideNamedConstructor() .to_owned(), + hide_inferred_type_hints: self.inlayHints_typeHints_hideInferredTypes().to_owned(), hide_closure_initialization_hints: self .inlayHints_typeHints_hideClosureInitialization() .to_owned(), @@ -2382,6 +2476,8 @@ impl Config { pub(crate) fn cargo_test_options(&self, source_root: Option) -> CargoOptions { CargoOptions { + // Might be nice to allow users to specify test_command = "nextest" + subcommand: "test".into(), target_tuples: self.cargo_target(source_root).clone().into_iter().collect(), all_targets: false, no_default_features: *self.cargo_noDefaultFeatures(source_root), @@ -2415,9 +2511,9 @@ impl Config { }, } } - Some(_) | None => FlycheckConfig::CargoCommand { - command: self.check_command(source_root).clone(), - options: CargoOptions { + Some(_) | None => FlycheckConfig::Automatic { + cargo_options: CargoOptions { + subcommand: self.check_command(source_root).clone(), target_tuples: self .check_targets(source_root) .clone() @@ -2480,6 +2576,11 @@ impl Config { override_cargo: self.runnables_command(source_root).clone(), cargo_extra_args: self.runnables_extraArgs(source_root).clone(), extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(), + test_command: self.runnables_test_command(source_root).clone(), + test_override_command: self.runnables_test_overrideCommand(source_root).clone(), + bench_command: self.runnables_bench_command(source_root).clone(), + bench_override_command: self.runnables_bench_overrideCommand(source_root).clone(), + doc_test_override_command: self.runnables_doctest_overrideCommand(source_root).clone(), } } @@ -2576,6 +2677,13 @@ impl Config { } } + pub fn proc_macro_num_processes(&self) -> usize { + match self.procMacro_processes() { + NumProcesses::Concrete(0) | NumProcesses::Physical => num_cpus::get_physical(), + &NumProcesses::Concrete(n) => n, + } + } + pub fn main_loop_num_threads(&self) -> usize { match self.numThreads() { Some(NumThreads::Concrete(0)) | None | Some(NumThreads::Physical) => { @@ -3012,6 +3120,14 @@ pub enum NumThreads { Concrete(usize), } +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum NumProcesses { + Physical, + #[serde(untagged)] + Concrete(usize), +} + macro_rules! _default_val { ($default:expr, $ty:ty) => {{ let default_: $ty = $default; @@ -3838,6 +3954,22 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json }, ], }, + "NumProcesses" => set! { + "anyOf": [ + { + "type": "number", + "minimum": 0, + "maximum": 255 + }, + { + "type": "string", + "enum": ["physical"], + "enumDescriptions": [ + "Use the number of physical cores", + ], + }, + ], + }, "Option" => set! { "anyOf": [ { @@ -4117,8 +4249,8 @@ mod tests { assert_eq!(config.cargo_targetDir(None), &None); assert!(matches!( config.flycheck(None), - FlycheckConfig::CargoCommand { - options: CargoOptions { target_dir_config: TargetDirectoryConfig::None, .. }, + FlycheckConfig::Automatic { + cargo_options: CargoOptions { target_dir_config: TargetDirectoryConfig::None, .. }, .. } )); @@ -4141,8 +4273,8 @@ mod tests { Utf8PathBuf::from(std::env::var("CARGO_TARGET_DIR").unwrap_or("target".to_owned())); assert!(matches!( config.flycheck(None), - FlycheckConfig::CargoCommand { - options: CargoOptions { target_dir_config, .. }, + FlycheckConfig::Automatic { + cargo_options: CargoOptions { target_dir_config, .. }, .. } if target_dir_config.target_dir(Some(&ws_target_dir)).map(Cow::into_owned) == Some(ws_target_dir.join("rust-analyzer")) @@ -4167,8 +4299,8 @@ mod tests { ); assert!(matches!( config.flycheck(None), - FlycheckConfig::CargoCommand { - options: CargoOptions { target_dir_config, .. }, + FlycheckConfig::Automatic { + cargo_options: CargoOptions { target_dir_config, .. }, .. } if target_dir_config.target_dir(None).map(Cow::into_owned) == Some(Utf8PathBuf::from("other_folder")) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs index 389bb7848c01..5dc463eccce4 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config/patch_old_style.rs @@ -3,7 +3,7 @@ use serde_json::{Value, json}; /// This function patches the json config to the new expected keys. /// That is we try to load old known config keys here and convert them to the new ones. -/// See https://github.com/rust-lang/rust-analyzer/pull/12010 +/// See /// /// We already have an alias system for simple cases, but if we make structural changes /// the alias infra fails down. diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs index 4a247800af9d..8d0f52433e02 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs @@ -3,7 +3,6 @@ pub(crate) mod flycheck_to_proto; use std::mem; -use cargo_metadata::PackageId; use ide::FileId; use ide_db::{FxHashMap, base_db::DbPanicContext}; use itertools::Itertools; @@ -12,10 +11,13 @@ use smallvec::SmallVec; use stdx::iter_eq_by; use triomphe::Arc; -use crate::{global_state::GlobalStateSnapshot, lsp, lsp_ext, main_loop::DiagnosticsTaskKind}; +use crate::{ + flycheck::PackageSpecifier, global_state::GlobalStateSnapshot, lsp, lsp_ext, + main_loop::DiagnosticsTaskKind, +}; pub(crate) type CheckFixes = - Arc>, FxHashMap>>>>; + Arc, FxHashMap>>>>; #[derive(Debug, Default, Clone)] pub struct DiagnosticsMapConfig { @@ -29,7 +31,7 @@ pub(crate) type DiagnosticsGeneration = usize; #[derive(Debug, Clone, Default)] pub(crate) struct WorkspaceFlycheckDiagnostic { - pub(crate) per_package: FxHashMap>, PackageFlycheckDiagnostic>, + pub(crate) per_package: FxHashMap, PackageFlycheckDiagnostic>, } #[derive(Debug, Clone)] @@ -85,7 +87,7 @@ impl DiagnosticCollection { pub(crate) fn clear_check_for_package( &mut self, flycheck_id: usize, - package_id: Arc, + package_id: PackageSpecifier, ) { let Some(check) = self.check.get_mut(flycheck_id) else { return; @@ -124,7 +126,7 @@ impl DiagnosticCollection { pub(crate) fn clear_check_older_than_for_package( &mut self, flycheck_id: usize, - package_id: Arc, + package_id: PackageSpecifier, generation: DiagnosticsGeneration, ) { let Some(check) = self.check.get_mut(flycheck_id) else { @@ -154,7 +156,7 @@ impl DiagnosticCollection { &mut self, flycheck_id: usize, generation: DiagnosticsGeneration, - package_id: &Option>, + package_id: &Option, file_id: FileId, diagnostic: lsp_types::Diagnostic, fix: Option>, @@ -287,34 +289,40 @@ pub(crate) fn fetch_native_diagnostics( let mut diagnostics = subscriptions[slice] .iter() .copied() - .filter_map(|file_id| { - let line_index = snapshot.file_line_index(file_id).ok()?; - let source_root = snapshot.analysis.source_root_id(file_id).ok()?; + .map(|file_id| { + let diagnostics = (|| { + let line_index = snapshot.file_line_index(file_id).ok()?; + let source_root = snapshot.analysis.source_root_id(file_id).ok()?; - let config = &snapshot.config.diagnostics(Some(source_root)); - let diagnostics = match kind { - NativeDiagnosticsFetchKind::Syntax => { - snapshot.analysis.syntax_diagnostics(config, file_id).ok()? - } - - NativeDiagnosticsFetchKind::Semantic if config.enabled => snapshot - .analysis - .semantic_diagnostics(config, ide::AssistResolveStrategy::None, file_id) - .ok()?, - NativeDiagnosticsFetchKind::Semantic => return None, - }; - let diagnostics = diagnostics - .into_iter() - .filter_map(|d| { - if d.range.file_id == file_id { - Some(convert_diagnostic(&line_index, d)) - } else { - odd_ones.push(d); - None + let config = &snapshot.config.diagnostics(Some(source_root)); + let diagnostics = match kind { + NativeDiagnosticsFetchKind::Syntax => { + snapshot.analysis.syntax_diagnostics(config, file_id).ok()? } - }) - .collect::>(); - Some((file_id, diagnostics)) + + NativeDiagnosticsFetchKind::Semantic if config.enabled => snapshot + .analysis + .semantic_diagnostics(config, ide::AssistResolveStrategy::None, file_id) + .ok()?, + NativeDiagnosticsFetchKind::Semantic => return None, + }; + Some( + diagnostics + .into_iter() + .filter_map(|d| { + if d.range.file_id == file_id { + Some(convert_diagnostic(&line_index, d)) + } else { + odd_ones.push(d); + None + } + }) + .collect::>(), + ) + })() + .unwrap_or_default(); + + (file_id, diagnostics) }) .collect::>(); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs index 4aef5b0b7f3d..098b6a4d986d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs @@ -1,6 +1,6 @@ //! Infrastructure for lazy project discovery. Currently only support rust-project.json discovery //! via a custom discover command. -use std::{io, path::Path}; +use std::path::Path; use crossbeam_channel::Sender; use ide_db::FxHashMap; @@ -42,12 +42,12 @@ impl DiscoverCommand { Self { sender, command } } - /// Spawn the command inside [Discover] and report progress, if any. + /// Spawn the command inside `DiscoverCommand` and report progress, if any. pub(crate) fn spawn( &self, discover_arg: DiscoverArgument, current_dir: &Path, - ) -> io::Result { + ) -> anyhow::Result { let command = &self.command[0]; let args = &self.command[1..]; @@ -73,7 +73,7 @@ impl DiscoverCommand { } } -/// A handle to a spawned [Discover]. +/// A handle to a spawned `DiscoverCommand`. #[derive(Debug)] pub(crate) struct DiscoverHandle { pub(crate) handle: CommandHandle, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index 14a4a1752f41..47f7a57f72ec 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -14,6 +14,7 @@ use ide_db::FxHashSet; use itertools::Itertools; use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; use project_model::TargetDirectoryConfig; +use project_model::project_json; use rustc_hash::FxHashMap; use serde::Deserialize as _; use serde_derive::Deserialize; @@ -36,8 +37,11 @@ pub(crate) enum InvocationStrategy { PerWorkspace, } +/// Data needed to construct a `cargo` command invocation, e.g. for flycheck or running a test. #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct CargoOptions { + /// The cargo subcommand to run, e.g. "check" or "clippy" + pub(crate) subcommand: String, pub(crate) target_tuples: Vec, pub(crate) all_targets: bool, pub(crate) set_test: bool, @@ -89,13 +93,36 @@ impl CargoOptions { } } +/// The flycheck config from a rust-project.json file or discoverConfig JSON output. +#[derive(Debug, Default)] +pub(crate) struct FlycheckConfigJson { + /// The template with [project_json::RunnableKind::Flycheck] + pub single_template: Option, +} + +impl FlycheckConfigJson { + pub(crate) fn any_configured(&self) -> bool { + // self.workspace_template.is_some() || + self.single_template.is_some() + } +} + +/// The flycheck config from rust-analyzer's own configuration. +/// +/// We rely on this when rust-project.json does not specify a flycheck runnable +/// #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) enum FlycheckConfig { - CargoCommand { - command: String, - options: CargoOptions, + /// Automatically use rust-project.json's flycheck runnable or just use cargo (the common case) + /// + /// We can't have a variant for ProjectJson because that is configured on the fly during + /// discoverConfig. We only know what we can read at config time. + Automatic { + /// If we do use cargo, how to build the check command + cargo_options: CargoOptions, ansi_color_output: bool, }, + /// check_overrideCommand. This overrides both cargo and rust-project.json's flycheck runnable. CustomCommand { command: String, args: Vec, @@ -107,7 +134,7 @@ pub(crate) enum FlycheckConfig { impl FlycheckConfig { pub(crate) fn invocation_strategy(&self) -> InvocationStrategy { match self { - FlycheckConfig::CargoCommand { .. } => InvocationStrategy::PerWorkspace, + FlycheckConfig::Automatic { .. } => InvocationStrategy::PerWorkspace, FlycheckConfig::CustomCommand { invocation_strategy, .. } => { invocation_strategy.clone() } @@ -116,19 +143,33 @@ impl FlycheckConfig { } impl fmt::Display for FlycheckConfig { + /// Show a shortened version of the check command. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - FlycheckConfig::CargoCommand { command, .. } => write!(f, "cargo {command}"), + FlycheckConfig::Automatic { cargo_options, .. } => { + write!(f, "cargo {}", cargo_options.subcommand) + } FlycheckConfig::CustomCommand { command, args, .. } => { // Don't show `my_custom_check --foo $saved_file` literally to the user, as it // looks like we've forgotten to substitute $saved_file. // + // `my_custom_check --foo /home/user/project/src/dir/foo.rs` is too verbose. + // // Instead, show `my_custom_check --foo ...`. The // actual path is often too long to be worth showing // in the IDE (e.g. in the VS Code status bar). let display_args = args .iter() - .map(|arg| if arg == SAVED_FILE_PLACEHOLDER { "..." } else { arg }) + .map(|arg| { + if (arg == SAVED_FILE_PLACEHOLDER_DOLLAR) + || (arg == SAVED_FILE_INLINE) + || arg.ends_with(".rs") + { + "..." + } else { + arg + } + }) .collect::>(); write!(f, "{command} {}", display_args.join(" ")) @@ -147,15 +188,16 @@ pub(crate) struct FlycheckHandle { sender: Sender, _thread: stdx::thread::JoinHandle, id: usize, - generation: AtomicUsize, + generation: Arc, } impl FlycheckHandle { pub(crate) fn spawn( id: usize, - generation: DiagnosticsGeneration, + generation: Arc, sender: Sender, config: FlycheckConfig, + config_json: FlycheckConfigJson, sysroot_root: Option, workspace_root: AbsPathBuf, manifest_path: Option, @@ -163,9 +205,10 @@ impl FlycheckHandle { ) -> FlycheckHandle { let actor = FlycheckActor::new( id, - generation, + generation.load(Ordering::Relaxed), sender, config, + config_json, sysroot_root, workspace_root, manifest_path, @@ -176,7 +219,7 @@ impl FlycheckHandle { stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, format!("Flycheck{id}")) .spawn(move || actor.run(receiver)) .expect("failed to spawn thread"); - FlycheckHandle { id, generation: generation.into(), sender, _thread: thread } + FlycheckHandle { id, generation, sender, _thread: thread } } /// Schedule a re-start of the cargo check worker to do a workspace wide check. @@ -195,16 +238,17 @@ impl FlycheckHandle { /// Schedule a re-start of the cargo check worker to do a package wide check. pub(crate) fn restart_for_package( &self, - package: Arc, + package: PackageSpecifier, target: Option, - workspace_deps: Option>>, + workspace_deps: Option>, + saved_file: Option, ) { let generation = self.generation.fetch_add(1, Ordering::Relaxed) + 1; self.sender .send(StateChange::Restart { generation, scope: FlycheckScope::Package { package, workspace_deps }, - saved_file: None, + saved_file, target, }) .unwrap(); @@ -233,7 +277,7 @@ pub(crate) enum ClearDiagnosticsKind { #[derive(Debug)] pub(crate) enum ClearScope { Workspace, - Package(Arc), + Package(PackageSpecifier), } pub(crate) enum FlycheckMessage { @@ -243,7 +287,7 @@ pub(crate) enum FlycheckMessage { generation: DiagnosticsGeneration, workspace_root: Arc, diagnostic: Diagnostic, - package_id: Option>, + package_id: Option, }, /// Request clearing all outdated diagnostics. @@ -286,16 +330,56 @@ impl fmt::Debug for FlycheckMessage { #[derive(Debug)] pub(crate) enum Progress { - DidStart, + DidStart { + /// The user sees this in VSCode, etc. May be a shortened version of the command we actually + /// executed, otherwise it is way too long. + user_facing_command: String, + }, DidCheckCrate(String), DidFinish(io::Result<()>), DidCancel, DidFailToRestart(String), } +#[derive(Debug, Clone)] enum FlycheckScope { Workspace, - Package { package: Arc, workspace_deps: Option>> }, + Package { + // Either a cargo package or a $label in rust-project.check.overrideCommand + package: PackageSpecifier, + workspace_deps: Option>, + }, +} + +#[derive(Debug, Hash, PartialEq, Eq, Clone)] +pub(crate) enum PackageSpecifier { + Cargo { + /// The one in Cargo.toml, assumed to work with `cargo check -p {}` etc + package_id: Arc, + }, + BuildInfo { + /// If a `build` field is present in rust-project.json, its label field + label: String, + }, +} + +impl PackageSpecifier { + pub(crate) fn as_str(&self) -> &str { + match self { + Self::Cargo { package_id } => &package_id.repr, + Self::BuildInfo { label } => label, + } + } +} + +#[derive(Debug)] +enum FlycheckCommandOrigin { + /// Regular cargo invocation + Cargo, + /// Configured via check_overrideCommand + CheckOverrideCommand, + /// From a runnable with [project_json::RunnableKind::Flycheck] + ProjectJsonRunnable, } enum StateChange { @@ -316,6 +400,8 @@ struct FlycheckActor { generation: DiagnosticsGeneration, sender: Sender, config: FlycheckConfig, + config_json: FlycheckConfigJson, + manifest_path: Option, ws_target_dir: Option, /// Either the workspace root of the workspace we are flychecking, @@ -328,27 +414,92 @@ struct FlycheckActor { /// doesn't provide a way to read sub-process output without blocking, so we /// have to wrap sub-processes output handling in a thread and pass messages /// back over a channel. - command_handle: Option>, + command_handle: Option>, /// The receiver side of the channel mentioned above. - command_receiver: Option>, - diagnostics_cleared_for: FxHashSet>, + command_receiver: Option>, + diagnostics_cleared_for: FxHashSet, diagnostics_received: DiagnosticsReceived, } -#[derive(PartialEq)] +#[derive(PartialEq, Debug)] enum DiagnosticsReceived { - Yes, - No, - YesAndClearedForAll, + /// We started a flycheck, but we haven't seen any diagnostics yet. + NotYet, + /// We received a non-zero number of diagnostics from rustc or clippy (via + /// cargo or custom check command). This means there were errors or + /// warnings. + AtLeastOne, + /// We received a non-zero number of diagnostics, and the scope is + /// workspace, so we've discarded the previous workspace diagnostics. + AtLeastOneAndClearedWorkspace, } #[allow(clippy::large_enum_variant)] enum Event { RequestStateChange(StateChange), - CheckEvent(Option), + CheckEvent(Option), } -pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file"; +/// This is stable behaviour. Don't change. +const SAVED_FILE_PLACEHOLDER_DOLLAR: &str = "$saved_file"; +const LABEL_INLINE: &str = "{label}"; +const SAVED_FILE_INLINE: &str = "{saved_file}"; + +struct Substitutions<'a> { + label: Option<&'a str>, + saved_file: Option<&'a str>, +} + +impl<'a> Substitutions<'a> { + /// If you have a runnable, and it has {label} in it somewhere, treat it as a template that + /// may be unsatisfied if you do not provide a label to substitute into it. Returns None in + /// that situation. Otherwise performs the requested substitutions. + /// + /// Same for {saved_file}. + /// + #[allow(clippy::disallowed_types)] /* generic parameter allows for FxHashMap */ + fn substitute( + self, + template: &project_json::Runnable, + extra_env: &std::collections::HashMap, H>, + ) -> Option { + let mut cmd = toolchain::command(&template.program, &template.cwd, extra_env); + for arg in &template.args { + if let Some(ix) = arg.find(LABEL_INLINE) { + if let Some(label) = self.label { + let mut arg = arg.to_string(); + arg.replace_range(ix..ix + LABEL_INLINE.len(), label); + cmd.arg(arg); + continue; + } else { + return None; + } + } + if let Some(ix) = arg.find(SAVED_FILE_INLINE) { + if let Some(saved_file) = self.saved_file { + let mut arg = arg.to_string(); + arg.replace_range(ix..ix + SAVED_FILE_INLINE.len(), saved_file); + cmd.arg(arg); + continue; + } else { + return None; + } + } + // Legacy syntax: full argument match + if arg == SAVED_FILE_PLACEHOLDER_DOLLAR { + if let Some(saved_file) = self.saved_file { + cmd.arg(saved_file); + continue; + } else { + return None; + } + } + cmd.arg(arg); + } + cmd.current_dir(&template.cwd); + Some(cmd) + } +} impl FlycheckActor { fn new( @@ -356,6 +507,7 @@ impl FlycheckActor { generation: DiagnosticsGeneration, sender: Sender, config: FlycheckConfig, + config_json: FlycheckConfigJson, sysroot_root: Option, workspace_root: AbsPathBuf, manifest_path: Option, @@ -367,6 +519,7 @@ impl FlycheckActor { generation, sender, config, + config_json, sysroot_root, root: Arc::new(workspace_root), scope: FlycheckScope::Workspace, @@ -375,7 +528,7 @@ impl FlycheckActor { command_handle: None, command_receiver: None, diagnostics_cleared_for: Default::default(), - diagnostics_received: DiagnosticsReceived::No, + diagnostics_received: DiagnosticsReceived::NotYet, } } @@ -418,27 +571,29 @@ impl FlycheckActor { } let command = self.check_command(&scope, saved_file.as_deref(), target); - self.scope = scope; + self.scope = scope.clone(); self.generation = generation; - let Some(command) = command else { + let Some((command, origin)) = command else { + tracing::debug!(?scope, "failed to build flycheck command"); continue; }; - let formatted_command = format!("{command:?}"); + let debug_command = format!("{command:?}"); + let user_facing_command = self.config.to_string(); - tracing::debug!(?command, "will restart flycheck"); + tracing::debug!(?origin, ?command, "will restart flycheck"); let (sender, receiver) = unbounded(); match CommandHandle::spawn( command, - CargoCheckParser, + CheckParser, sender, match &self.config { - FlycheckConfig::CargoCommand { options, .. } => { + FlycheckConfig::Automatic { cargo_options, .. } => { let ws_target_dir = self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path); let target_dir = - options.target_dir_config.target_dir(ws_target_dir); + cargo_options.target_dir_config.target_dir(ws_target_dir); // If `"rust-analyzer.cargo.targetDir": null`, we should use // workspace's target dir instead of hard-coded fallback. @@ -464,14 +619,14 @@ impl FlycheckActor { }, ) { Ok(command_handle) => { - tracing::debug!(command = formatted_command, "did restart flycheck"); + tracing::debug!(?origin, command = %debug_command, "did restart flycheck"); self.command_handle = Some(command_handle); self.command_receiver = Some(receiver); - self.report_progress(Progress::DidStart); + self.report_progress(Progress::DidStart { user_facing_command }); } Err(error) => { self.report_progress(Progress::DidFailToRestart(format!( - "Failed to run the following command: {formatted_command} error={error}" + "Failed to run the following command: {debug_command} origin={origin:?} error={error}" ))); } } @@ -492,7 +647,7 @@ impl FlycheckActor { error ); } - if self.diagnostics_received == DiagnosticsReceived::No { + if self.diagnostics_received == DiagnosticsReceived::NotYet { tracing::trace!(flycheck_id = self.id, "clearing diagnostics"); // We finished without receiving any diagnostics. // Clear everything for good measure @@ -551,7 +706,7 @@ impl FlycheckActor { self.report_progress(Progress::DidFinish(res)); } Event::CheckEvent(Some(message)) => match message { - CargoCheckMessage::CompilerArtifact(msg) => { + CheckMessage::CompilerArtifact(msg) => { tracing::trace!( flycheck_id = self.id, artifact = msg.target.name, @@ -564,7 +719,10 @@ impl FlycheckActor { msg.target.kind.iter().format_with(", ", |kind, f| f(&kind)), ))); let package_id = Arc::new(msg.package_id); - if self.diagnostics_cleared_for.insert(package_id.clone()) { + if self + .diagnostics_cleared_for + .insert(PackageSpecifier::Cargo { package_id: package_id.clone() }) + { tracing::trace!( flycheck_id = self.id, package_id = package_id.repr, @@ -572,25 +730,27 @@ impl FlycheckActor { ); self.send(FlycheckMessage::ClearDiagnostics { id: self.id, - kind: ClearDiagnosticsKind::All(ClearScope::Package(package_id)), + kind: ClearDiagnosticsKind::All(ClearScope::Package( + PackageSpecifier::Cargo { package_id }, + )), }); } } - CargoCheckMessage::Diagnostic { diagnostic, package_id } => { + CheckMessage::Diagnostic { diagnostic, package_id } => { tracing::trace!( flycheck_id = self.id, message = diagnostic.message, - package_id = package_id.as_ref().map(|it| &it.repr), + package_id = package_id.as_ref().map(|it| it.as_str()), "diagnostic received" ); - if self.diagnostics_received == DiagnosticsReceived::No { - self.diagnostics_received = DiagnosticsReceived::Yes; + if self.diagnostics_received == DiagnosticsReceived::NotYet { + self.diagnostics_received = DiagnosticsReceived::AtLeastOne; } if let Some(package_id) = &package_id { if self.diagnostics_cleared_for.insert(package_id.clone()) { tracing::trace!( flycheck_id = self.id, - package_id = package_id.repr, + package_id = package_id.as_str(), "clearing diagnostics" ); self.send(FlycheckMessage::ClearDiagnostics { @@ -601,9 +761,10 @@ impl FlycheckActor { }); } } else if self.diagnostics_received - != DiagnosticsReceived::YesAndClearedForAll + != DiagnosticsReceived::AtLeastOneAndClearedWorkspace { - self.diagnostics_received = DiagnosticsReceived::YesAndClearedForAll; + self.diagnostics_received = + DiagnosticsReceived::AtLeastOneAndClearedWorkspace; self.send(FlycheckMessage::ClearDiagnostics { id: self.id, kind: ClearDiagnosticsKind::All(ClearScope::Workspace), @@ -639,7 +800,30 @@ impl FlycheckActor { fn clear_diagnostics_state(&mut self) { self.diagnostics_cleared_for.clear(); - self.diagnostics_received = DiagnosticsReceived::No; + self.diagnostics_received = DiagnosticsReceived::NotYet; + } + + fn explicit_check_command( + &self, + scope: &FlycheckScope, + saved_file: Option<&AbsPath>, + ) -> Option { + let label = match scope { + // We could add a runnable like "RunnableKind::FlycheckWorkspace". But generally + // if you're not running cargo, it's because your workspace is too big to check + // all at once. You can always use `check_overrideCommand` with no {label}. + FlycheckScope::Workspace => return None, + FlycheckScope::Package { package: PackageSpecifier::BuildInfo { label }, .. } => { + label.as_str() + } + FlycheckScope::Package { + package: PackageSpecifier::Cargo { package_id: label }, + .. + } => &label.repr, + }; + let template = self.config_json.single_template.as_ref()?; + let subs = Substitutions { label: Some(label), saved_file: saved_file.map(|x| x.as_str()) }; + subs.substitute(template, &FxHashMap::default()) } /// Construct a `Command` object for checking the user's code. If the user @@ -650,23 +834,49 @@ impl FlycheckActor { scope: &FlycheckScope, saved_file: Option<&AbsPath>, target: Option, - ) -> Option { + ) -> Option<(Command, FlycheckCommandOrigin)> { match &self.config { - FlycheckConfig::CargoCommand { command, options, ansi_color_output } => { + FlycheckConfig::Automatic { cargo_options, ansi_color_output } => { + // Only use the rust-project.json's flycheck config when no check_overrideCommand + // is configured. In the FlycheckConcig::CustomCommand branch we will still do + // label substitution, but on the overrideCommand instead. + // + // There needs to be SOME way to override what your discoverConfig tool says, + // because to change the flycheck runnable there you may have to literally + // recompile the tool. + if self.config_json.any_configured() { + // Completely handle according to rust-project.json. + // We don't consider this to be "using cargo" so we will not apply any of the + // CargoOptions to the command. + let cmd = self.explicit_check_command(scope, saved_file)?; + return Some((cmd, FlycheckCommandOrigin::ProjectJsonRunnable)); + } + let mut cmd = - toolchain::command(Tool::Cargo.path(), &*self.root, &options.extra_env); + toolchain::command(Tool::Cargo.path(), &*self.root, &cargo_options.extra_env); if let Some(sysroot_root) = &self.sysroot_root - && !options.extra_env.contains_key("RUSTUP_TOOLCHAIN") + && !cargo_options.extra_env.contains_key("RUSTUP_TOOLCHAIN") && std::env::var_os("RUSTUP_TOOLCHAIN").is_none() { cmd.env("RUSTUP_TOOLCHAIN", AsRef::::as_ref(sysroot_root)); } cmd.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info"); - cmd.arg(command); + cmd.arg(&cargo_options.subcommand); match scope { FlycheckScope::Workspace => cmd.arg("--workspace"), - FlycheckScope::Package { package, .. } => cmd.arg("-p").arg(&package.repr), + FlycheckScope::Package { + package: PackageSpecifier::Cargo { package_id }, + .. + } => cmd.arg("-p").arg(&package_id.repr), + FlycheckScope::Package { + package: PackageSpecifier::BuildInfo { .. }, .. + } => { + // No way to flycheck this single package. All we have is a build label. + // There's no way to really say whether this build label happens to be + // a cargo canonical name, so we won't try. + return None; + } }; if let Some(tgt) = target { @@ -695,12 +905,12 @@ impl FlycheckActor { cmd.arg("--keep-going"); - options.apply_on_command( + cargo_options.apply_on_command( &mut cmd, self.ws_target_dir.as_ref().map(Utf8PathBuf::as_path), ); - cmd.args(&options.extra_args); - Some(cmd) + cmd.args(&cargo_options.extra_args); + Some((cmd, FlycheckCommandOrigin::Cargo)) } FlycheckConfig::CustomCommand { command, args, extra_env, invocation_strategy } => { let root = match invocation_strategy { @@ -710,31 +920,25 @@ impl FlycheckActor { &*self.root } }; - let mut cmd = toolchain::command(command, root, extra_env); + let runnable = project_json::Runnable { + program: command.clone(), + cwd: Utf8Path::to_owned(root.as_ref()), + args: args.clone(), + kind: project_json::RunnableKind::Flycheck, + }; - // If the custom command has a $saved_file placeholder, and - // we're saving a file, replace the placeholder in the arguments. - if let Some(saved_file) = saved_file { - for arg in args { - if arg == SAVED_FILE_PLACEHOLDER { - cmd.arg(saved_file); - } else { - cmd.arg(arg); - } - } - } else { - for arg in args { - if arg == SAVED_FILE_PLACEHOLDER { - // The custom command has a $saved_file placeholder, - // but we had an IDE event that wasn't a file save. Do nothing. - return None; - } + let label = match scope { + FlycheckScope::Workspace => None, + // We support substituting both build labels (e.g. buck, bazel) and cargo package ids. + // With cargo package ids, you get `cargo check -p path+file:///path/to/rust-analyzer/crates/hir#0.0.0`. + // That does work! + FlycheckScope::Package { package, .. } => Some(package.as_str()), + }; - cmd.arg(arg); - } - } + let subs = Substitutions { label, saved_file: saved_file.map(|x| x.as_str()) }; + let cmd = subs.substitute(&runnable, extra_env)?; - Some(cmd) + Some((cmd, FlycheckCommandOrigin::CheckOverrideCommand)) } } } @@ -746,15 +950,18 @@ impl FlycheckActor { } #[allow(clippy::large_enum_variant)] -enum CargoCheckMessage { +enum CheckMessage { + /// A message from `cargo check`, including details like the path + /// to the relevant `Cargo.toml`. CompilerArtifact(cargo_metadata::Artifact), - Diagnostic { diagnostic: Diagnostic, package_id: Option> }, + /// A diagnostic message from rustc itself. + Diagnostic { diagnostic: Diagnostic, package_id: Option }, } -struct CargoCheckParser; +struct CheckParser; -impl JsonLinesParser for CargoCheckParser { - fn from_line(&self, line: &str, error: &mut String) -> Option { +impl JsonLinesParser for CheckParser { + fn from_line(&self, line: &str, error: &mut String) -> Option { let mut deserializer = serde_json::Deserializer::from_str(line); deserializer.disable_recursion_limit(); if let Ok(message) = JsonMessage::deserialize(&mut deserializer) { @@ -762,18 +969,20 @@ impl JsonLinesParser for CargoCheckParser { // Skip certain kinds of messages to only spend time on what's useful JsonMessage::Cargo(message) => match message { cargo_metadata::Message::CompilerArtifact(artifact) if !artifact.fresh => { - Some(CargoCheckMessage::CompilerArtifact(artifact)) + Some(CheckMessage::CompilerArtifact(artifact)) } cargo_metadata::Message::CompilerMessage(msg) => { - Some(CargoCheckMessage::Diagnostic { + Some(CheckMessage::Diagnostic { diagnostic: msg.message, - package_id: Some(Arc::new(msg.package_id)), + package_id: Some(PackageSpecifier::Cargo { + package_id: Arc::new(msg.package_id), + }), }) } _ => None, }, JsonMessage::Rustc(message) => { - Some(CargoCheckMessage::Diagnostic { diagnostic: message, package_id: None }) + Some(CheckMessage::Diagnostic { diagnostic: message, package_id: None }) } }; } @@ -783,7 +992,7 @@ impl JsonLinesParser for CargoCheckParser { None } - fn from_eof(&self) -> Option { + fn from_eof(&self) -> Option { None } } @@ -794,3 +1003,144 @@ enum JsonMessage { Cargo(cargo_metadata::Message), Rustc(Diagnostic), } + +#[cfg(test)] +mod tests { + use super::*; + use ide_db::FxHashMap; + use itertools::Itertools; + use paths::Utf8Path; + use project_model::project_json; + + #[test] + fn test_substitutions() { + let label = ":label"; + let saved_file = "file.rs"; + + // Runnable says it needs both; you need both. + assert_eq!(test_substitute(None, None, "{label} {saved_file}").as_deref(), None); + assert_eq!(test_substitute(Some(label), None, "{label} {saved_file}").as_deref(), None); + assert_eq!( + test_substitute(None, Some(saved_file), "{label} {saved_file}").as_deref(), + None + ); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "{label} {saved_file}").as_deref(), + Some("build :label file.rs") + ); + + // Only need label? only need label. + assert_eq!(test_substitute(None, None, "{label}").as_deref(), None); + assert_eq!(test_substitute(Some(label), None, "{label}").as_deref(), Some("build :label"),); + assert_eq!(test_substitute(None, Some(saved_file), "{label}").as_deref(), None,); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "{label}").as_deref(), + Some("build :label"), + ); + + // Only need saved_file + assert_eq!(test_substitute(None, None, "{saved_file}").as_deref(), None); + assert_eq!(test_substitute(Some(label), None, "{saved_file}").as_deref(), None); + assert_eq!( + test_substitute(None, Some(saved_file), "{saved_file}").as_deref(), + Some("build file.rs") + ); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "{saved_file}").as_deref(), + Some("build file.rs") + ); + + // Need neither + assert_eq!(test_substitute(None, None, "xxx").as_deref(), Some("build xxx")); + assert_eq!(test_substitute(Some(label), None, "xxx").as_deref(), Some("build xxx")); + assert_eq!(test_substitute(None, Some(saved_file), "xxx").as_deref(), Some("build xxx")); + assert_eq!( + test_substitute(Some(label), Some(saved_file), "xxx").as_deref(), + Some("build xxx") + ); + + // {label} mid-argument substitution + assert_eq!( + test_substitute(Some(label), None, "--label={label}").as_deref(), + Some("build --label=:label") + ); + + // {saved_file} mid-argument substitution + assert_eq!( + test_substitute(None, Some(saved_file), "--saved={saved_file}").as_deref(), + Some("build --saved=file.rs") + ); + + // $saved_file legacy support (no mid-argument substitution, we never supported that) + assert_eq!( + test_substitute(None, Some(saved_file), "$saved_file").as_deref(), + Some("build file.rs") + ); + + fn test_substitute( + label: Option<&str>, + saved_file: Option<&str>, + args: &str, + ) -> Option { + Substitutions { label, saved_file } + .substitute( + &project_json::Runnable { + program: "build".to_owned(), + args: Vec::from_iter(args.split_whitespace().map(ToOwned::to_owned)), + cwd: Utf8Path::new("/path").to_owned(), + kind: project_json::RunnableKind::Flycheck, + }, + &FxHashMap::default(), + ) + .map(|command| { + command.get_args().map(|x| x.to_string_lossy()).collect_vec().join(" ") + }) + .map(|args| format!("build {}", args)) + } + } + + #[test] + fn test_flycheck_config_display() { + let clippy = FlycheckConfig::Automatic { + cargo_options: CargoOptions { + subcommand: "clippy".to_owned(), + target_tuples: vec![], + all_targets: false, + set_test: false, + no_default_features: false, + all_features: false, + features: vec![], + extra_args: vec![], + extra_test_bin_args: vec![], + extra_env: FxHashMap::default(), + target_dir_config: TargetDirectoryConfig::default(), + }, + ansi_color_output: true, + }; + assert_eq!(clippy.to_string(), "cargo clippy"); + + let custom_dollar = FlycheckConfig::CustomCommand { + command: "check".to_owned(), + args: vec!["--input".to_owned(), "$saved_file".to_owned()], + extra_env: FxHashMap::default(), + invocation_strategy: InvocationStrategy::Once, + }; + assert_eq!(custom_dollar.to_string(), "check --input ..."); + + let custom_inline = FlycheckConfig::CustomCommand { + command: "check".to_owned(), + args: vec!["--input".to_owned(), "{saved_file}".to_owned()], + extra_env: FxHashMap::default(), + invocation_strategy: InvocationStrategy::Once, + }; + assert_eq!(custom_inline.to_string(), "check --input ..."); + + let custom_rs = FlycheckConfig::CustomCommand { + command: "check".to_owned(), + args: vec!["--input".to_owned(), "/path/to/file.rs".to_owned()], + extra_env: FxHashMap::default(), + invocation_strategy: InvocationStrategy::Once, + }; + assert_eq!(custom_rs.to_string(), "check --input ..."); + } +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 7828f5084433..afd4162de622 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -9,13 +9,12 @@ use std::{ time::{Duration, Instant}, }; -use cargo_metadata::PackageId; use crossbeam_channel::{Receiver, Sender, unbounded}; use hir::ChangeWithProcMacros; use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId}; use ide_db::{ MiniCore, - base_db::{Crate, ProcMacroPaths, SourceDatabase}, + base_db::{Crate, ProcMacroPaths, SourceDatabase, salsa::Revision}, }; use itertools::Itertools; use load_cargo::SourceRootConfig; @@ -36,7 +35,7 @@ use crate::{ config::{Config, ConfigChange, ConfigErrors, RatomlFileKind}, diagnostics::{CheckFixes, DiagnosticCollection}, discover, - flycheck::{FlycheckHandle, FlycheckMessage}, + flycheck::{FlycheckHandle, FlycheckMessage, PackageSpecifier}, line_index::{LineEndings, LineIndex}, lsp::{from_proto, to_proto::url_from_abs_path}, lsp_ext, @@ -113,6 +112,7 @@ pub(crate) struct GlobalState { pub(crate) flycheck_sender: Sender, pub(crate) flycheck_receiver: Receiver, pub(crate) last_flycheck_error: Option, + pub(crate) flycheck_formatted_commands: Vec, // Test explorer pub(crate) test_run_session: Option>, @@ -188,18 +188,19 @@ pub(crate) struct GlobalState { /// been called. pub(crate) deferred_task_queue: DeferredTaskQueue, - /// HACK: Workaround for https://github.com/rust-lang/rust-analyzer/issues/19709 + /// HACK: Workaround for /// This is marked true if we failed to load a crate root file at crate graph creation, /// which will usually end up causing a bunch of incorrect diagnostics on startup. pub(crate) incomplete_crate_graph: bool, pub(crate) minicore: MiniCoreRustAnalyzerInternalOnly, + pub(crate) last_gc_revision: Revision, } // FIXME: This should move to the VFS once the rewrite is done. #[derive(Debug, Clone, Default)] pub(crate) struct MiniCoreRustAnalyzerInternalOnly { - pub(crate) minicore_text: Option, + pub(crate) minicore_text: Option>, } /// An immutable snapshot of the world's state at a point in time. @@ -256,6 +257,8 @@ impl GlobalState { let (discover_sender, discover_receiver) = unbounded(); + let last_gc_revision = analysis_host.raw_database().nonce_and_revision().1; + let mut this = GlobalState { sender, req_queue: ReqQueue::default(), @@ -286,6 +289,7 @@ impl GlobalState { flycheck_sender, flycheck_receiver, last_flycheck_error: None, + flycheck_formatted_commands: vec![], test_run_session: None, test_run_sender, @@ -319,6 +323,7 @@ impl GlobalState { incomplete_crate_graph: false, minicore: MiniCoreRustAnalyzerInternalOnly::default(), + last_gc_revision, }; // Apply any required database inputs from the config. this.update_configuration(config); @@ -343,11 +348,11 @@ impl GlobalState { let (change, modified_rust_files, workspace_structure_change) = self.cancellation_pool.scoped(|s| { - // start cancellation in parallel, this will kick off lru eviction + // start cancellation in parallel, // allowing us to do meaningful work while waiting let analysis_host = AssertUnwindSafe(&mut self.analysis_host); s.spawn(thread::ThreadIntent::LatencySensitive, || { - { analysis_host }.0.request_cancellation() + { analysis_host }.0.trigger_cancellation() }); // downgrade to read lock to allow more readers while we are normalizing text @@ -435,6 +440,7 @@ impl GlobalState { }); self.analysis_host.apply_change(change); + if !modified_ratoml_files.is_empty() || !self.config.same_source_root_parent_map(&self.local_roots_parent_map) { @@ -728,7 +734,7 @@ impl GlobalState { impl Drop for GlobalState { fn drop(&mut self) { - self.analysis_host.request_cancellation(); + self.analysis_host.trigger_cancellation(); } } @@ -820,7 +826,7 @@ impl GlobalStateSnapshot { let Some(krate) = project.crate_by_root(path) else { continue; }; - let Some(build) = krate.build else { + let Some(build) = krate.build.clone() else { continue; }; @@ -828,6 +834,7 @@ impl GlobalStateSnapshot { label: build.label, target_kind: build.target_kind, shell_runnables: project.runnables().to_owned(), + project_root: project.project_root().to_owned(), })); } ProjectWorkspaceKind::DetachedFile { .. } => {} @@ -839,23 +846,43 @@ impl GlobalStateSnapshot { pub(crate) fn all_workspace_dependencies_for_package( &self, - package: &Arc, - ) -> Option>> { - for workspace in self.workspaces.iter() { - match &workspace.kind { - ProjectWorkspaceKind::Cargo { cargo, .. } - | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. } => { - let package = cargo.packages().find(|p| cargo[*p].id == *package)?; + package: &PackageSpecifier, + ) -> Option> { + match package { + PackageSpecifier::Cargo { package_id } => { + self.workspaces.iter().find_map(|workspace| match &workspace.kind { + ProjectWorkspaceKind::Cargo { cargo, .. } + | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. } => { + let package = cargo.packages().find(|p| cargo[*p].id == *package_id)?; - return cargo[package] - .all_member_deps - .as_ref() - .map(|deps| deps.iter().map(|dep| cargo[*dep].id.clone()).collect()); - } - _ => {} + cargo[package].all_member_deps.as_ref().map(|deps| { + deps.iter() + .map(|dep| cargo[*dep].id.clone()) + .map(|p| PackageSpecifier::Cargo { package_id: p }) + .collect() + }) + } + _ => None, + }) + } + PackageSpecifier::BuildInfo { label } => { + self.workspaces.iter().find_map(|workspace| match &workspace.kind { + ProjectWorkspaceKind::Json(p) => { + let krate = p.crate_by_label(label)?; + Some( + krate + .iter_deps() + .filter_map(|dep| p[dep].build.as_ref()) + .map(|build| PackageSpecifier::BuildInfo { + label: build.label.clone(), + }) + .collect(), + ) + } + _ => None, + }) } } - None } pub(crate) fn file_exists(&self, file_id: FileId) -> bool { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs index 10bbb0bb31d9..90deae2d902e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs @@ -101,7 +101,7 @@ impl RequestDispatcher<'_> { } /// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not - /// ready this will return a default constructed [`R::Result`]. + /// ready this will return a default constructed `R::Result`. pub(crate) fn on( &mut self, f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result, @@ -128,7 +128,7 @@ impl RequestDispatcher<'_> { } /// Dispatches a non-latency-sensitive request onto the thread pool. When the VFS is marked not - /// ready this will return a `default` constructed [`R::Result`]. + /// ready this will return a `default` constructed `R::Result`. pub(crate) fn on_with_vfs_default( &mut self, f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result, @@ -176,7 +176,7 @@ impl RequestDispatcher<'_> { } /// Dispatches a latency-sensitive request onto the thread pool. When the VFS is marked not - /// ready this will return a default constructed [`R::Result`]. + /// ready this will return a default constructed `R::Result`. pub(crate) fn on_latency_sensitive( &mut self, f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index 4a6544508ff4..138310b78f62 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -18,7 +18,7 @@ use vfs::{AbsPathBuf, ChangeKind, VfsPath}; use crate::{ config::{Config, ConfigChange}, - flycheck::{InvocationStrategy, Target}, + flycheck::{InvocationStrategy, PackageSpecifier, Target}, global_state::{FetchWorkspaceRequest, GlobalState}, lsp::{from_proto, utils::apply_document_changes}, lsp_ext::{self, RunFlycheckParams}, @@ -289,11 +289,24 @@ pub(crate) fn handle_did_change_watched_files( state: &mut GlobalState, params: DidChangeWatchedFilesParams, ) -> anyhow::Result<()> { + // we want to trigger flycheck if a file outside of our workspaces has changed, + // as to reduce stale diagnostics when outside changes happen + let mut trigger_flycheck = false; for change in params.changes.iter().unique_by(|&it| &it.uri) { if let Ok(path) = from_proto::abs_path(&change.uri) { + if !trigger_flycheck { + trigger_flycheck = + state.config.workspace_roots().iter().any(|root| !path.starts_with(root)); + } state.loader.handle.invalidate(path); } } + + if trigger_flycheck && state.config.check_on_save(None) { + for flycheck in state.flycheck.iter() { + flycheck.restart_workspace(None); + } + } Ok(()) } @@ -328,22 +341,33 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { } InvocationStrategy::PerWorkspace => { Box::new(move || { - let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| { + let saved_file = vfs_path.as_path().map(ToOwned::to_owned); + let target = TargetSpec::for_file(&world, file_id)?.map(|it| { let tgt_kind = it.target_kind(); let (tgt_name, root, package) = match it { - TargetSpec::Cargo(c) => (c.target, c.workspace_root, c.package_id), - _ => return None, + TargetSpec::Cargo(c) => ( + Some(c.target), + c.workspace_root, + PackageSpecifier::Cargo { package_id: c.package_id }, + ), + TargetSpec::ProjectJson(p) => ( + None, + p.project_root, + PackageSpecifier::BuildInfo { label: p.label.clone() }, + ), }; - let tgt = match tgt_kind { - project_model::TargetKind::Bin => Target::Bin(tgt_name), - project_model::TargetKind::Example => Target::Example(tgt_name), - project_model::TargetKind::Test => Target::Test(tgt_name), - project_model::TargetKind::Bench => Target::Benchmark(tgt_name), - _ => return Some((None, root, package)), - }; + let tgt = tgt_name.and_then(|tgt_name| { + Some(match tgt_kind { + project_model::TargetKind::Bin => Target::Bin(tgt_name), + project_model::TargetKind::Example => Target::Example(tgt_name), + project_model::TargetKind::Test => Target::Test(tgt_name), + project_model::TargetKind::Bench => Target::Benchmark(tgt_name), + _ => return None, + }) + }); - Some((Some(tgt), root, package)) + (tgt, root, package) }); tracing::debug!(?target, "flycheck target"); // we have a specific non-library target, attempt to only check that target, nothing @@ -352,8 +376,10 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { if let Some((target, root, package)) = target { // trigger a package check if we have a non-library target as that can't affect // anything else in the workspace OR if we're not allowed to check the workspace as - // the user opted into package checks then - let package_check_allowed = target.is_some() || !may_flycheck_workspace; + // the user opted into package checks then OR if this is not cargo. + let package_check_allowed = target.is_some() + || !may_flycheck_workspace + || matches!(package, PackageSpecifier::BuildInfo { .. }); if package_check_allowed { package_workspace_idx = world.workspaces.iter().position(|ws| match &ws.kind { @@ -365,16 +391,30 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { cargo: Some((cargo, _, _)), .. } => *cargo.workspace_root() == root, - _ => false, + project_model::ProjectWorkspaceKind::Json(p) => { + *p.project_root() == root + } + project_model::ProjectWorkspaceKind::DetachedFile { + cargo: None, + .. + } => false, }); if let Some(idx) = package_workspace_idx { - let workspace_deps = - world.all_workspace_dependencies_for_package(&package); - world.flycheck[idx].restart_for_package( - package, - target, - workspace_deps, - ); + // flycheck handles are indexed by their ID (which is the workspace index), + // but not all workspaces have flycheck enabled (e.g., JSON projects without + // a flycheck template). Find the flycheck handle by its ID. + if let Some(flycheck) = + world.flycheck.iter().find(|fc| fc.id() == idx) + { + let workspace_deps = + world.all_workspace_dependencies_for_package(&package); + flycheck.restart_for_package( + package, + target, + workspace_deps, + saved_file.clone(), + ); + } } } } @@ -444,7 +484,6 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { ws_contains_file && !is_pkg_ws }); - let saved_file = vfs_path.as_path().map(ToOwned::to_owned); let mut workspace_check_triggered = false; // Find and trigger corresponding flychecks 'flychecks: for flycheck in world.flycheck.iter() { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index d15b519d6983..ad07da77597d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -42,8 +42,8 @@ use crate::{ lsp::{ LspError, completion_item_hash, ext::{ - InternalTestingFetchConfigOption, InternalTestingFetchConfigParams, - InternalTestingFetchConfigResponse, + GetFailedObligationsParams, InternalTestingFetchConfigOption, + InternalTestingFetchConfigParams, InternalTestingFetchConfigResponse, }, from_proto, to_proto, utils::{all_edits_are_disjoint, invalid_params_error}, @@ -808,7 +808,11 @@ pub(crate) fn handle_will_rename_files( } }) .filter_map(|(file_id, new_name)| { - snap.analysis.will_rename_file(file_id?, &new_name).ok()? + let file_id = file_id?; + let source_root = snap.analysis.source_root_id(file_id).ok(); + snap.analysis + .will_rename_file(file_id, &new_name, &snap.config.rename(source_root)) + .ok()? }) .collect(); @@ -2575,6 +2579,18 @@ pub(crate) fn internal_testing_fetch_config( })) } +pub(crate) fn get_failed_obligations( + snap: GlobalStateSnapshot, + params: GetFailedObligationsParams, +) -> anyhow::Result { + let _p = tracing::info_span!("get_failed_obligations").entered(); + let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); + let line_index = snap.file_line_index(file_id)?; + let offset = from_proto::offset(&line_index, params.position)?; + + Ok(snap.analysis.get_failed_obligations(offset, file_id)?) +} + /// Searches for the directory of a Rust crate given this crate's root file path. /// /// # Arguments diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs index 38ee9cbe7fc8..d16ca2fb48ac 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/integrated_benchmarks.rs @@ -53,6 +53,7 @@ fn integrated_highlighting_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: false, + proc_macro_processes: 1, }; let (db, vfs, _proc_macro) = { @@ -121,6 +122,7 @@ fn integrated_completion_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + proc_macro_processes: 1, }; let (db, vfs, _proc_macro) = { @@ -322,6 +324,7 @@ fn integrated_diagnostics_benchmark() { load_out_dirs_from_check: true, with_proc_macro_server: ProcMacroServerChoice::Sysroot, prefill_caches: true, + proc_macro_processes: 1, }; let (db, vfs, _proc_macro) = { @@ -363,6 +366,7 @@ fn integrated_diagnostics_benchmark() { prefer_absolute: false, term_search_fuel: 400, term_search_borrowck: true, + show_rename_conflicts: true, }; host.analysis() .full_diagnostics(&diagnostics_config, ide::AssistResolveStrategy::None, file_id) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 6ae527abb1ff..4a37bb34aba3 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -9,8 +9,16 @@ //! The `cli` submodule implements some batch-processing analysis, primarily as //! a debugging aid. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + extern crate ra_ap_rustc_type_ir as rustc_type_ir; +/* + If you bump this, grep for `FIXME(MINIMUM_SUPPORTED_TOOLCHAIN_VERSION)` to check for old support code we can drop +*/ /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { major: 1, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs index f94e7486ff8f..d6a694be9121 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs @@ -37,7 +37,11 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { change: Some(TextDocumentSyncKind::INCREMENTAL), will_save: None, will_save_wait_until: None, - save: Some(SaveOptions::default().into()), + save: if config.caps().did_save_text_document_dynamic_registration() { + None + } else { + Some(SaveOptions::default().into()) + }, })), hover_provider: Some(HoverProviderCapability::Simple(true)), completion_provider: Some(CompletionOptions { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs index b132323bec5b..e6493eefef17 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs @@ -864,3 +864,18 @@ pub struct CompletionImport { pub struct ClientCommandOptions { pub commands: Vec, } + +pub enum GetFailedObligations {} + +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GetFailedObligationsParams { + pub text_document: TextDocumentIdentifier, + pub position: Position, +} + +impl Request for GetFailedObligations { + type Params = GetFailedObligationsParams; + type Result = String; + const METHOD: &'static str = "rust-analyzer/getFailedObligations"; +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 86a35c7d116c..e5b983dcbf85 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -70,6 +70,7 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { | SymbolKind::Attribute | SymbolKind::Derive | SymbolKind::DeriveHelper => lsp_types::SymbolKind::FUNCTION, + SymbolKind::CrateRoot => lsp_types::SymbolKind::PACKAGE, SymbolKind::Module | SymbolKind::ToolModule => lsp_types::SymbolKind::MODULE, SymbolKind::TypeAlias | SymbolKind::TypeParam | SymbolKind::SelfType => { lsp_types::SymbolKind::TYPE_PARAMETER @@ -141,6 +142,7 @@ pub(crate) fn completion_item_kind( SymbolKind::Method => lsp_types::CompletionItemKind::METHOD, SymbolKind::Const => lsp_types::CompletionItemKind::CONSTANT, SymbolKind::ConstParam => lsp_types::CompletionItemKind::TYPE_PARAMETER, + SymbolKind::CrateRoot => lsp_types::CompletionItemKind::MODULE, SymbolKind::Derive => lsp_types::CompletionItemKind::FUNCTION, SymbolKind::DeriveHelper => lsp_types::CompletionItemKind::FUNCTION, SymbolKind::Enum => lsp_types::CompletionItemKind::ENUM, @@ -803,11 +805,16 @@ fn semantic_token_type_and_modifiers( ) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) { use semantic_tokens::{modifiers as mods, types}; + let mut mods = semantic_tokens::ModifierSet::default(); let ty = match highlight.tag { HlTag::Symbol(symbol) => match symbol { SymbolKind::Attribute => types::DECORATOR, SymbolKind::Derive => types::DERIVE, SymbolKind::DeriveHelper => types::DERIVE_HELPER, + SymbolKind::CrateRoot => { + mods |= mods::CRATE_ROOT; + types::NAMESPACE + } SymbolKind::Module => types::NAMESPACE, SymbolKind::Impl => types::TYPE_ALIAS, SymbolKind::Field => types::PROPERTY, @@ -870,7 +877,6 @@ fn semantic_token_type_and_modifiers( }, }; - let mut mods = semantic_tokens::ModifierSet::default(); for modifier in highlight.mods.iter() { let modifier = match modifier { HlMod::Associated => mods::ASSOCIATED, @@ -1561,6 +1567,9 @@ pub(crate) fn runnable( let target = spec.target.clone(); + let override_command = + CargoTargetSpec::override_command(snap, Some(spec.clone()), &runnable.kind); + let (cargo_args, executable_args) = CargoTargetSpec::runnable_args( snap, Some(spec.clone()), @@ -1576,23 +1585,41 @@ pub(crate) fn runnable( let label = runnable.label(Some(&target)); let location = location_link(snap, None, runnable.nav)?; - Ok(Some(lsp_ext::Runnable { - label, - location: Some(location), - kind: lsp_ext::RunnableKind::Cargo, - args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs { - workspace_root: Some(workspace_root.into()), - override_cargo: config.override_cargo, - cargo_args, - cwd: cwd.into(), - executable_args, - environment: spec - .sysroot_root - .map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string())) - .into_iter() - .collect(), + let environment = spec + .sysroot_root + .map(|root| ("RUSTC_TOOLCHAIN".to_owned(), root.to_string())) + .into_iter() + .collect(); + + Ok(match override_command { + Some(override_command) => match override_command.split_first() { + Some((program, args)) => Some(lsp_ext::Runnable { + label, + location: Some(location), + kind: lsp_ext::RunnableKind::Shell, + args: lsp_ext::RunnableArgs::Shell(lsp_ext::ShellRunnableArgs { + environment, + cwd: cwd.into(), + program: program.to_string(), + args: args.to_vec(), + }), + }), + _ => None, + }, + None => Some(lsp_ext::Runnable { + label, + location: Some(location), + kind: lsp_ext::RunnableKind::Cargo, + args: lsp_ext::RunnableArgs::Cargo(lsp_ext::CargoRunnableArgs { + workspace_root: Some(workspace_root.into()), + override_cargo: config.override_cargo, + cargo_args, + cwd: cwd.into(), + executable_args, + environment, + }), }), - })) + }) } Some(TargetSpec::ProjectJson(spec)) => { let label = runnable.label(Some(&spec.label)); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 77dedf12720c..64decc9e0db6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -9,7 +9,7 @@ use std::{ }; use crossbeam_channel::{Receiver, never, select}; -use ide_db::base_db::{SourceDatabase, VfsPath, salsa::Database as _}; +use ide_db::base_db::{SourceDatabase, VfsPath}; use lsp_server::{Connection, Notification, Request}; use lsp_types::{TextDocumentIdentifier, notification::Notification as _}; use stdx::thread::ThreadIntent; @@ -309,10 +309,10 @@ impl GlobalState { let event_dbg_msg = format!("{event:?}"); tracing::debug!(?loop_start, ?event, "handle_event"); - if tracing::enabled!(tracing::Level::INFO) { + if tracing::enabled!(tracing::Level::TRACE) { let task_queue_len = self.task_pool.handle.len(); if task_queue_len > 0 { - tracing::info!("task queue len: {}", task_queue_len); + tracing::trace!("task queue len: {}", task_queue_len); } } @@ -383,7 +383,7 @@ impl GlobalState { )); } PrimeCachesProgress::End { cancelled } => { - self.analysis_host.raw_database_mut().trigger_lru_eviction(); + self.analysis_host.trigger_garbage_collection(); self.prime_caches_queue.op_completed(()); if cancelled { self.prime_caches_queue @@ -437,11 +437,17 @@ impl GlobalState { } } Event::Flycheck(message) => { - let _p = tracing::info_span!("GlobalState::handle_event/flycheck").entered(); - self.handle_flycheck_msg(message); + let mut cargo_finished = false; + self.handle_flycheck_msg(message, &mut cargo_finished); // Coalesce many flycheck updates into a single loop turn while let Ok(message) = self.flycheck_receiver.try_recv() { - self.handle_flycheck_msg(message); + self.handle_flycheck_msg(message, &mut cargo_finished); + } + if cargo_finished { + self.send_request::( + (), + |_, _| (), + ); } } Event::TestResult(message) => { @@ -529,6 +535,16 @@ impl GlobalState { if project_or_mem_docs_changed && self.config.test_explorer() { self.update_tests(); } + + let current_revision = self.analysis_host.raw_database().nonce_and_revision().1; + // no work is currently being done, now we can block a bit and clean up our garbage + if self.task_pool.handle.is_empty() + && self.fmt_pool.handle.is_empty() + && current_revision != self.last_gc_revision + { + self.analysis_host.trigger_garbage_collection(); + self.last_gc_revision = current_revision; + } } self.cleanup_discover_handles(); @@ -650,31 +666,33 @@ impl GlobalState { move |sender| { // We aren't observing the semantics token cache here let snapshot = AssertUnwindSafe(&snapshot); - let Ok(diags) = std::panic::catch_unwind(|| { + let diags = std::panic::catch_unwind(|| { fetch_native_diagnostics( &snapshot, subscriptions.clone(), slice.clone(), NativeDiagnosticsFetchKind::Syntax, ) - }) else { - return; - }; + }) + .unwrap_or_else(|_| { + subscriptions.iter().map(|&id| (id, Vec::new())).collect::>() + }); sender .send(Task::Diagnostics(DiagnosticsTaskKind::Syntax(generation, diags))) .unwrap(); if fetch_semantic { - let Ok(diags) = std::panic::catch_unwind(|| { + let diags = std::panic::catch_unwind(|| { fetch_native_diagnostics( &snapshot, subscriptions.clone(), slice.clone(), NativeDiagnosticsFetchKind::Semantic, ) - }) else { - return; - }; + }) + .unwrap_or_else(|_| { + subscriptions.iter().map(|&id| (id, Vec::new())).collect::>() + }); sender .send(Task::Diagnostics(DiagnosticsTaskKind::Semantic( generation, diags, @@ -809,33 +827,29 @@ impl GlobalState { } Task::DiscoverLinkedProjects(arg) => { if let Some(cfg) = self.config.discover_workspace_config() { - // the clone is unfortunately necessary to avoid a borrowck error when - // `self.report_progress` is called later - let title = &cfg.progress_label.clone(); let command = cfg.command.clone(); let discover = DiscoverCommand::new(self.discover_sender.clone(), command); - if self.discover_jobs_active == 0 { - self.report_progress(title, Progress::Begin, None, None, None); - } - self.discover_jobs_active += 1; - let arg = match arg { DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it), DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it), }; - let handle = discover - .spawn( - arg, - &std::env::current_dir() - .expect("Failed to get cwd during project discovery"), - ) - .unwrap_or_else(|e| { - panic!("Failed to spawn project discovery command: {e}") - }); - - self.discover_handles.push(handle); + match discover.spawn(arg, self.config.root_path().as_ref()) { + Ok(handle) => { + if self.discover_jobs_active == 0 { + let title = &cfg.progress_label.clone(); + self.report_progress(title, Progress::Begin, None, None, None); + } + self.discover_jobs_active += 1; + self.discover_handles.push(handle) + } + Err(e) => self.show_message( + lsp_types::MessageType::ERROR, + format!("Failed to spawn project discovery command: {e:#}"), + false, + ), + } } } Task::FetchBuildData(progress) => { @@ -901,7 +915,8 @@ impl GlobalState { // Not a lot of bad can happen from mistakenly identifying `minicore`, so proceed with that. self.minicore.minicore_text = contents .as_ref() - .and_then(|contents| String::from_utf8(contents.clone()).ok()); + .and_then(|contents| str::from_utf8(contents).ok()) + .map(triomphe::Arc::from); } let path = VfsPath::from(path); @@ -1109,7 +1124,7 @@ impl GlobalState { } } - fn handle_flycheck_msg(&mut self, message: FlycheckMessage) { + fn handle_flycheck_msg(&mut self, message: FlycheckMessage, cargo_finished: &mut bool) { match message { FlycheckMessage::AddDiagnostic { id, @@ -1162,11 +1177,28 @@ impl GlobalState { kind: ClearDiagnosticsKind::OlderThan(generation, ClearScope::Package(package_id)), } => self.diagnostics.clear_check_older_than_for_package(id, package_id, generation), FlycheckMessage::Progress { id, progress } => { + let format_with_id = |user_facing_command: String| { + if self.flycheck.len() == 1 { + user_facing_command + } else { + format!("{user_facing_command} (#{})", id + 1) + } + }; + + self.flycheck_formatted_commands + .resize_with(self.flycheck.len().max(id + 1), || { + format_with_id(self.config.flycheck(None).to_string()) + }); + let (state, message) = match progress { - flycheck::Progress::DidStart => (Progress::Begin, None), + flycheck::Progress::DidStart { user_facing_command } => { + self.flycheck_formatted_commands[id] = format_with_id(user_facing_command); + (Progress::Begin, None) + } flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), flycheck::Progress::DidCancel => { self.last_flycheck_error = None; + *cargo_finished = true; (Progress::End, None) } flycheck::Progress::DidFailToRestart(err) => { @@ -1177,17 +1209,13 @@ impl GlobalState { flycheck::Progress::DidFinish(result) => { self.last_flycheck_error = result.err().map(|err| format!("cargo check failed to start: {err}")); + *cargo_finished = true; (Progress::End, None) } }; - // When we're running multiple flychecks, we have to include a disambiguator in - // the title, or the editor complains. Note that this is a user-facing string. - let title = if self.flycheck.len() == 1 { - format!("{}", self.config.flycheck(None)) - } else { - format!("{} (#{})", self.config.flycheck(None), id + 1) - }; + // Clone because we &mut self for report_progress + let title = self.flycheck_formatted_commands[id].clone(); self.report_progress( &title, state, @@ -1320,6 +1348,7 @@ impl GlobalState { .on::(handlers::handle_move_item) // .on::(handlers::internal_testing_fetch_config) + .on::(handlers::get_failed_obligations) .finish(); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index 317c1123659e..83f4a19b39fa 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -13,7 +13,7 @@ //! project is currently loading and we don't have a full project model, we //! still want to respond to various requests. // FIXME: This is a mess that needs some untangling work -use std::{iter, mem}; +use std::{iter, mem, sync::atomic::AtomicUsize}; use hir::{ChangeWithProcMacros, ProcMacrosBuilder, db::DefDatabase}; use ide_db::{ @@ -25,7 +25,9 @@ use load_cargo::{ProjectFolders, load_proc_macro}; use lsp_types::FileSystemWatcher; use paths::Utf8Path; use proc_macro_api::ProcMacroClient; -use project_model::{ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, WorkspaceBuildScripts}; +use project_model::{ + ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, WorkspaceBuildScripts, project_json, +}; use stdx::{format_to, thread::ThreadIntent}; use triomphe::Arc; use vfs::{AbsPath, AbsPathBuf, ChangeKind}; @@ -699,15 +701,19 @@ impl GlobalState { _ => Default::default(), }; info!("Using proc-macro server at {path}"); + let num_process = self.config.proc_macro_num_processes(); - Some(ProcMacroClient::spawn(&path, &env, ws.toolchain.as_ref()).map_err(|err| { - tracing::error!( - "Failed to run proc-macro server from path {path}, error: {err:?}", - ); - anyhow::format_err!( - "Failed to run proc-macro server from path {path}, error: {err:?}", - ) - })) + Some( + ProcMacroClient::spawn(&path, &env, ws.toolchain.as_ref(), num_process) + .map_err(|err| { + tracing::error!( + "Failed to run proc-macro server from path {path}, error: {err:?}", + ); + anyhow::format_err!( + "Failed to run proc-macro server from path {path}, error: {err:?}", + ) + }), + ) })) } @@ -866,14 +872,16 @@ impl GlobalState { let invocation_strategy = config.invocation_strategy(); let next_gen = self.flycheck.iter().map(FlycheckHandle::generation).max().unwrap_or_default() + 1; + let generation = Arc::new(AtomicUsize::new(next_gen)); self.flycheck = match invocation_strategy { crate::flycheck::InvocationStrategy::Once => { vec![FlycheckHandle::spawn( 0, - next_gen, + generation.clone(), sender.clone(), config, + crate::flycheck::FlycheckConfigJson::default(), None, self.config.root_path().clone(), None, @@ -893,16 +901,25 @@ impl GlobalState { cargo: Some((cargo, _, _)), .. } => ( + crate::flycheck::FlycheckConfigJson::default(), cargo.workspace_root(), Some(cargo.manifest_path()), Some(cargo.target_directory()), ), ProjectWorkspaceKind::Json(project) => { + let config_json = crate::flycheck::FlycheckConfigJson { + single_template: project + .runnable_template(project_json::RunnableKind::Flycheck) + .cloned(), + }; // Enable flychecks for json projects if a custom flycheck command was supplied // in the workspace configuration. match config { + _ if config_json.any_configured() => { + (config_json, project.path(), None, None) + } FlycheckConfig::CustomCommand { .. } => { - (project.path(), None, None) + (config_json, project.path(), None, None) } _ => return None, } @@ -912,12 +929,13 @@ impl GlobalState { ws.sysroot.root().map(ToOwned::to_owned), )) }) - .map(|(id, (root, manifest_path, target_dir), sysroot_root)| { + .map(|(id, (config_json, root, manifest_path, target_dir), sysroot_root)| { FlycheckHandle::spawn( id, - next_gen, + generation.clone(), sender.clone(), config.clone(), + config_json, sysroot_root, root.to_path_buf(), manifest_path.map(|it| it.to_path_buf()), @@ -928,6 +946,7 @@ impl GlobalState { } } .into(); + self.flycheck_formatted_commands = vec![]; } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index e532d155536c..b8d9acc02a32 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -68,6 +68,7 @@ pub(crate) struct ProjectJsonTargetSpec { pub(crate) label: String, pub(crate) target_kind: TargetKind, pub(crate) shell_runnables: Vec, + pub(crate) project_root: AbsPathBuf, } impl ProjectJsonTargetSpec { @@ -76,7 +77,16 @@ impl ProjectJsonTargetSpec { RunnableKind::Bin => { for runnable in &self.shell_runnables { if matches!(runnable.kind, project_model::project_json::RunnableKind::Run) { - return Some(runnable.clone()); + let mut runnable = runnable.clone(); + + let replaced_args: Vec<_> = runnable + .args + .iter() + .map(|arg| arg.replace("{label}", &self.label)) + .collect(); + runnable.args = replaced_args; + + return Some(runnable); } } @@ -123,7 +133,7 @@ impl CargoTargetSpec { match kind { RunnableKind::Test { test_id, attr } => { - cargo_args.push("test".to_owned()); + cargo_args.push(config.test_command); executable_args.push(test_id.to_string()); if let TestId::Path(_) = test_id { executable_args.push("--exact".to_owned()); @@ -134,12 +144,12 @@ impl CargoTargetSpec { } } RunnableKind::TestMod { path } => { - cargo_args.push("test".to_owned()); + cargo_args.push(config.test_command); executable_args.push(path.clone()); executable_args.extend(extra_test_binary_args); } RunnableKind::Bench { test_id } => { - cargo_args.push("bench".to_owned()); + cargo_args.push(config.bench_command); executable_args.push(test_id.to_string()); if let TestId::Path(_) = test_id { executable_args.push("--exact".to_owned()); @@ -154,10 +164,12 @@ impl CargoTargetSpec { } RunnableKind::Bin => { let subcommand = match spec { - Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => "test", - _ => "run", + Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => { + config.test_command + } + _ => "run".to_owned(), }; - cargo_args.push(subcommand.to_owned()); + cargo_args.push(subcommand); } } @@ -206,6 +218,53 @@ impl CargoTargetSpec { (cargo_args, executable_args) } + pub(crate) fn override_command( + snap: &GlobalStateSnapshot, + spec: Option, + kind: &RunnableKind, + ) -> Option> { + let config = snap.config.runnables(None); + let (args, test_name) = match kind { + RunnableKind::Test { test_id, .. } => { + (config.test_override_command, Some(test_id.to_string())) + } + RunnableKind::TestMod { path } => (config.test_override_command, Some(path.clone())), + RunnableKind::Bench { test_id } => { + (config.bench_override_command, Some(test_id.to_string())) + } + RunnableKind::DocTest { test_id } => { + (config.doc_test_override_command, Some(test_id.to_string())) + } + RunnableKind::Bin => match spec { + Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => { + (config.test_override_command, None) + } + _ => (None, None), + }, + }; + let test_name = test_name.unwrap_or_default(); + + let target_arg = |kind| match kind { + TargetKind::Bin => "--bin", + TargetKind::Test => "--test", + TargetKind::Bench => "--bench", + TargetKind::Example => "--example", + TargetKind::Lib { .. } => "--lib", + TargetKind::BuildScript | TargetKind::Other => "", + }; + + let replace_placeholders = |arg: String| match &spec { + Some(spec) => arg + .replace("${package}", &spec.package) + .replace("${target_arg}", target_arg(spec.target_kind)) + .replace("${target}", &spec.target) + .replace("${test_name}", &test_name), + _ => arg, + }; + + args.map(|args| args.into_iter().map(replace_placeholders).collect()) + } + pub(crate) fn push_to(self, buf: &mut Vec, kind: &RunnableKind) { buf.push("--package".to_owned()); buf.push(self.package); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs index ef0feb179698..104cd3d2eae9 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/task_pool.rs @@ -43,12 +43,16 @@ impl TaskPool { pub(crate) fn len(&self) -> usize { self.pool.len() } + + pub(crate) fn is_empty(&self) -> bool { + self.pool.is_empty() + } } /// `DeferredTaskQueue` holds deferred tasks. /// /// These are tasks that must be run after -/// [`GlobalState::process_changes`] has been called. +/// `GlobalState::process_changes` has been called. pub(crate) struct DeferredTaskQueue { pub(crate) sender: crossbeam_channel::Sender, pub(crate) receiver: crossbeam_channel::Receiver, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs index 7111a15d0246..0d9c8310d858 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs @@ -101,11 +101,11 @@ impl CargoTestHandle { ws_target_dir: Option<&Utf8Path>, test_target: TestTarget, sender: Sender, - ) -> std::io::Result { + ) -> anyhow::Result { let mut cmd = toolchain::command(Tool::Cargo.path(), root, &options.extra_env); cmd.env("RUSTC_BOOTSTRAP", "1"); cmd.arg("--color=always"); - cmd.arg("test"); + cmd.arg(&options.subcommand); // test, usually cmd.arg("--package"); cmd.arg(&test_target.package); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 5a4ad6f380f9..b4a7b44d165a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -9,6 +9,10 @@ //! be sure without a real client anyway. #![allow(clippy::disallowed_types)] +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; mod cli; mod ratoml; @@ -1443,7 +1447,27 @@ foo = { path = "../foo" } .server() .wait_until_workspace_is_loaded(); - server.request::(Default::default(), json!([])); + server.request::( + Default::default(), + json!([ + { + "name": "bar", + "kind": 4, + "location": { + "uri": "file:///[..]bar/src/lib.rs", + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + } + } + }]), + ); let server = Project::with_fixture( r#" @@ -1482,5 +1506,64 @@ version = "0.0.0" .server() .wait_until_workspace_is_loaded(); - server.request::(Default::default(), json!([])); + server.request::( + Default::default(), + json!([ + { + "name": "baz", + "kind": 4, + "location": { + "uri": "file:///[..]baz/src/lib.rs", + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + } + } + }]), + ); +} + +#[test] +fn test_get_failed_obligations() { + use expect_test::expect; + if skip_slow_tests() { + return; + } + + let server = Project::with_fixture( + r#" +//- /Cargo.toml +[package] +name = "foo" +version = "0.0.0" + +//- /src/lib.rs +trait Trait {} +fn requires_trait(x: T) {} + +fn test() { + requires_trait(0usize); +} +"#, + ) + .server() + .wait_until_workspace_is_loaded(); + + let res = server.send_request::( + rust_analyzer::lsp::ext::GetFailedObligationsParams { + text_document: server.doc_id("src/lib.rs"), + position: Position::new(4, 19), + }, + ); + + let res: serde_json::Value = serde_json::from_str(res.as_str().unwrap()).unwrap(); + let arr = res.as_array().unwrap(); + assert_eq!(arr.len(), 2); + expect![[r#"{"goal":"Goal { param_env: ParamEnv { clauses: [] }, predicate: Binder { value: TraitPredicate(usize: Trait, polarity:Positive), bound_vars: [] } }","result":"Err(NoSolution)","depth":0,"candidates":[]}"#]].assert_eq(&arr[0].to_string()); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index b1b428e7068d..195ad226ae0c 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -48,6 +48,7 @@ impl Project<'_> { "enable": false, }, }, + "checkOnSave": false, "procMacro": { "enable": false, } diff --git a/src/tools/rust-analyzer/crates/span/Cargo.toml b/src/tools/rust-analyzer/crates/span/Cargo.toml index 966962bab381..cfb319d688b6 100644 --- a/src/tools/rust-analyzer/crates/span/Cargo.toml +++ b/src/tools/rust-analyzer/crates/span/Cargo.toml @@ -27,6 +27,7 @@ syntax.workspace = true [features] default = ["salsa"] +in-rust-tree = [] [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index bd49e08b10fa..f52604e13917 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -48,6 +48,11 @@ pub const ROOT_ERASED_FILE_AST_ID: ErasedFileAstId = pub const FIXUP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId = ErasedFileAstId(pack_hash_index_and_kind(0, 0, ErasedFileAstIdKind::Fixup as u32)); +/// [`ErasedFileAstId`] used as the span for syntax nodes that should not be mapped down to +/// macro expansion. Any `Span` containing this file id is to be considered fake. +pub const NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId = + ErasedFileAstId(pack_hash_index_and_kind(0, 0, ErasedFileAstIdKind::NoDownmap as u32)); + /// This is a type erased FileAstId. #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct ErasedFileAstId(u32); @@ -83,7 +88,6 @@ impl fmt::Debug for ErasedFileAstId { Module, Static, Trait, - TraitAlias, Variant, Const, Fn, @@ -95,6 +99,7 @@ impl fmt::Debug for ErasedFileAstId { BlockExpr, AsmExpr, Fixup, + NoDownmap, ); if f.alternate() { write!(f, "{kind}[{:04X}, {}]", self.hash_value(), self.index()) @@ -123,7 +128,6 @@ enum ErasedFileAstIdKind { Module, Static, Trait, - TraitAlias, // Until here associated with `ErasedHasNameFileAstId`. // The following are associated with `ErasedAssocItemFileAstId`. Variant, @@ -150,6 +154,9 @@ enum ErasedFileAstIdKind { // because incrementality is not a problem, they will always be the only item in the macro file, // and memory usage also not because they're rare. AsmExpr, + /// Represents a fake [`ErasedFileAstId`] that should not be mapped down to macro expansion + /// result. + NoDownmap, /// Keep this last. Root, } @@ -158,7 +165,7 @@ enum ErasedFileAstIdKind { const HASH_BITS: u32 = 16; const INDEX_BITS: u32 = 11; const KIND_BITS: u32 = 5; -const _: () = assert!(ErasedFileAstIdKind::Fixup as u32 <= ((1 << KIND_BITS) - 1)); +const _: () = assert!(ErasedFileAstIdKind::Root as u32 <= ((1 << KIND_BITS) - 1)); const _: () = assert!(HASH_BITS + INDEX_BITS + KIND_BITS == u32::BITS); #[inline] @@ -594,8 +601,9 @@ impl AstIdMap { // After all, the block will then contain the *outer* item, so we allocate // an ID for it anyway. let mut blocks = Vec::new(); - let mut curr_layer = vec![(node.clone(), None)]; - let mut next_layer = vec![]; + let mut curr_layer = Vec::with_capacity(32); + curr_layer.push((node.clone(), None)); + let mut next_layer = Vec::with_capacity(32); while !curr_layer.is_empty() { curr_layer.drain(..).for_each(|(node, parent_idx)| { let mut preorder = node.preorder(); @@ -767,6 +775,48 @@ impl AstIdMap { } } +#[cfg(not(no_salsa_async_drops))] +impl Drop for AstIdMap { + fn drop(&mut self) { + let arena = std::mem::take(&mut self.arena); + let ptr_map = std::mem::take(&mut self.ptr_map); + let id_map = std::mem::take(&mut self.id_map); + static AST_ID_MAP_DROP_THREAD: std::sync::OnceLock< + std::sync::mpsc::Sender<( + Arena<(SyntaxNodePtr, ErasedFileAstId)>, + hashbrown::HashTable, + hashbrown::HashTable, + )>, + > = std::sync::OnceLock::new(); + AST_ID_MAP_DROP_THREAD + .get_or_init(|| { + let (sender, receiver) = std::sync::mpsc::channel::<( + Arena<(SyntaxNodePtr, ErasedFileAstId)>, + hashbrown::HashTable, + hashbrown::HashTable, + )>(); + std::thread::Builder::new() + .name("AstIdMapDropper".to_owned()) + .spawn(move || { + loop { + // block on a receive + _ = receiver.recv(); + // then drain the entire channel + while receiver.try_recv().is_ok() {} + // and sleep for a bit + std::thread::sleep(std::time::Duration::from_millis(100)); + } + // why do this over just a `receiver.iter().for_each(drop)`? To reduce contention on the channel lock. + // otherwise this thread will constantly wake up and sleep again. + }) + .unwrap(); + sender + }) + .send((arena, ptr_map, id_map)) + .unwrap(); + } +} + #[inline] fn hash_ptr(ptr: &SyntaxNodePtr) -> u64 { FxBuildHasher.hash_one(ptr) diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index 6805417177cd..fe05ef946518 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -8,9 +8,9 @@ //! //! # The Expansion Order Hierarchy //! -//! `ExpnData` in rustc, rust-analyzer's version is [`MacroCallLoc`]. Traversing the hierarchy -//! upwards can be achieved by walking up [`MacroCallLoc::kind`]'s contained file id, as -//! [`MacroFile`]s are interned [`MacroCallLoc`]s. +//! `ExpnData` in rustc, rust-analyzer's version is `MacroCallLoc`. Traversing the hierarchy +//! upwards can be achieved by walking up `MacroCallLoc::kind`'s contained file id, as +//! `MacroFile`s are interned `MacroCallLoc`s. //! //! # The Macro Definition Hierarchy //! @@ -18,10 +18,9 @@ //! //! # The Call-site Hierarchy //! -//! `ExpnData::call_site` in rustc, [`MacroCallLoc::call_site`] in rust-analyzer. -use std::fmt; - +//! `ExpnData::call_site` in rustc, `MacroCallLoc::call_site` in rust-analyzer. use crate::Edition; +use std::fmt; /// A syntax context describes a hierarchy tracking order of macro definitions. #[cfg(feature = "salsa")] @@ -47,7 +46,7 @@ const _: () = { edition: Edition, parent: SyntaxContext, opaque: SyntaxContext, - opaque_and_semitransparent: SyntaxContext, + opaque_and_semiopaque: SyntaxContext, } impl PartialEq for SyntaxContextData { @@ -215,7 +214,7 @@ const _: () = { edition: T2, parent: T3, opaque: impl FnOnce(SyntaxContext) -> SyntaxContext, - opaque_and_semitransparent: impl FnOnce(SyntaxContext) -> SyntaxContext, + opaque_and_semiopaque: impl FnOnce(SyntaxContext) -> SyntaxContext, ) -> Self where Db: ?Sized + salsa::Database, @@ -242,9 +241,7 @@ const _: () = { edition: zalsa_::interned::Lookup::into_owned(data.2), parent: zalsa_::interned::Lookup::into_owned(data.3), opaque: opaque(zalsa_::FromId::from_id(id)), - opaque_and_semitransparent: opaque_and_semitransparent( - zalsa_::FromId::from_id(id), - ), + opaque_and_semiopaque: opaque_and_semiopaque(zalsa_::FromId::from_id(id)), }, ) } @@ -302,7 +299,7 @@ const _: () = { } } - /// This context, but with all transparent and semi-transparent expansions filtered away. + /// This context, but with all transparent and semi-opaque expansions filtered away. pub fn opaque(self, db: &'db Db) -> SyntaxContext where Db: ?Sized + zalsa_::Database, @@ -318,7 +315,7 @@ const _: () = { } /// This context, but with all transparent expansions filtered away. - pub fn opaque_and_semitransparent(self, db: &'db Db) -> SyntaxContext + pub fn opaque_and_semiopaque(self, db: &'db Db) -> SyntaxContext where Db: ?Sized + zalsa_::Database, { @@ -326,7 +323,7 @@ const _: () = { Some(id) => { let zalsa = db.zalsa(); let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); - fields.opaque_and_semitransparent + fields.opaque_and_semiopaque } None => self, } @@ -406,7 +403,7 @@ impl<'db> SyntaxContext { #[inline] pub fn normalize_to_macro_rules(self, db: &'db dyn salsa::Database) -> SyntaxContext { - self.opaque_and_semitransparent(db) + self.opaque_and_semiopaque(db) } pub fn is_opaque(self, db: &'db dyn salsa::Database) -> bool { @@ -477,13 +474,13 @@ pub enum Transparency { /// Identifier produced by a transparent expansion is always resolved at call-site. /// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this. Transparent, - /// Identifier produced by a semi-transparent expansion may be resolved + /// Identifier produced by a semi-opaque expansion may be resolved /// either at call-site or at definition-site. /// If it's a local variable, label or `$crate` then it's resolved at def-site. /// Otherwise it's resolved at call-site. /// `macro_rules` macros behave like this, built-in macros currently behave like this too, /// but that's an implementation detail. - SemiTransparent, + SemiOpaque, /// Identifier produced by an opaque expansion is always resolved at definition-site. /// Def-site spans in procedural macros, identifiers from `macro` by default use this. Opaque, diff --git a/src/tools/rust-analyzer/crates/span/src/lib.rs b/src/tools/rust-analyzer/crates/span/src/lib.rs index cb91f4924944..bfe7b2620d56 100644 --- a/src/tools/rust-analyzer/crates/span/src/lib.rs +++ b/src/tools/rust-analyzer/crates/span/src/lib.rs @@ -1,4 +1,10 @@ //! File and span related types. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::fmt::{self, Write}; mod ast_id; @@ -8,7 +14,7 @@ mod map; pub use self::{ ast_id::{ AstIdMap, AstIdNode, ErasedFileAstId, FIXUP_ERASED_FILE_AST_ID_MARKER, FileAstId, - ROOT_ERASED_FILE_AST_ID, + NO_DOWNMAP_ERASED_FILE_AST_ID_MARKER, ROOT_ERASED_FILE_AST_ID, }, hygiene::{SyntaxContext, Transparency}, map::{RealSpanMap, SpanMap}, @@ -18,8 +24,6 @@ pub use syntax::Edition; pub use text_size::{TextRange, TextSize}; pub use vfs::FileId; -pub type Span = SpanData; - impl Span { pub fn cover(self, other: Span) -> Span { if self.anchor != other.anchor { @@ -55,13 +59,17 @@ impl Span { } Some(Span { range: self.range.cover(other.range), anchor: other.anchor, ctx: other.ctx }) } + + pub fn eq_ignoring_ctx(self, other: Self) -> bool { + self.anchor == other.anchor && self.range == other.range + } } /// Spans represent a region of code, used by the IDE to be able link macro inputs and outputs /// together. Positions in spans are relative to some [`SpanAnchor`] to make them more incremental /// friendly. #[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub struct SpanData { +pub struct Span { /// The text range of this span, relative to the anchor. /// We need the anchor for incrementality, as storing absolute ranges will require /// recomputation on every change in a file at all times. @@ -69,10 +77,10 @@ pub struct SpanData { /// The anchor this span is relative to. pub anchor: SpanAnchor, /// The syntax context of the span. - pub ctx: Ctx, + pub ctx: SyntaxContext, } -impl fmt::Debug for SpanData { +impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { fmt::Debug::fmt(&self.anchor.file_id.file_id().index(), f)?; @@ -92,12 +100,6 @@ impl fmt::Debug for SpanData { } } -impl SpanData { - pub fn eq_ignoring_ctx(self, other: Self) -> bool { - self.anchor == other.anchor && self.range == other.range - } -} - impl fmt::Display for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.anchor.file_id.file_id().index(), f)?; diff --git a/src/tools/rust-analyzer/crates/span/src/map.rs b/src/tools/rust-analyzer/crates/span/src/map.rs index d14c497474bd..dc7d471aa03a 100644 --- a/src/tools/rust-analyzer/crates/span/src/map.rs +++ b/src/tools/rust-analyzer/crates/span/src/map.rs @@ -6,24 +6,21 @@ use std::{fmt, hash::Hash}; use stdx::{always, itertools::Itertools}; use crate::{ - EditionedFileId, ErasedFileAstId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SpanData, - SyntaxContext, TextRange, TextSize, + EditionedFileId, ErasedFileAstId, ROOT_ERASED_FILE_AST_ID, Span, SpanAnchor, SyntaxContext, + TextRange, TextSize, }; /// Maps absolute text ranges for the corresponding file to the relevant span data. #[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub struct SpanMap { +pub struct SpanMap { /// The offset stored here is the *end* of the node. - spans: Vec<(TextSize, SpanData)>, + spans: Vec<(TextSize, Span)>, /// Index of the matched macro arm on successful expansion for declarative macros. // FIXME: Does it make sense to have this here? pub matched_arm: Option, } -impl SpanMap -where - SpanData: Copy, -{ +impl SpanMap { /// Creates a new empty [`SpanMap`]. pub fn empty() -> Self { Self { spans: Vec::new(), matched_arm: None } @@ -40,7 +37,7 @@ where } /// Pushes a new span onto the [`SpanMap`]. - pub fn push(&mut self, offset: TextSize, span: SpanData) { + pub fn push(&mut self, offset: TextSize, span: Span) { if cfg!(debug_assertions) && let Some(&(last_offset, _)) = self.spans.last() { @@ -57,11 +54,8 @@ where /// Note this does a linear search through the entire backing vector. pub fn ranges_with_span_exact( &self, - span: SpanData, - ) -> impl Iterator + '_ - where - S: Copy, - { + span: Span, + ) -> impl Iterator + '_ { self.spans.iter().enumerate().filter_map(move |(idx, &(end, s))| { if !s.eq_ignoring_ctx(span) { return None; @@ -74,10 +68,10 @@ where /// Returns all [`TextRange`]s whose spans contain the given span. /// /// Note this does a linear search through the entire backing vector. - pub fn ranges_with_span(&self, span: SpanData) -> impl Iterator + '_ - where - S: Copy, - { + pub fn ranges_with_span( + &self, + span: Span, + ) -> impl Iterator + '_ { self.spans.iter().enumerate().filter_map(move |(idx, &(end, s))| { if s.anchor != span.anchor { return None; @@ -91,28 +85,28 @@ where } /// Returns the span at the given position. - pub fn span_at(&self, offset: TextSize) -> SpanData { + pub fn span_at(&self, offset: TextSize) -> Span { let entry = self.spans.partition_point(|&(it, _)| it <= offset); self.spans[entry].1 } /// Returns the spans associated with the given range. /// In other words, this will return all spans that correspond to all offsets within the given range. - pub fn spans_for_range(&self, range: TextRange) -> impl Iterator> + '_ { + pub fn spans_for_range(&self, range: TextRange) -> impl Iterator + '_ { let (start, end) = (range.start(), range.end()); let start_entry = self.spans.partition_point(|&(it, _)| it <= start); let end_entry = self.spans[start_entry..].partition_point(|&(it, _)| it <= end); // FIXME: this might be wrong? self.spans[start_entry..][..end_entry].iter().map(|&(_, s)| s) } - pub fn iter(&self) -> impl Iterator)> + '_ { + pub fn iter(&self) -> impl Iterator + '_ { self.spans.iter().copied() } /// Merges this span map with another span map, where `other` is inserted at (and replaces) `other_range`. /// /// The length of the replacement node needs to be `other_size`. - pub fn merge(&mut self, other_range: TextRange, other_size: TextSize, other: &SpanMap) { + pub fn merge(&mut self, other_range: TextRange, other_size: TextSize, other: &SpanMap) { // I find the following diagram helpful to illustrate the bounds and why we use `<` or `<=`: // -------------------------------------------------------------------- // 1 3 5 6 7 10 11 <-- offsets we store @@ -157,39 +151,34 @@ where } #[cfg(not(no_salsa_async_drops))] -impl Drop for SpanMap { +impl Drop for SpanMap { fn drop(&mut self) { - struct SendPtr(*mut [()]); - unsafe impl Send for SendPtr {} + let spans = std::mem::take(&mut self.spans); static SPAN_MAP_DROP_THREAD: std::sync::OnceLock< - std::sync::mpsc::Sender<(SendPtr, fn(SendPtr))>, + std::sync::mpsc::Sender>, > = std::sync::OnceLock::new(); + SPAN_MAP_DROP_THREAD .get_or_init(|| { - let (sender, receiver) = std::sync::mpsc::channel::<(SendPtr, fn(SendPtr))>(); + let (sender, receiver) = std::sync::mpsc::channel::>(); std::thread::Builder::new() .name("SpanMapDropper".to_owned()) - .spawn(move || receiver.iter().for_each(|(b, drop)| drop(b))) + .spawn(move || { + loop { + // block on a receive + _ = receiver.recv(); + // then drain the entire channel + while receiver.try_recv().is_ok() {} + // and sleep for a bit + std::thread::sleep(std::time::Duration::from_millis(100)); + } + // why do this over just a `receiver.iter().for_each(drop)`? To reduce contention on the channel lock. + // otherwise this thread will constantly wake up and sleep again. + }) .unwrap(); sender }) - .send(( - unsafe { - SendPtr(std::mem::transmute::<*mut [(TextSize, SpanData)], *mut [()]>( - Box::<[(TextSize, SpanData)]>::into_raw( - std::mem::take(&mut self.spans).into_boxed_slice(), - ), - )) - }, - |b: SendPtr| { - _ = unsafe { - Box::from_raw(std::mem::transmute::< - *mut [()], - *mut [(TextSize, SpanData)], - >(b.0)) - } - }, - )) + .send(spans) .unwrap(); } } diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs index 5fa007416371..7ab26b189065 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs @@ -76,6 +76,20 @@ impl TupleExt for (T, U, V) { } } +impl TupleExt for &T +where + T: TupleExt + Copy, +{ + type Head = T::Head; + type Tail = T::Tail; + fn head(self) -> Self::Head { + (*self).head() + } + fn tail(self) -> Self::Tail { + (*self).tail() + } +} + pub fn to_lower_snake_case(s: &str) -> String { to_snake_case(s, char::to_lowercase) } diff --git a/src/tools/rust-analyzer/crates/stdx/src/process.rs b/src/tools/rust-analyzer/crates/stdx/src/process.rs index 2efeed45e44e..7c4ae978b04a 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/process.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/process.rs @@ -76,7 +76,7 @@ pub fn spawn_with_streaming_output( Ok(Output { status, stdout, stderr }) } -#[cfg(unix)] +#[cfg(all(unix, not(target_arch = "wasm32")))] mod imp { use std::{ io::{self, prelude::*}, diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs index 8d76c5fd1fb3..918b88d960f1 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/thread/pool.rs @@ -66,7 +66,6 @@ impl Pool { job.requested_intent.apply_to_current_thread(); current_intent = job.requested_intent; } - extant_tasks.fetch_add(1, Ordering::SeqCst); // discard the panic, we should've logged the backtrace already drop(panic::catch_unwind(job.f)); extant_tasks.fetch_sub(1, Ordering::SeqCst); @@ -93,6 +92,7 @@ impl Pool { }); let job = Job { requested_intent: intent, f }; + self.extant_tasks.fetch_add(1, Ordering::SeqCst); self.job_sender.send(job).unwrap(); } @@ -147,6 +147,7 @@ impl<'scope> Scope<'_, 'scope> { >(f) }, }; + self.pool.extant_tasks.fetch_add(1, Ordering::SeqCst); self.pool.job_sender.send(job).unwrap(); } } diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs index 1ded2b411319..0dcf18a4ad97 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/lib.rs @@ -1,10 +1,15 @@ //! Conversions between [`SyntaxNode`] and [`tt::TokenTree`]. +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::{collections::VecDeque, fmt, hash::Hash}; use intern::Symbol; use rustc_hash::{FxHashMap, FxHashSet}; -use span::{Edition, SpanAnchor, SpanData, SpanMap}; +use span::{Edition, Span, SpanAnchor, SpanMap, SyntaxContext}; use stdx::{format_to, never}; use syntax::{ AstToken, Parse, PreorderWithTokens, SmolStr, SyntaxElement, @@ -24,21 +29,18 @@ pub use ::parser::TopEntryPoint; #[cfg(test)] mod tests; -pub trait SpanMapper { - fn span_for(&self, range: TextRange) -> S; +pub trait SpanMapper { + fn span_for(&self, range: TextRange) -> Span; } -impl SpanMapper> for SpanMap -where - SpanData: Copy, -{ - fn span_for(&self, range: TextRange) -> SpanData { +impl SpanMapper for SpanMap { + fn span_for(&self, range: TextRange) -> Span { self.span_at(range.start()) } } -impl> SpanMapper for &SM { - fn span_for(&self, range: TextRange) -> S { +impl SpanMapper for &SM { + fn span_for(&self, range: TextRange) -> Span { SM::span_for(self, range) } } @@ -64,7 +66,7 @@ pub mod dummy_test_span_utils { pub struct DummyTestSpanMap; - impl SpanMapper for DummyTestSpanMap { + impl SpanMapper for DummyTestSpanMap { fn span_for(&self, range: syntax::TextRange) -> Span { Span { range, @@ -92,15 +94,14 @@ pub enum DocCommentDesugarMode { /// Converts a syntax tree to a [`tt::Subtree`] using the provided span map to populate the /// subtree's spans. -pub fn syntax_node_to_token_tree( +pub fn syntax_node_to_token_tree( node: &SyntaxNode, map: SpanMap, - span: SpanData, + span: Span, mode: DocCommentDesugarMode, -) -> tt::TopSubtree> +) -> tt::TopSubtree where - SpanData: Copy + fmt::Debug, - SpanMap: SpanMapper>, + SpanMap: SpanMapper, { let mut c = Converter::new(node, map, Default::default(), Default::default(), span, mode, |_, _| { @@ -112,22 +113,18 @@ where /// Converts a syntax tree to a [`tt::Subtree`] using the provided span map to populate the /// subtree's spans. Additionally using the append and remove parameters, the additional tokens can /// be injected or hidden from the output. -pub fn syntax_node_to_token_tree_modified( +pub fn syntax_node_to_token_tree_modified( node: &SyntaxNode, map: SpanMap, - append: FxHashMap>>>, + append: FxHashMap>, remove: FxHashSet, - call_site: SpanData, + call_site: Span, mode: DocCommentDesugarMode, on_enter: OnEvent, -) -> tt::TopSubtree> +) -> tt::TopSubtree where - SpanMap: SpanMapper>, - SpanData: Copy + fmt::Debug, - OnEvent: FnMut( - &mut PreorderWithTokens, - &WalkEvent, - ) -> (bool, Vec>>), + SpanMap: SpanMapper, + OnEvent: FnMut(&mut PreorderWithTokens, &WalkEvent) -> (bool, Vec), { let mut c = Converter::new(node, map, append, remove, call_site, mode, on_enter); convert_tokens(&mut c) @@ -147,13 +144,13 @@ where /// Converts a [`tt::Subtree`] back to a [`SyntaxNode`]. /// The produced `SpanMap` contains a mapping from the syntax nodes offsets to the subtree's spans. -pub fn token_tree_to_syntax_node( - tt: &tt::TopSubtree>, +pub fn token_tree_to_syntax_node( + tt: &tt::TopSubtree, entry_point: parser::TopEntryPoint, - span_to_edition: &mut dyn FnMut(Ctx) -> Edition, -) -> (Parse, SpanMap) + span_to_edition: &mut dyn FnMut(SyntaxContext) -> Edition, +) -> (Parse, SpanMap) where - Ctx: Copy + fmt::Debug + PartialEq + PartialEq + Eq + Hash, + SyntaxContext: Copy + fmt::Debug + PartialEq + PartialEq + Eq + Hash, { let buffer = tt.view().strip_invisible(); let parser_input = to_parser_input(buffer, span_to_edition); @@ -178,16 +175,12 @@ where /// Convert a string to a `TokenTree`. The spans of the subtree will be anchored to the provided /// anchor with the given context. -pub fn parse_to_token_tree( +pub fn parse_to_token_tree( edition: Edition, anchor: SpanAnchor, - ctx: Ctx, + ctx: SyntaxContext, text: &str, -) -> Option>> -where - SpanData: Copy + fmt::Debug, - Ctx: Copy, -{ +) -> Option { let lexed = parser::LexedStr::new(edition, text); if lexed.errors().next().is_some() { return None; @@ -198,14 +191,11 @@ where } /// Convert a string to a `TokenTree`. The passed span will be used for all spans of the produced subtree. -pub fn parse_to_token_tree_static_span( +pub fn parse_to_token_tree_static_span( edition: Edition, - span: S, + span: Span, text: &str, -) -> Option> -where - S: Copy + fmt::Debug, -{ +) -> Option { let lexed = parser::LexedStr::new(edition, text); if lexed.errors().next().is_some() { return None; @@ -215,10 +205,9 @@ where Some(convert_tokens(&mut conv)) } -fn convert_tokens(conv: &mut C) -> tt::TopSubtree +fn convert_tokens(conv: &mut C) -> tt::TopSubtree where - C: TokenConverter, - S: Copy + fmt::Debug, + C: TokenConverter, C::Token: fmt::Debug, { let mut builder = @@ -234,7 +223,7 @@ where spacing: _, })) => { let found_expected_delimiter = - builder.expected_delimiters().enumerate().find(|(_, delim)| match delim.kind { + builder.expected_delimiters().enumerate().find(|(_, delim)| match delim { tt::DelimiterKind::Parenthesis => char == ')', tt::DelimiterKind::Brace => char == '}', tt::DelimiterKind::Bracket => char == ']', @@ -268,13 +257,11 @@ where } kind if kind.is_punct() && kind != UNDERSCORE => { let found_expected_delimiter = - builder.expected_delimiters().enumerate().find(|(_, delim)| { - match delim.kind { - tt::DelimiterKind::Parenthesis => kind == T![')'], - tt::DelimiterKind::Brace => kind == T!['}'], - tt::DelimiterKind::Bracket => kind == T![']'], - tt::DelimiterKind::Invisible => false, - } + builder.expected_delimiters().enumerate().find(|(_, delim)| match delim { + tt::DelimiterKind::Parenthesis => kind == T![')'], + tt::DelimiterKind::Brace => kind == T!['}'], + tt::DelimiterKind::Bracket => kind == T![']'], + tt::DelimiterKind::Invisible => false, }); // Current token is a closing delimiter that we expect, fix up the closing span @@ -322,7 +309,7 @@ where .into() }; } - let leaf: tt::Leaf<_> = match kind { + let leaf: tt::Leaf = match kind { k if k.is_any_identifier() => { let text = token.to_text(conv); tt::Ident::new(&text, conv.span_for(abs_range)).into() @@ -430,11 +417,11 @@ pub fn desugar_doc_comment_text(text: &str, mode: DocCommentDesugarMode) -> (Sym } } -fn convert_doc_comment( +fn convert_doc_comment( token: &syntax::SyntaxToken, - span: S, + span: Span, mode: DocCommentDesugarMode, - builder: &mut tt::TopSubtreeBuilder, + builder: &mut tt::TopSubtreeBuilder, ) { let Some(comment) = ast::Comment::cast(token.clone()) else { return }; let Some(doc) = comment.kind().doc else { return }; @@ -455,7 +442,7 @@ fn convert_doc_comment( text = &text[0..text.len() - 2]; } let (text, kind) = desugar_doc_comment_text(text, mode); - let lit = tt::Literal { symbol: text, span, kind, suffix: None }; + let lit = tt::Literal { text_and_suffix: text, span, kind, suffix_len: 0 }; tt::Leaf::from(lit) }; @@ -474,92 +461,84 @@ fn convert_doc_comment( } /// A raw token (straight from lexer) converter -struct RawConverter<'a, Ctx> { +struct RawConverter<'a> { lexed: parser::LexedStr<'a>, pos: usize, anchor: SpanAnchor, - ctx: Ctx, + ctx: SyntaxContext, mode: DocCommentDesugarMode, } /// A raw token (straight from lexer) converter that gives every token the same span. -struct StaticRawConverter<'a, S> { +struct StaticRawConverter<'a> { lexed: parser::LexedStr<'a>, pos: usize, - span: S, + span: Span, mode: DocCommentDesugarMode, } -trait SrcToken { +trait SrcToken { fn kind(&self, ctx: &Ctx) -> SyntaxKind; fn to_char(&self, ctx: &Ctx) -> Option; fn to_text(&self, ctx: &Ctx) -> SmolStr; - fn as_leaf(&self) -> Option<&tt::Leaf> { + fn as_leaf(&self) -> Option<&tt::Leaf> { None } } -trait TokenConverter: Sized { - type Token: SrcToken; +trait TokenConverter: Sized { + type Token: SrcToken; fn convert_doc_comment( &self, token: &Self::Token, - span: S, - builder: &mut tt::TopSubtreeBuilder, + span: Span, + builder: &mut tt::TopSubtreeBuilder, ); fn bump(&mut self) -> Option<(Self::Token, TextRange)>; fn peek(&self) -> Option; - fn span_for(&self, range: TextRange) -> S; + fn span_for(&self, range: TextRange) -> Span; - fn call_site(&self) -> S; + fn call_site(&self) -> Span; } -impl SrcToken, S> for usize { - fn kind(&self, ctx: &RawConverter<'_, Ctx>) -> SyntaxKind { +impl SrcToken> for usize { + fn kind(&self, ctx: &RawConverter<'_>) -> SyntaxKind { ctx.lexed.kind(*self) } - fn to_char(&self, ctx: &RawConverter<'_, Ctx>) -> Option { + fn to_char(&self, ctx: &RawConverter<'_>) -> Option { ctx.lexed.text(*self).chars().next() } - fn to_text(&self, ctx: &RawConverter<'_, Ctx>) -> SmolStr { + fn to_text(&self, ctx: &RawConverter<'_>) -> SmolStr { ctx.lexed.text(*self).into() } } -impl SrcToken, S> for usize { - fn kind(&self, ctx: &StaticRawConverter<'_, S>) -> SyntaxKind { +impl SrcToken> for usize { + fn kind(&self, ctx: &StaticRawConverter<'_>) -> SyntaxKind { ctx.lexed.kind(*self) } - fn to_char(&self, ctx: &StaticRawConverter<'_, S>) -> Option { + fn to_char(&self, ctx: &StaticRawConverter<'_>) -> Option { ctx.lexed.text(*self).chars().next() } - fn to_text(&self, ctx: &StaticRawConverter<'_, S>) -> SmolStr { + fn to_text(&self, ctx: &StaticRawConverter<'_>) -> SmolStr { ctx.lexed.text(*self).into() } } -impl TokenConverter> for RawConverter<'_, Ctx> -where - SpanData: Copy, -{ +impl TokenConverter for RawConverter<'_> { type Token = usize; - fn convert_doc_comment( - &self, - &token: &usize, - span: SpanData, - builder: &mut tt::TopSubtreeBuilder>, - ) { + fn convert_doc_comment(&self, &token: &usize, span: Span, builder: &mut tt::TopSubtreeBuilder) { let text = self.lexed.text(token); convert_doc_comment(&doc_comment(text), span, self.mode, builder); } @@ -583,22 +562,19 @@ where Some(self.pos) } - fn span_for(&self, range: TextRange) -> SpanData { - SpanData { range, anchor: self.anchor, ctx: self.ctx } + fn span_for(&self, range: TextRange) -> Span { + Span { range, anchor: self.anchor, ctx: self.ctx } } - fn call_site(&self) -> SpanData { - SpanData { range: TextRange::empty(0.into()), anchor: self.anchor, ctx: self.ctx } + fn call_site(&self) -> Span { + Span { range: TextRange::empty(0.into()), anchor: self.anchor, ctx: self.ctx } } } -impl TokenConverter for StaticRawConverter<'_, S> -where - S: Copy, -{ +impl TokenConverter for StaticRawConverter<'_> { type Token = usize; - fn convert_doc_comment(&self, &token: &usize, span: S, builder: &mut tt::TopSubtreeBuilder) { + fn convert_doc_comment(&self, &token: &usize, span: Span, builder: &mut tt::TopSubtreeBuilder) { let text = self.lexed.text(token); convert_doc_comment(&doc_comment(text), span, self.mode, builder); } @@ -622,40 +598,40 @@ where Some(self.pos) } - fn span_for(&self, _: TextRange) -> S { + fn span_for(&self, _: TextRange) -> Span { self.span } - fn call_site(&self) -> S { + fn call_site(&self) -> Span { self.span } } -struct Converter { +struct Converter { current: Option, - current_leaves: VecDeque>, + current_leaves: VecDeque, preorder: PreorderWithTokens, range: TextRange, punct_offset: Option<(SyntaxToken, TextSize)>, /// Used to make the emitted text ranges in the spans relative to the span anchor. map: SpanMap, - append: FxHashMap>>, + append: FxHashMap>, remove: FxHashSet, - call_site: S, + call_site: Span, mode: DocCommentDesugarMode, on_event: OnEvent, } -impl Converter +impl Converter where - OnEvent: FnMut(&mut PreorderWithTokens, &WalkEvent) -> (bool, Vec>), + OnEvent: FnMut(&mut PreorderWithTokens, &WalkEvent) -> (bool, Vec), { fn new( node: &SyntaxNode, map: SpanMap, - append: FxHashMap>>, + append: FxHashMap>, remove: FxHashSet, - call_site: S, + call_site: Span, mode: DocCommentDesugarMode, on_enter: OnEvent, ) -> Self { @@ -715,13 +691,13 @@ where } #[derive(Debug)] -enum SynToken { +enum SynToken { Ordinary(SyntaxToken), Punct { token: SyntaxToken, offset: usize }, - Leaf(tt::Leaf), + Leaf(tt::Leaf), } -impl SynToken { +impl SynToken { fn token(&self) -> &SyntaxToken { match self { SynToken::Ordinary(it) | SynToken::Punct { token: it, offset: _ } => it, @@ -730,8 +706,8 @@ impl SynToken { } } -impl SrcToken, S> for SynToken { - fn kind(&self, _ctx: &Converter) -> SyntaxKind { +impl SrcToken> for SynToken { + fn kind(&self, _ctx: &Converter) -> SyntaxKind { match self { SynToken::Ordinary(token) => token.kind(), SynToken::Punct { token, offset: i } => { @@ -743,14 +719,14 @@ impl SrcToken, S> for SynTok } } } - fn to_char(&self, _ctx: &Converter) -> Option { + fn to_char(&self, _ctx: &Converter) -> Option { match self { SynToken::Ordinary(_) => None, SynToken::Punct { token: it, offset: i } => it.text().chars().nth(*i), SynToken::Leaf(_) => None, } } - fn to_text(&self, _ctx: &Converter) -> SmolStr { + fn to_text(&self, _ctx: &Converter) -> SmolStr { match self { SynToken::Ordinary(token) | SynToken::Punct { token, offset: _ } => token.text().into(), SynToken::Leaf(_) => { @@ -759,7 +735,7 @@ impl SrcToken, S> for SynTok } } } - fn as_leaf(&self) -> Option<&tt::Leaf> { + fn as_leaf(&self) -> Option<&tt::Leaf> { match self { SynToken::Ordinary(_) | SynToken::Punct { .. } => None, SynToken::Leaf(it) => Some(it), @@ -767,18 +743,17 @@ impl SrcToken, S> for SynTok } } -impl TokenConverter for Converter +impl TokenConverter for Converter where - S: Copy, - SpanMap: SpanMapper, - OnEvent: FnMut(&mut PreorderWithTokens, &WalkEvent) -> (bool, Vec>), + SpanMap: SpanMapper, + OnEvent: FnMut(&mut PreorderWithTokens, &WalkEvent) -> (bool, Vec), { - type Token = SynToken; + type Token = SynToken; fn convert_doc_comment( &self, token: &Self::Token, - span: S, - builder: &mut tt::TopSubtreeBuilder, + span: Span, + builder: &mut tt::TopSubtreeBuilder, ) { convert_doc_comment(token.token(), span, self.mode, builder); } @@ -842,30 +817,24 @@ where Some(token) } - fn span_for(&self, range: TextRange) -> S { + fn span_for(&self, range: TextRange) -> Span { self.map.span_for(range) } - fn call_site(&self) -> S { + fn call_site(&self) -> Span { self.call_site } } -struct TtTreeSink<'a, Ctx> -where - SpanData: Copy, -{ +struct TtTreeSink<'a> { buf: String, - cursor: Cursor<'a, SpanData>, + cursor: Cursor<'a>, text_pos: TextSize, inner: SyntaxTreeBuilder, - token_map: SpanMap, + token_map: SpanMap, } -impl<'a, Ctx> TtTreeSink<'a, Ctx> -where - SpanData: Copy, -{ - fn new(cursor: Cursor<'a, SpanData>) -> Self { +impl<'a> TtTreeSink<'a> { + fn new(cursor: Cursor<'a>) -> Self { TtTreeSink { buf: String::new(), cursor, @@ -875,7 +844,7 @@ where } } - fn finish(mut self) -> (Parse, SpanMap) { + fn finish(mut self) -> (Parse, SpanMap) { self.token_map.finish(); (self.inner.finish(), self.token_map) } @@ -893,21 +862,15 @@ fn delim_to_str(d: tt::DelimiterKind, closing: bool) -> Option<&'static str> { Some(&texts[idx..texts.len() - (1 - idx)]) } -impl TtTreeSink<'_, Ctx> -where - SpanData: Copy + fmt::Debug, - Ctx: PartialEq, -{ +impl TtTreeSink<'_> { /// Parses a float literal as if it was a one to two name ref nodes with a dot inbetween. /// This occurs when a float literal is used as a field access. fn float_split(&mut self, has_pseudo_dot: bool) { - let (text, span) = match self.cursor.token_tree() { - Some(tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { - symbol: text, - span, - kind: tt::LitKind::Float, - suffix: _, - }))) => (text.as_str(), *span), + let token_tree = self.cursor.token_tree(); + let (text, span) = match &token_tree { + Some(tt::TokenTree::Leaf(tt::Leaf::Literal( + lit @ tt::Literal { span, kind: tt::LitKind::Float, .. }, + ))) => (lit.text(), *span), tt => unreachable!("{tt:?}"), }; // FIXME: Span splitting @@ -966,9 +929,15 @@ where self.buf.push_str("r#"); self.text_pos += TextSize::of("r#"); } - let r = (ident.sym.as_str(), ident.span); + let text = ident.sym.as_str(); + self.buf += text; + self.text_pos += TextSize::of(text); + combined_span = match combined_span { + None => Some(ident.span), + Some(prev_span) => Some(Self::merge_spans(prev_span, ident.span)), + }; self.cursor.bump(); - r + continue 'tokens; } tt::Leaf::Punct(punct) => { assert!(punct.char.is_ascii()); @@ -1048,10 +1017,10 @@ where self.inner.error(error, self.text_pos) } - fn merge_spans(a: SpanData, b: SpanData) -> SpanData { + fn merge_spans(a: Span, b: Span) -> Span { // We don't do what rustc does exactly, rustc does something clever when the spans have different syntax contexts // but this runs afoul of our separation between `span` and `hir-expand`. - SpanData { + Span { range: if a.ctx == b.ctx && a.anchor == b.anchor { TextRange::new( std::cmp::min(a.range.start(), b.range.start()), diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs index c8dc3131b59c..16f2498bf357 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/tests.rs @@ -30,15 +30,15 @@ fn check_punct_spacing(fixture: &str) { }) .collect(); - let mut cursor = Cursor::new(&subtree.0); + let mut cursor = Cursor::new(subtree.as_token_trees()); while !cursor.eof() { while let Some(token_tree) = cursor.token_tree() { if let tt::TokenTree::Leaf(Leaf::Punct(Punct { spacing, span: Span { range, .. }, .. })) = token_tree - && let Some(expected) = annotations.remove(range) + && let Some(expected) = annotations.remove(&range) { - assert_eq!(expected, *spacing); + assert_eq!(expected, spacing); } cursor.bump(); } diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs b/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs index 5922994c084c..851a4af86439 100644 --- a/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs +++ b/src/tools/rust-analyzer/crates/syntax-bridge/src/to_parser_input.rs @@ -1,16 +1,13 @@ //! Convert macro-by-example tokens which are specific to macro expansion into a //! format that works for our parser. -use std::fmt; -use std::hash::Hash; - use rustc_hash::FxHashMap; -use span::{Edition, SpanData}; +use span::{Edition, SyntaxContext}; use syntax::{SyntaxKind, SyntaxKind::*, T}; -pub fn to_parser_input( - buffer: tt::TokenTreesView<'_, SpanData>, - span_to_edition: &mut dyn FnMut(Ctx) -> Edition, +pub fn to_parser_input( + buffer: tt::TokenTreesView<'_>, + span_to_edition: &mut dyn FnMut(SyntaxContext) -> Edition, ) -> parser::Input { let mut res = parser::Input::with_capacity(buffer.len()); @@ -55,7 +52,7 @@ pub fn to_parser_input( }; res.push(kind, ctx_edition(lit.span.ctx)); - if kind == FLOAT_NUMBER && !lit.symbol.as_str().ends_with('.') { + if kind == FLOAT_NUMBER && !lit.text().ends_with('.') { // Tag the token as joint if it is float with a fractional part // we use this jointness to inform the parser about what token split // event to emit when we encounter a float literal in a field access diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml index 1ee93013e3e8..8909fb423c4d 100644 --- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml @@ -33,6 +33,7 @@ rustc_apfloat = "0.2.3" test-utils.workspace = true [features] +default = [] in-rust-tree = [] [lints] diff --git a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml index 8910911ff025..b2f238efc025 100644 --- a/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml +++ b/src/tools/rust-analyzer/crates/syntax/fuzz/Cargo.toml @@ -10,7 +10,6 @@ cargo-fuzz = true [dependencies] syntax = { path = "..", version = "0.0.0" } -text-edit = { path = "../../text-edit", version = "0.0.0" } libfuzzer-sys = "0.4.5" # Prevent this from interfering with workspaces diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index d73d60c51f0c..544053408f73 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -438,7 +438,10 @@ FormatArgsExpr = ')' FormatArgsArg = - (Name '=')? Expr + arg_name:FormatArgsArgName? Expr + +FormatArgsArgName = + '=' // This also has a name, but it's any token and we can't put it here MacroExpr = MacroCall @@ -469,8 +472,11 @@ RefExpr = TryExpr = Attr* Expr '?' +TryBlockModifier = + 'try' ('bikeshed' Type)? + BlockExpr = - Attr* Label? ('try' | 'unsafe' | ('async' 'move'?) | ('gen' 'move'?) | 'const') StmtList + Attr* Label? (TryBlockModifier | 'unsafe' | ('async' 'move'?) | ('gen' 'move'?) | 'const') StmtList PrefixExpr = Attr* op:('-' | '!' | '*') Expr diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs index 1cd8146f6863..2b7dc5cd76ab 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs @@ -9,8 +9,9 @@ use crate::{ SyntaxKind::{ATTR, COMMENT, WHITESPACE}, SyntaxNode, SyntaxToken, algo::{self, neighbor}, - ast::{self, HasGenericParams, edit::IndentLevel, make}, - ted::{self, Position}, + ast::{self, HasGenericParams, edit::IndentLevel, make, syntax_factory::SyntaxFactory}, + syntax_editor::{Position, SyntaxEditor}, + ted, }; use super::{GenericParam, HasName}; @@ -26,13 +27,13 @@ impl GenericParamsOwnerEdit for ast::Fn { Some(it) => it, None => { let position = if let Some(name) = self.name() { - Position::after(name.syntax) + ted::Position::after(name.syntax) } else if let Some(fn_token) = self.fn_token() { - Position::after(fn_token) + ted::Position::after(fn_token) } else if let Some(param_list) = self.param_list() { - Position::before(param_list.syntax) + ted::Position::before(param_list.syntax) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_generic_param_list(position) } @@ -42,11 +43,11 @@ impl GenericParamsOwnerEdit for ast::Fn { fn get_or_create_where_clause(&self) -> ast::WhereClause { if self.where_clause().is_none() { let position = if let Some(ty) = self.ret_type() { - Position::after(ty.syntax()) + ted::Position::after(ty.syntax()) } else if let Some(param_list) = self.param_list() { - Position::after(param_list.syntax()) + ted::Position::after(param_list.syntax()) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_where_clause(position); } @@ -60,8 +61,8 @@ impl GenericParamsOwnerEdit for ast::Impl { Some(it) => it, None => { let position = match self.impl_token() { - Some(imp_token) => Position::after(imp_token), - None => Position::last_child_of(self.syntax()), + Some(imp_token) => ted::Position::after(imp_token), + None => ted::Position::last_child_of(self.syntax()), }; create_generic_param_list(position) } @@ -71,8 +72,8 @@ impl GenericParamsOwnerEdit for ast::Impl { fn get_or_create_where_clause(&self) -> ast::WhereClause { if self.where_clause().is_none() { let position = match self.assoc_item_list() { - Some(items) => Position::before(items.syntax()), - None => Position::last_child_of(self.syntax()), + Some(items) => ted::Position::before(items.syntax()), + None => ted::Position::last_child_of(self.syntax()), }; create_where_clause(position); } @@ -86,11 +87,11 @@ impl GenericParamsOwnerEdit for ast::Trait { Some(it) => it, None => { let position = if let Some(name) = self.name() { - Position::after(name.syntax) + ted::Position::after(name.syntax) } else if let Some(trait_token) = self.trait_token() { - Position::after(trait_token) + ted::Position::after(trait_token) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_generic_param_list(position) } @@ -100,9 +101,9 @@ impl GenericParamsOwnerEdit for ast::Trait { fn get_or_create_where_clause(&self) -> ast::WhereClause { if self.where_clause().is_none() { let position = match (self.assoc_item_list(), self.semicolon_token()) { - (Some(items), _) => Position::before(items.syntax()), - (_, Some(tok)) => Position::before(tok), - (None, None) => Position::last_child_of(self.syntax()), + (Some(items), _) => ted::Position::before(items.syntax()), + (_, Some(tok)) => ted::Position::before(tok), + (None, None) => ted::Position::last_child_of(self.syntax()), }; create_where_clause(position); } @@ -116,11 +117,11 @@ impl GenericParamsOwnerEdit for ast::TypeAlias { Some(it) => it, None => { let position = if let Some(name) = self.name() { - Position::after(name.syntax) + ted::Position::after(name.syntax) } else if let Some(trait_token) = self.type_token() { - Position::after(trait_token) + ted::Position::after(trait_token) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_generic_param_list(position) } @@ -130,10 +131,10 @@ impl GenericParamsOwnerEdit for ast::TypeAlias { fn get_or_create_where_clause(&self) -> ast::WhereClause { if self.where_clause().is_none() { let position = match self.eq_token() { - Some(tok) => Position::before(tok), + Some(tok) => ted::Position::before(tok), None => match self.semicolon_token() { - Some(tok) => Position::before(tok), - None => Position::last_child_of(self.syntax()), + Some(tok) => ted::Position::before(tok), + None => ted::Position::last_child_of(self.syntax()), }, }; create_where_clause(position); @@ -148,11 +149,11 @@ impl GenericParamsOwnerEdit for ast::Struct { Some(it) => it, None => { let position = if let Some(name) = self.name() { - Position::after(name.syntax) + ted::Position::after(name.syntax) } else if let Some(struct_token) = self.struct_token() { - Position::after(struct_token) + ted::Position::after(struct_token) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_generic_param_list(position) } @@ -166,13 +167,13 @@ impl GenericParamsOwnerEdit for ast::Struct { ast::FieldList::TupleFieldList(it) => Some(it), }); let position = if let Some(tfl) = tfl { - Position::after(tfl.syntax()) + ted::Position::after(tfl.syntax()) } else if let Some(gpl) = self.generic_param_list() { - Position::after(gpl.syntax()) + ted::Position::after(gpl.syntax()) } else if let Some(name) = self.name() { - Position::after(name.syntax()) + ted::Position::after(name.syntax()) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_where_clause(position); } @@ -186,11 +187,11 @@ impl GenericParamsOwnerEdit for ast::Enum { Some(it) => it, None => { let position = if let Some(name) = self.name() { - Position::after(name.syntax) + ted::Position::after(name.syntax) } else if let Some(enum_token) = self.enum_token() { - Position::after(enum_token) + ted::Position::after(enum_token) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_generic_param_list(position) } @@ -200,11 +201,11 @@ impl GenericParamsOwnerEdit for ast::Enum { fn get_or_create_where_clause(&self) -> ast::WhereClause { if self.where_clause().is_none() { let position = if let Some(gpl) = self.generic_param_list() { - Position::after(gpl.syntax()) + ted::Position::after(gpl.syntax()) } else if let Some(name) = self.name() { - Position::after(name.syntax()) + ted::Position::after(name.syntax()) } else { - Position::last_child_of(self.syntax()) + ted::Position::last_child_of(self.syntax()) }; create_where_clause(position); } @@ -212,12 +213,12 @@ impl GenericParamsOwnerEdit for ast::Enum { } } -fn create_where_clause(position: Position) { +fn create_where_clause(position: ted::Position) { let where_clause = make::where_clause(empty()).clone_for_update(); ted::insert(position, where_clause.syntax()); } -fn create_generic_param_list(position: Position) -> ast::GenericParamList { +fn create_generic_param_list(position: ted::Position) -> ast::GenericParamList { let gpl = make::generic_param_list(empty()).clone_for_update(); ted::insert_raw(position, gpl.syntax()); gpl @@ -253,7 +254,7 @@ impl ast::GenericParamList { pub fn add_generic_param(&self, generic_param: ast::GenericParam) { match self.generic_params().last() { Some(last_param) => { - let position = Position::after(last_param.syntax()); + let position = ted::Position::after(last_param.syntax()); let elements = vec![ make::token(T![,]).into(), make::tokens::single_space().into(), @@ -262,7 +263,7 @@ impl ast::GenericParamList { ted::insert_all(position, elements); } None => { - let after_l_angle = Position::after(self.l_angle_token().unwrap()); + let after_l_angle = ted::Position::after(self.l_angle_token().unwrap()); ted::insert(after_l_angle, generic_param.syntax()); } } @@ -412,7 +413,7 @@ impl ast::UseTree { match self.use_tree_list() { Some(it) => it, None => { - let position = Position::last_child_of(self.syntax()); + let position = ted::Position::last_child_of(self.syntax()); let use_tree_list = make::use_tree_list(empty()).clone_for_update(); let mut elements = Vec::with_capacity(2); if self.coloncolon_token().is_none() { @@ -458,7 +459,7 @@ impl ast::UseTree { // Next, transform 'suffix' use tree into 'prefix::{suffix}' let subtree = self.clone_subtree().clone_for_update(); ted::remove_all_iter(self.syntax().children_with_tokens()); - ted::insert(Position::first_child_of(self.syntax()), prefix.syntax()); + ted::insert(ted::Position::first_child_of(self.syntax()), prefix.syntax()); self.get_or_create_use_tree_list().add_use_tree(subtree); fn split_path_prefix(prefix: &ast::Path) -> Option<()> { @@ -507,7 +508,7 @@ impl ast::UseTreeList { pub fn add_use_tree(&self, use_tree: ast::UseTree) { let (position, elements) = match self.use_trees().last() { Some(last_tree) => ( - Position::after(last_tree.syntax()), + ted::Position::after(last_tree.syntax()), vec![ make::token(T![,]).into(), make::tokens::single_space().into(), @@ -516,8 +517,8 @@ impl ast::UseTreeList { ), None => { let position = match self.l_curly_token() { - Some(l_curly) => Position::after(l_curly), - None => Position::last_child_of(self.syntax()), + Some(l_curly) => ted::Position::after(l_curly), + None => ted::Position::last_child_of(self.syntax()), }; (position, vec![use_tree.syntax.into()]) } @@ -582,15 +583,15 @@ impl ast::AssocItemList { let (indent, position, whitespace) = match self.assoc_items().last() { Some(last_item) => ( IndentLevel::from_node(last_item.syntax()), - Position::after(last_item.syntax()), + ted::Position::after(last_item.syntax()), "\n\n", ), None => match self.l_curly_token() { Some(l_curly) => { normalize_ws_between_braces(self.syntax()); - (IndentLevel::from_token(&l_curly) + 1, Position::after(&l_curly), "\n") + (IndentLevel::from_token(&l_curly) + 1, ted::Position::after(&l_curly), "\n") } - None => (IndentLevel::single(), Position::last_child_of(self.syntax()), "\n"), + None => (IndentLevel::single(), ted::Position::last_child_of(self.syntax()), "\n"), }, }; let elements: Vec = vec![ @@ -618,17 +619,17 @@ impl ast::RecordExprFieldList { let position = match self.fields().last() { Some(last_field) => { let comma = get_or_insert_comma_after(last_field.syntax()); - Position::after(comma) + ted::Position::after(comma) } None => match self.l_curly_token() { - Some(it) => Position::after(it), - None => Position::last_child_of(self.syntax()), + Some(it) => ted::Position::after(it), + None => ted::Position::last_child_of(self.syntax()), }, }; ted::insert_all(position, vec![whitespace.into(), field.syntax().clone().into()]); if is_multiline { - ted::insert(Position::after(field.syntax()), ast::make::token(T![,])); + ted::insert(ted::Position::after(field.syntax()), ast::make::token(T![,])); } } } @@ -656,7 +657,7 @@ impl ast::RecordExprField { ast::make::tokens::single_space().into(), expr.syntax().clone().into(), ]; - ted::insert_all_raw(Position::last_child_of(self.syntax()), children); + ted::insert_all_raw(ted::Position::last_child_of(self.syntax()), children); } } } @@ -679,17 +680,17 @@ impl ast::RecordPatFieldList { Some(last_field) => { let syntax = last_field.syntax(); let comma = get_or_insert_comma_after(syntax); - Position::after(comma) + ted::Position::after(comma) } None => match self.l_curly_token() { - Some(it) => Position::after(it), - None => Position::last_child_of(self.syntax()), + Some(it) => ted::Position::after(it), + None => ted::Position::last_child_of(self.syntax()), }, }; ted::insert_all(position, vec![whitespace.into(), field.syntax().clone().into()]); if is_multiline { - ted::insert(Position::after(field.syntax()), ast::make::token(T![,])); + ted::insert(ted::Position::after(field.syntax()), ast::make::token(T![,])); } } } @@ -703,7 +704,7 @@ fn get_or_insert_comma_after(syntax: &SyntaxNode) -> SyntaxToken { Some(it) => it, None => { let comma = ast::make::token(T![,]); - ted::insert(Position::after(syntax), &comma); + ted::insert(ted::Position::after(syntax), &comma); comma } } @@ -728,7 +729,7 @@ fn normalize_ws_between_braces(node: &SyntaxNode) -> Option<()> { } } Some(ws) if ws.kind() == T!['}'] => { - ted::insert(Position::after(l), make::tokens::whitespace(&format!("\n{indent}"))); + ted::insert(ted::Position::after(l), make::tokens::whitespace(&format!("\n{indent}"))); } _ => (), } @@ -780,6 +781,56 @@ impl ast::IdentPat { } } } + + pub fn set_pat_with_editor( + &self, + pat: Option, + syntax_editor: &mut SyntaxEditor, + syntax_factory: &SyntaxFactory, + ) { + match pat { + None => { + if let Some(at_token) = self.at_token() { + // Remove `@ Pat` + let start = at_token.clone().into(); + let end = self + .pat() + .map(|it| it.syntax().clone().into()) + .unwrap_or_else(|| at_token.into()); + syntax_editor.delete_all(start..=end); + + // Remove any trailing ws + if let Some(last) = + self.syntax().last_token().filter(|it| it.kind() == WHITESPACE) + { + last.detach(); + } + } + } + Some(pat) => { + if let Some(old_pat) = self.pat() { + // Replace existing pattern + syntax_editor.replace(old_pat.syntax(), pat.syntax()) + } else if let Some(at_token) = self.at_token() { + // Have an `@` token but not a pattern yet + syntax_editor.insert(Position::after(at_token), pat.syntax()); + } else { + // Don't have an `@`, should have a name + let name = self.name().unwrap(); + + syntax_editor.insert_all( + Position::after(name.syntax()), + vec![ + syntax_factory.whitespace(" ").into(), + syntax_factory.token(T![@]).into(), + syntax_factory.whitespace(" ").into(), + pat.syntax().clone().into(), + ], + ) + } + } + } + } } pub trait HasVisibilityEdit: ast::HasVisibility { diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs index db6699538138..b44150f86842 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/expr_ext.rs @@ -375,7 +375,11 @@ impl ast::Literal { pub enum BlockModifier { Async(SyntaxToken), Unsafe(SyntaxToken), - Try(SyntaxToken), + Try { + try_token: SyntaxToken, + bikeshed_token: Option, + result_type: Option, + }, Const(SyntaxToken), AsyncGen(SyntaxToken), Gen(SyntaxToken), @@ -394,7 +398,13 @@ impl ast::BlockExpr { }) .or_else(|| self.async_token().map(BlockModifier::Async)) .or_else(|| self.unsafe_token().map(BlockModifier::Unsafe)) - .or_else(|| self.try_token().map(BlockModifier::Try)) + .or_else(|| { + let modifier = self.try_block_modifier()?; + let try_token = modifier.try_token()?; + let bikeshed_token = modifier.bikeshed_token(); + let result_type = modifier.ty(); + Some(BlockModifier::Try { try_token, bikeshed_token, result_type }) + }) .or_else(|| self.const_token().map(BlockModifier::Const)) .or_else(|| self.label().map(BlockModifier::Label)) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 6c1dcf336ac5..c4e72eafa793 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -323,6 +323,8 @@ impl BlockExpr { #[inline] pub fn stmt_list(&self) -> Option { support::child(&self.syntax) } #[inline] + pub fn try_block_modifier(&self) -> Option { support::child(&self.syntax) } + #[inline] pub fn async_token(&self) -> Option { support::token(&self.syntax, T![async]) } #[inline] pub fn const_token(&self) -> Option { support::token(&self.syntax, T![const]) } @@ -331,8 +333,6 @@ impl BlockExpr { #[inline] pub fn move_token(&self) -> Option { support::token(&self.syntax, T![move]) } #[inline] - pub fn try_token(&self) -> Option { support::token(&self.syntax, T![try]) } - #[inline] pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, T![unsafe]) } } pub struct BoxPat { @@ -639,10 +639,16 @@ impl ForType { pub struct FormatArgsArg { pub(crate) syntax: SyntaxNode, } -impl ast::HasName for FormatArgsArg {} impl FormatArgsArg { + #[inline] + pub fn arg_name(&self) -> Option { support::child(&self.syntax) } #[inline] pub fn expr(&self) -> Option { support::child(&self.syntax) } +} +pub struct FormatArgsArgName { + pub(crate) syntax: SyntaxNode, +} +impl FormatArgsArgName { #[inline] pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![=]) } } @@ -1624,6 +1630,19 @@ impl Trait { #[inline] pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, T![unsafe]) } } +pub struct TryBlockModifier { + pub(crate) syntax: SyntaxNode, +} +impl TryBlockModifier { + #[inline] + pub fn ty(&self) -> Option { support::child(&self.syntax) } + #[inline] + pub fn bikeshed_token(&self) -> Option { + support::token(&self.syntax, T![bikeshed]) + } + #[inline] + pub fn try_token(&self) -> Option { support::token(&self.syntax, T![try]) } +} pub struct TryExpr { pub(crate) syntax: SyntaxNode, } @@ -3722,6 +3741,38 @@ impl fmt::Debug for FormatArgsArg { f.debug_struct("FormatArgsArg").field("syntax", &self.syntax).finish() } } +impl AstNode for FormatArgsArgName { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FORMAT_ARGS_ARG_NAME + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_ARG_NAME } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for FormatArgsArgName { + fn hash(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for FormatArgsArgName {} +impl PartialEq for FormatArgsArgName { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for FormatArgsArgName { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for FormatArgsArgName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FormatArgsArgName").field("syntax", &self.syntax).finish() + } +} impl AstNode for FormatArgsExpr { #[inline] fn kind() -> SyntaxKind @@ -6282,6 +6333,38 @@ impl fmt::Debug for Trait { f.debug_struct("Trait").field("syntax", &self.syntax).finish() } } +impl AstNode for TryBlockModifier { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TRY_BLOCK_MODIFIER + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == TRY_BLOCK_MODIFIER } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for TryBlockModifier { + fn hash(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for TryBlockModifier {} +impl PartialEq for TryBlockModifier { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for TryBlockModifier { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for TryBlockModifier { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryBlockModifier").field("syntax", &self.syntax).finish() + } +} impl AstNode for TryExpr { #[inline] fn kind() -> SyntaxKind @@ -8947,7 +9030,6 @@ impl AstNode for AnyHasName { | CONST_PARAM | ENUM | FN - | FORMAT_ARGS_ARG | IDENT_PAT | MACRO_DEF | MACRO_RULES @@ -9006,10 +9088,6 @@ impl From for AnyHasName { #[inline] fn from(node: Fn) -> AnyHasName { AnyHasName { syntax: node.syntax } } } -impl From for AnyHasName { - #[inline] - fn from(node: FormatArgsArg) -> AnyHasName { AnyHasName { syntax: node.syntax } } -} impl From for AnyHasName { #[inline] fn from(node: IdentPat) -> AnyHasName { AnyHasName { syntax: node.syntax } } @@ -9541,6 +9619,11 @@ impl std::fmt::Display for FormatArgsArg { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for FormatArgsArgName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for FormatArgsExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -9941,6 +10024,11 @@ impl std::fmt::Display for Trait { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for TryBlockModifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for TryExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index dba39204e32e..98d759aef209 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -658,7 +658,7 @@ pub fn expr_if( }; expr_from_text(&format!("if {condition} {then_branch} {else_branch}")) } -pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::Expr { +pub fn expr_for_loop(pat: ast::Pat, expr: ast::Expr, block: ast::BlockExpr) -> ast::ForExpr { expr_from_text(&format!("for {pat} in {expr} {block}")) } @@ -690,6 +690,13 @@ pub fn expr_macro(path: ast::Path, tt: ast::TokenTree) -> ast::MacroExpr { pub fn expr_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr { expr_from_text(&if exclusive { format!("&mut {expr}") } else { format!("&{expr}") }) } +pub fn expr_raw_ref(expr: ast::Expr, exclusive: bool) -> ast::Expr { + expr_from_text(&if exclusive { + format!("&raw mut {expr}") + } else { + format!("&raw const {expr}") + }) +} pub fn expr_reborrow(expr: ast::Expr) -> ast::Expr { expr_from_text(&format!("&mut *{expr}")) } @@ -1016,7 +1023,19 @@ pub fn item_static( } pub fn unnamed_param(ty: ast::Type) -> ast::Param { - ast_from_text(&format!("fn f({ty}) {{ }}")) + quote! { + Param { + #ty + } + } +} + +pub fn untyped_param(pat: ast::Pat) -> ast::Param { + quote! { + Param { + #pat + } + } } pub fn param(pat: ast::Pat, ty: ast::Type) -> ast::Param { @@ -1456,3 +1475,86 @@ pub mod tokens { } } } + +#[cfg(test)] +mod tests { + use expect_test::expect; + + use super::*; + + #[track_caller] + fn check(node: impl AstNode, expect: expect_test::Expect) { + let node_debug = format!("{:#?}", node.syntax()); + expect.assert_eq(&node_debug); + } + + #[test] + fn test_unnamed_param() { + check( + unnamed_param(ty("Vec")), + expect![[r#" + PARAM@0..3 + PATH_TYPE@0..3 + PATH@0..3 + PATH_SEGMENT@0..3 + NAME_REF@0..3 + IDENT@0..3 "Vec" + "#]], + ); + + check( + unnamed_param(ty("Vec")), + expect![[r#" + PARAM@0..6 + PATH_TYPE@0..6 + PATH@0..6 + PATH_SEGMENT@0..6 + NAME_REF@0..3 + IDENT@0..3 "Vec" + GENERIC_ARG_LIST@3..6 + L_ANGLE@3..4 "<" + TYPE_ARG@4..5 + PATH_TYPE@4..5 + PATH@4..5 + PATH_SEGMENT@4..5 + NAME_REF@4..5 + IDENT@4..5 "T" + R_ANGLE@5..6 ">" + "#]], + ); + } + + #[test] + fn test_untyped_param() { + check( + untyped_param(path_pat(ext::ident_path("name"))), + expect![[r#" + PARAM@0..4 + IDENT_PAT@0..4 + NAME@0..4 + IDENT@0..4 "name" + "#]], + ); + + check( + untyped_param( + range_pat( + Some(path_pat(ext::ident_path("start"))), + Some(path_pat(ext::ident_path("end"))), + ) + .into(), + ), + expect![[r#" + PARAM@0..10 + RANGE_PAT@0..10 + IDENT_PAT@0..5 + NAME@0..5 + IDENT@0..5 "start" + DOT2@5..7 ".." + IDENT_PAT@7..10 + NAME@7..10 + IDENT@7..10 "end" + "#]], + ); + } +} diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 901d17bb1491..76cfea9d5bc6 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -447,24 +447,23 @@ impl ast::UseTreeList { impl ast::Impl { pub fn self_ty(&self) -> Option { - match self.target() { - (Some(t), None) | (_, Some(t)) => Some(t), - _ => None, - } + self.target().1 } pub fn trait_(&self) -> Option { - match self.target() { - (Some(t), Some(_)) => Some(t), - _ => None, - } + self.target().0 } fn target(&self) -> (Option, Option) { - let mut types = support::children(self.syntax()); - let first = types.next(); - let second = types.next(); - (first, second) + let mut types = support::children(self.syntax()).peekable(); + let for_kw = self.for_token(); + let trait_ = types.next_if(|trait_: &ast::Type| { + for_kw.is_some_and(|for_kw| { + trait_.syntax().text_range().start() < for_kw.text_range().start() + }) + }); + let self_ty = types.next(); + (trait_, self_ty) } pub fn for_trait_name_ref(name_ref: &ast::NameRef) -> Option { @@ -813,13 +812,16 @@ pub enum TypeBoundKind { } impl ast::TypeBound { - pub fn kind(&self) -> TypeBoundKind { + pub fn kind(&self) -> Option { if let Some(path_type) = support::children(self.syntax()).next() { - TypeBoundKind::PathType(self.for_binder(), path_type) + Some(TypeBoundKind::PathType(self.for_binder(), path_type)) + } else if let Some(for_binder) = support::children::(&self.syntax).next() { + let Some(ast::Type::PathType(path_type)) = for_binder.ty() else { return None }; + Some(TypeBoundKind::PathType(for_binder.for_binder(), path_type)) } else if let Some(args) = self.use_bound_generic_args() { - TypeBoundKind::Use(args) + Some(TypeBoundKind::Use(args)) } else if let Some(lifetime) = self.lifetime() { - TypeBoundKind::Lifetime(lifetime) + Some(TypeBoundKind::Lifetime(lifetime)) } else { unreachable!() } @@ -1093,6 +1095,16 @@ impl ast::MatchGuard { } } +impl ast::MatchArm { + pub fn parent_match(&self) -> ast::MatchExpr { + self.syntax() + .parent() + .and_then(|it| it.parent()) + .and_then(ast::MatchExpr::cast) + .expect("MatchArms are always nested in MatchExprs") + } +} + impl From for ast::AnyHasAttrs { fn from(node: ast::Item) -> Self { Self::new(node) @@ -1105,6 +1117,15 @@ impl From for ast::AnyHasAttrs { } } +impl ast::FormatArgsArgName { + /// This is not a [`ast::Name`], because the name may be a keyword. + pub fn name(&self) -> SyntaxToken { + let name = self.syntax.first_token().unwrap(); + assert!(name.kind().is_any_identifier()); + name + } +} + impl ast::OrPat { pub fn leading_pipe(&self) -> Option { self.syntax diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs index 8c88224a761a..d99cf492616e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs @@ -154,6 +154,11 @@ fn check_ancestry(ancestor: &SyntaxNode, descendent: &SyntaxNode) -> bool { bail() } +fn next_token_of(node: &SyntaxNode) -> Option { + let last = node.last_token()?; + skip_trivia_token(last.next_token()?, Direction::Next) +} + impl Expr { pub fn precedence(&self) -> ExprPrecedence { precedence(self) @@ -197,6 +202,8 @@ impl Expr { if is_parent_call_expr && is_field_expr { return true; } + let place_of_parent = + || place_of.ancestors().find(|it| it.parent().is_none_or(|p| &p == parent.syntax())); // Special-case block weirdness if parent.child_is_followed_by_a_block() { @@ -226,15 +233,24 @@ impl Expr { // For `&&`, we avoid introducing ` && ` into a binary chain. if self.precedence() == ExprPrecedence::Jump - && let Some(node) = - place_of.ancestors().find(|it| it.parent().is_none_or(|p| &p == parent.syntax())) - && let Some(next) = - node.last_token().and_then(|t| skip_trivia_token(t.next_token()?, Direction::Next)) + && let Some(node) = place_of_parent() + && let Some(next) = next_token_of(&node) && matches!(next.kind(), T![||] | T![&&]) { return true; } + // Special-case `2 as x < 3` + if let ast::Expr::CastExpr(it) = self + && let Some(ty) = it.ty() + && ty.syntax().last_token().and_then(|it| ast::NameLike::cast(it.parent()?)).is_some() + && let Some(node) = place_of_parent() + && let Some(next) = next_token_of(&node) + && matches!(next.kind(), T![<] | T![<<]) + { + return true; + } + if self.is_paren_like() || parent.is_paren_like() || self.is_prefix() diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 969552392180..6e17d262a79d 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -71,6 +71,206 @@ impl SyntaxFactory { ast } + pub fn path_from_text(&self, text: &str) -> ast::Path { + make::path_from_text(text).clone_for_update() + } + + pub fn path_concat(&self, first: ast::Path, second: ast::Path) -> ast::Path { + make::path_concat(first, second).clone_for_update() + } + + pub fn visibility_pub(&self) -> ast::Visibility { + make::visibility_pub() + } + + pub fn struct_( + &self, + visibility: Option, + strukt_name: ast::Name, + generic_param_list: Option, + field_list: ast::FieldList, + ) -> ast::Struct { + make::struct_(visibility, strukt_name, generic_param_list, field_list).clone_for_update() + } + + pub fn expr_field(&self, receiver: ast::Expr, field: &str) -> ast::FieldExpr { + let ast::Expr::FieldExpr(ast) = + make::expr_field(receiver.clone(), field).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(receiver.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn impl_trait( + &self, + attrs: impl IntoIterator, + is_unsafe: bool, + trait_gen_params: Option, + trait_gen_args: Option, + type_gen_params: Option, + type_gen_args: Option, + is_negative: bool, + path_type: ast::Type, + ty: ast::Type, + trait_where_clause: Option, + ty_where_clause: Option, + body: Option, + ) -> ast::Impl { + let (attrs, attrs_input) = iterator_input(attrs); + let ast = make::impl_trait( + attrs, + is_unsafe, + trait_gen_params.clone(), + trait_gen_args.clone(), + type_gen_params.clone(), + type_gen_args.clone(), + is_negative, + path_type.clone(), + ty.clone(), + trait_where_clause.clone(), + ty_where_clause.clone(), + body.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); + if let Some(trait_gen_params) = trait_gen_params { + builder.map_node( + trait_gen_params.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + builder.map_node(path_type.syntax().clone(), ast.trait_().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.self_ty().unwrap().syntax().clone()); + if let Some(ty_where_clause) = ty_where_clause { + builder.map_node( + ty_where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + if let Some(body) = body { + builder.map_node( + body.syntax().clone(), + ast.assoc_item_list().unwrap().syntax().clone(), + ); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn ty_alias( + &self, + attrs: impl IntoIterator, + ident: &str, + generic_param_list: Option, + type_param_bounds: Option, + where_clause: Option, + assignment: Option<(ast::Type, Option)>, + ) -> ast::TypeAlias { + let (attrs, attrs_input) = iterator_input(attrs); + let ast = make::ty_alias( + attrs, + ident, + generic_param_list.clone(), + type_param_bounds.clone(), + where_clause.clone(), + assignment.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); + if let Some(generic_param_list) = generic_param_list { + builder.map_node( + generic_param_list.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + if let Some(type_param_bounds) = type_param_bounds { + builder.map_node( + type_param_bounds.syntax().clone(), + ast.type_bound_list().unwrap().syntax().clone(), + ); + } + if let Some(where_clause) = where_clause { + builder.map_node( + where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + if let Some((ty, _)) = assignment { + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn param_list( + &self, + self_param: Option, + params: impl IntoIterator, + ) -> ast::ParamList { + let (params, input) = iterator_input(params); + let ast = make::param_list(self_param.clone(), params).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + if let Some(self_param) = self_param + && let Some(new_self_param) = ast.self_param() + { + builder.map_node(self_param.syntax().clone(), new_self_param.syntax().clone()); + } + builder.map_children(input, ast.params().map(|p| p.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + + pub fn const_param(&self, name: ast::Name, ty: ast::Type) -> ast::ConstParam { + let ast = make::const_param(name.clone(), ty.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn generic_param_list( + &self, + params: impl IntoIterator, + ) -> ast::GenericParamList { + let (params, input) = iterator_input(params); + let ast = make::generic_param_list(params).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.generic_params().map(|p| p.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + pub fn path_segment(&self, name_ref: ast::NameRef) -> ast::PathSegment { let ast = make::path_segment(name_ref.clone()).clone_for_update(); @@ -566,6 +766,22 @@ impl SyntaxFactory { ast.into() } + pub fn expr_raw_ref(&self, expr: ast::Expr, exclusive: bool) -> ast::Expr { + let ast::Expr::RefExpr(ast) = + make::expr_raw_ref(expr.clone(), exclusive).clone_for_update() + else { + unreachable!() + }; + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast.into() + } + pub fn expr_closure( &self, pats: impl IntoIterator, @@ -671,6 +887,26 @@ impl SyntaxFactory { ast } + pub fn expr_for_loop( + &self, + pat: ast::Pat, + iterable: ast::Expr, + body: ast::BlockExpr, + ) -> ast::ForExpr { + let ast = + make::expr_for_loop(pat.clone(), iterable.clone(), body.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone()); + builder.map_node(iterable.syntax().clone(), ast.iterable().unwrap().syntax().clone()); + builder.map_node(body.syntax().clone(), ast.loop_body().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + pub fn expr_let(&self, pattern: ast::Pat, expr: ast::Expr) -> ast::LetExpr { let ast = make::expr_let(pattern.clone(), expr.clone()).clone_for_update(); @@ -1272,6 +1508,23 @@ impl SyntaxFactory { ast } + pub fn assoc_item_list( + &self, + items: impl IntoIterator, + ) -> ast::AssocItemList { + let (items, input) = iterator_input(items); + let items_vec: Vec<_> = items.into_iter().collect(); + let ast = make::assoc_item_list(Some(items_vec)).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.assoc_items().map(|item| item.syntax().clone())); + builder.finish(&mut mapping); + } + + ast + } + pub fn attr_outer(&self, meta: ast::Meta) -> ast::Attr { let ast = make::attr_outer(meta.clone()).clone_for_update(); @@ -1343,6 +1596,103 @@ impl SyntaxFactory { pub fn ident(&self, text: &str) -> SyntaxToken { make::tokens::ident(text) } + + pub fn mut_self_param(&self) -> ast::SelfParam { + let ast = make::mut_self_param().clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn self_param(&self) -> ast::SelfParam { + let ast = make::self_param().clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.finish(&mut mapping); + } + + ast + } + + pub fn impl_( + &self, + attrs: impl IntoIterator, + generic_params: Option, + generic_args: Option, + path_type: ast::Type, + where_clause: Option, + body: Option, + ) -> ast::Impl { + let (attrs, attrs_input) = iterator_input(attrs); + let ast = make::impl_( + attrs, + generic_params.clone(), + generic_args.clone(), + path_type.clone(), + where_clause.clone(), + body.clone(), + ) + .clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); + if let Some(generic_params) = generic_params { + builder.map_node( + generic_params.syntax().clone(), + ast.generic_param_list().unwrap().syntax().clone(), + ); + } + builder.map_node(path_type.syntax().clone(), ast.self_ty().unwrap().syntax().clone()); + if let Some(where_clause) = where_clause { + builder.map_node( + where_clause.syntax().clone(), + ast.where_clause().unwrap().syntax().clone(), + ); + } + if let Some(body) = body { + builder.map_node( + body.syntax().clone(), + ast.assoc_item_list().unwrap().syntax().clone(), + ); + } + builder.finish(&mut mapping); + } + + ast + } + + pub fn ret_type(&self, ty: ast::Type) -> ast::RetType { + let ast = make::ret_type(ty.clone()).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone()); + builder.finish(&mut mapping); + } + ast + } + + pub fn ty_ref(&self, ty: ast::Type, is_mut: bool) -> ast::Type { + let ast = make::ty_ref(ty.clone(), is_mut).clone_for_update(); + + if let Some(mut mapping) = self.mappings() { + let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + match &ast { + ast::Type::RefType(ref_ty) => { + builder.map_node(ty.syntax().clone(), ref_ty.ty().unwrap().syntax().clone()); + } + _ => unreachable!(), + } + builder.finish(&mut mapping); + } + ast + } } // `ext` constructors diff --git a/src/tools/rust-analyzer/crates/syntax/src/lib.rs b/src/tools/rust-analyzer/crates/syntax/src/lib.rs index de341f05538e..c510b2831e12 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/lib.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/lib.rs @@ -19,6 +19,11 @@ //! [RFC]: //! [Swift]: +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + mod parsing; mod ptr; mod syntax_error; @@ -213,7 +218,18 @@ impl Drop for Parse { let (sender, receiver) = std::sync::mpsc::channel::(); std::thread::Builder::new() .name("ParseNodeDropper".to_owned()) - .spawn(move || receiver.iter().for_each(drop)) + .spawn(move || { + loop { + // block on a receive + _ = receiver.recv(); + // then drain the entire channel + while receiver.try_recv().is_ok() {} + // and sleep for a bit + std::thread::sleep(std::time::Duration::from_millis(100)); + } + // why do this over just a `receiver.iter().for_each(drop)`? To reduce contention on the channel lock. + // otherwise this thread will constantly wake up and sleep again. + }) .unwrap(); sender }) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ptr.rs b/src/tools/rust-analyzer/crates/syntax/src/ptr.rs index 34c07598d200..c4979b8e3ae8 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ptr.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ptr.rs @@ -68,7 +68,7 @@ impl AstPtr { self.raw } - pub fn text_range(&self) -> TextRange { + pub fn text_range(self) -> TextRange { self.raw.text_range() } diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs index 1eaef03197c5..6257bf4e572e 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs @@ -1,6 +1,6 @@ //! Maps syntax elements through disjoint syntax nodes. //! -//! [`SyntaxMappingBuilder`] should be used to create mappings to add to a [`SyntaxEditor`] +//! [`SyntaxMappingBuilder`] should be used to create mappings to add to a `SyntaxEditor` use itertools::Itertools; use rustc_hash::FxHashMap; diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs index 1c902893abc6..6f00ef4ed584 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs @@ -9,16 +9,6 @@ use crate::{TextRange, TextSize}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SyntaxError(String, TextRange); -// FIXME: there was an unused SyntaxErrorKind previously (before this enum was removed) -// It was introduced in this PR: https://github.com/rust-lang/rust-analyzer/pull/846/files#diff-827da9b03b8f9faa1bade5cdd44d5dafR95 -// but it was not removed by a mistake. -// -// So, we need to find a place where to stick validation for attributes in match clauses. -// Code before refactor: -// InvalidMatchInnerAttr => { -// write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression") -// } - impl SyntaxError { pub fn new(message: impl Into, range: TextRange) -> Self { Self(message.into(), range) diff --git a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml index 353d4c312dba..74a4f8363248 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml +++ b/src/tools/rust-analyzer/crates/test-fixture/Cargo.toml @@ -14,12 +14,15 @@ test-utils.workspace = true tt.workspace = true cfg.workspace = true base-db.workspace = true -rustc-hash.workspace = true span.workspace = true stdx.workspace = true intern.workspace = true triomphe.workspace = true paths.workspace = true +[features] +default = [] +in-rust-tree = [] + [lints] workspace = true diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 457cd3ac854a..ca68edd88c05 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -1,4 +1,10 @@ //! A set of high-level utility fixture methods to use in tests. + +#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] + +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + use std::{any::TypeId, mem, str::FromStr, sync}; use base_db::target::TargetData; @@ -31,7 +37,110 @@ use triomphe::Arc; pub const WORKSPACE: base_db::SourceRootId = base_db::SourceRootId(0); +/// A trait for setting up test databases from fixture strings. +/// +/// Fixtures are strings containing Rust source code with optional metadata that describe +/// a project setup. This is the primary way to write tests for rust-analyzer without +/// having to depend on the entire sysroot. +/// +/// # Fixture Syntax +/// +/// ## Basic Structure +/// +/// A fixture without metadata is parsed into a single source file (`/main.rs`). +/// Metadata is added after a `//-` comment prefix. +/// +/// ```text +/// //- /main.rs +/// fn main() { +/// println!("Hello"); +/// } +/// ``` +/// +/// Note that the fixture syntax is optional and can be omitted if the test only requires +/// a simple single file. +/// +/// ## File Metadata +/// +/// Each file can have the following metadata after `//-`: +/// +/// - **Path** (required): Must start with `/`, e.g., `/main.rs`, `/lib.rs`, `/foo/bar.rs` +/// - **`crate:`**: Defines a new crate with this file as its root +/// - Optional version: `crate:foo@0.1.0,https://example.com/repo.git` +/// - **`deps:,`**: Dependencies (requires `crate:`) +/// - **`extern-prelude:,`**: Limits extern prelude to specified crates +/// - **`edition:`**: Rust edition (2015, 2018, 2021, 2024). Defaults to current. +/// - **`cfg:=,`**: Configuration options, e.g., `cfg:test,feature="foo"` +/// - **`env:=`**: Environment variables +/// - **`crate-attr:`**: Crate-level attributes, e.g., `crate-attr:no_std` +/// - **`new_source_root:local|library`**: Starts a new source root +/// - **`library`**: Marks crate as external library (not workspace member) +/// +/// ## Global Meta (must appear at the top, in order) +/// +/// - **`//- toolchain: nightly|stable`**: Sets the Rust toolchain (default: stable) +/// - **`//- target_data_layout: `**: LLVM data layout string +/// - **`//- target_arch: `**: Target architecture (default: x86_64) +/// - **`//- proc_macros: ,`**: Enables predefined test proc macros +/// - **`//- minicore: , `**: Includes subset of libcore +/// +/// ## Cursor Markers +/// +/// Use `$0` to mark cursor position(s) in the fixture: +/// - Single `$0`: marks a position (use with [`with_position`](Self::with_position)) +/// - Two `$0` markers: marks a range (use with [`with_range`](Self::with_range)) +/// - Escape as `\$0` if you need a literal `$0` +/// +/// # Examples +/// +/// ## Single file with cursor position +/// ```text +/// r#" +/// fn main() { +/// let x$0 = 42; +/// } +/// "# +/// ``` +/// +/// ## Multiple crates with dependencies +/// ```text +/// r#" +/// //- /main.rs crate:main deps:helper +/// use helper::greet; +/// fn main() { greet(); } +/// +/// //- /lib.rs crate:helper +/// pub fn greet() {} +/// "# +/// ``` +/// +/// ## Using minicore for lang items +/// ```text +/// r#" +/// //- minicore: option, result, iterator +/// //- /main.rs +/// fn foo() -> Option { Some(42) } +/// "# +/// ``` +/// +/// The available minicore flags are listed at the top of crates\test-utils\src\minicore.rs. +/// +/// ## Using test proc macros +/// ```text +/// r#" +/// //- proc_macros: identity, mirror +/// //- /main.rs crate:main deps:proc_macros +/// use proc_macros::identity; +/// +/// #[identity] +/// fn foo() {} +/// "# +/// ``` +/// +/// Available proc macros: `identity` (attr), `DeriveIdentity` (derive), `input_replace` (attr), +/// `mirror` (bang), `shorten` (bang) pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_single_file( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -44,6 +153,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, file) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_many_files( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -60,6 +170,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, files) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_files(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> Self { let mut db = Self::default(); @@ -69,6 +180,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { db } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_files_extra_proc_macros( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -82,6 +194,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { db } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_position(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FilePosition) { let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture); @@ -89,6 +202,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, FilePosition { file_id, offset }) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_range(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FileRange) { let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture); @@ -96,6 +210,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, FileRange { file_id, range }) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_range_or_offset( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -233,6 +348,7 @@ impl ChangeFixture { Some(meta.cfg), meta.env, origin, + meta.crate_attrs, false, proc_macro_cwd.clone(), crate_ws_data.clone(), @@ -286,6 +402,7 @@ impl ChangeFixture { String::from("__ra_is_test_fixture"), )]), CrateOrigin::Lang(LangCrateOrigin::Core), + Vec::new(), false, proc_macro_cwd.clone(), crate_ws_data.clone(), @@ -316,6 +433,7 @@ impl ChangeFixture { Some(default_cfg), default_env, CrateOrigin::Local { repo: None, name: None }, + Vec::new(), false, proc_macro_cwd.clone(), crate_ws_data.clone(), @@ -379,6 +497,7 @@ impl ChangeFixture { String::from("__ra_is_test_fixture"), )]), CrateOrigin::Local { repo: None, name: None }, + Vec::new(), true, proc_macro_cwd, crate_ws_data, @@ -629,6 +748,7 @@ struct FileMeta { cfg: CfgOptions, edition: Edition, env: Env, + crate_attrs: Vec, introduce_new_source_root: Option, } @@ -660,6 +780,7 @@ impl FileMeta { cfg, edition: f.edition.map_or(Edition::CURRENT, |v| Edition::from_str(&v).unwrap()), env: f.env.into_iter().collect(), + crate_attrs: f.crate_attrs, introduce_new_source_root, } } @@ -726,6 +847,7 @@ struct IdentityProcMacroExpander; impl ProcMacroExpander for IdentityProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -748,6 +870,7 @@ struct Issue18089ProcMacroExpander; impl ProcMacroExpander for Issue18089ProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -756,7 +879,7 @@ impl ProcMacroExpander for Issue18089ProcMacroExpander { _: Span, _: String, ) -> Result { - let tt::TokenTree::Leaf(macro_name) = &subtree.0[2] else { + let Some(tt::TtElement::Leaf(macro_name)) = subtree.iter().nth(1) else { return Err(ProcMacroExpansionError::Panic("incorrect input".to_owned())); }; Ok(quote! { call_site => @@ -783,6 +906,7 @@ struct AttributeInputReplaceProcMacroExpander; impl ProcMacroExpander for AttributeInputReplaceProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, _: &TopSubtree, attrs: Option<&TopSubtree>, _: &Env, @@ -806,6 +930,7 @@ struct Issue18840ProcMacroExpander; impl ProcMacroExpander for Issue18840ProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, fn_: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -821,13 +946,14 @@ impl ProcMacroExpander for Issue18840ProcMacroExpander { // ``` // The span that was created by the fixup infra. - let fixed_up_span = fn_.token_trees().flat_tokens()[5].first_span(); + let mut iter = fn_.iter(); + iter.nth(2); + let (_, mut fn_body) = iter.expect_subtree().unwrap(); + let fixed_up_span = fn_body.nth(1).unwrap().first_span(); let mut result = quote! {fixed_up_span => ::core::compile_error! { "my cool compile_error!" } }; // Make it so we won't remove the top subtree when reversing fixups. - let top_subtree_delimiter_mut = result.top_subtree_delimiter_mut(); - top_subtree_delimiter_mut.open = def_site; - top_subtree_delimiter_mut.close = def_site; + result.set_top_subtree_delimiter_span(tt::DelimSpan::from_single(def_site)); Ok(result) } @@ -841,6 +967,7 @@ struct MirrorProcMacroExpander; impl ProcMacroExpander for MirrorProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, input: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -879,6 +1006,7 @@ struct ShortenProcMacroExpander; impl ProcMacroExpander for ShortenProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, input: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -887,20 +1015,22 @@ impl ProcMacroExpander for ShortenProcMacroExpander { _: Span, _: String, ) -> Result { - let mut result = input.0.clone(); - for it in &mut result { - if let TokenTree::Leaf(leaf) = it { - modify_leaf(leaf) + let mut result = input.clone(); + for (idx, it) in input.as_token_trees().iter_flat_tokens().enumerate() { + if let TokenTree::Leaf(mut leaf) = it { + modify_leaf(&mut leaf); + result.set_token(idx, leaf); } } - return Ok(tt::TopSubtree(result)); + return Ok(result); fn modify_leaf(leaf: &mut Leaf) { match leaf { Leaf::Literal(it) => { // XXX Currently replaces any literals with an empty string, but supporting // "shortening" other literals would be nice. - it.symbol = Symbol::empty(); + it.text_and_suffix = Symbol::empty(); + it.suffix_len = 0; } Leaf::Punct(_) => {} Leaf::Ident(it) => { @@ -921,6 +1051,7 @@ struct Issue17479ProcMacroExpander; impl ProcMacroExpander for Issue17479ProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -929,10 +1060,11 @@ impl ProcMacroExpander for Issue17479ProcMacroExpander { _: Span, _: String, ) -> Result { - let TokenTree::Leaf(Leaf::Literal(lit)) = &subtree.0[1] else { + let mut iter = subtree.iter(); + let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; - let symbol = &lit.symbol; + let symbol = Symbol::intern(lit.text()); let span = lit.span; Ok(quote! { span => #symbol() @@ -950,6 +1082,7 @@ struct Issue18898ProcMacroExpander; impl ProcMacroExpander for Issue18898ProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -960,10 +1093,8 @@ impl ProcMacroExpander for Issue18898ProcMacroExpander { ) -> Result { let span = subtree .token_trees() - .flat_tokens() - .last() - .ok_or_else(|| ProcMacroExpansionError::Panic("malformed input".to_owned()))? - .first_span(); + .last_span() + .ok_or_else(|| ProcMacroExpansionError::Panic("malformed input".to_owned()))?; let overly_long_subtree = quote! {span => { let a = 5; @@ -1005,6 +1136,7 @@ struct DisallowCfgProcMacroExpander; impl ProcMacroExpander for DisallowCfgProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _: Option<&TopSubtree>, _: &Env, @@ -1013,7 +1145,7 @@ impl ProcMacroExpander for DisallowCfgProcMacroExpander { _: Span, _: String, ) -> Result { - for tt in subtree.token_trees().flat_tokens() { + for tt in subtree.token_trees().iter_flat_tokens() { if let tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) = tt && (ident.sym == sym::cfg || ident.sym == sym::cfg_attr) { @@ -1036,6 +1168,7 @@ struct GenerateSuffixedTypeProcMacroExpander; impl ProcMacroExpander for GenerateSuffixedTypeProcMacroExpander { fn expand( &self, + _: &dyn ExpandDatabase, subtree: &TopSubtree, _attrs: Option<&TopSubtree>, _env: &Env, @@ -1044,20 +1177,23 @@ impl ProcMacroExpander for GenerateSuffixedTypeProcMacroExpander { _mixed_site: Span, _current_dir: String, ) -> Result { - let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[1] else { + let mut iter = subtree.iter(); + let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; let ident = match ident.sym.as_str() { "struct" => { - let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[2] else { + let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; ident } "enum" => { - let TokenTree::Leaf(Leaf::Ident(ident)) = &subtree.0[4] else { + iter.next(); + let (_, mut iter) = iter.expect_subtree().unwrap(); + let Some(TtElement::Leaf(tt::Leaf::Ident(ident))) = iter.next() else { return Err(ProcMacroExpansionError::Panic("incorrect Input".into())); }; ident diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs index 831d2b30c1b6..1f6262c897c7 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs @@ -107,6 +107,11 @@ pub struct Fixture { /// /// Syntax: `env:PATH=/bin,RUST_LOG=debug` pub env: FxHashMap, + /// Specifies extra crate-level attributes injected at the top of the crate root file. + /// This must be used with `crate` meta. + /// + /// Syntax: `crate-attr:no_std crate-attr:features(f16,f128) crate-attr:cfg(target_arch="x86")` + pub crate_attrs: Vec, /// Introduces a new source root. This file **and the following /// files** will belong the new source root. This must be used /// with `crate` meta. @@ -275,6 +280,7 @@ impl FixtureWithProjectMeta { let mut krate = None; let mut deps = Vec::new(); + let mut crate_attrs = Vec::new(); let mut extern_prelude = None; let mut edition = None; let mut cfgs = Vec::new(); @@ -292,6 +298,7 @@ impl FixtureWithProjectMeta { match key { "crate" => krate = Some(value.to_owned()), "deps" => deps = value.split(',').map(|it| it.to_owned()).collect(), + "crate-attr" => crate_attrs.push(value.to_owned()), "extern-prelude" => { if value.is_empty() { extern_prelude = Some(Vec::new()); @@ -334,6 +341,7 @@ impl FixtureWithProjectMeta { line, krate, deps, + crate_attrs, extern_prelude, cfgs, edition, @@ -548,7 +556,7 @@ fn parse_fixture_gets_full_meta() { //- toolchain: nightly //- proc_macros: identity //- minicore: coerce_unsized -//- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo +//- /lib.rs crate:foo deps:bar,baz crate-attr:no_std crate-attr:features(f16,f128) crate-attr:cfg(target_arch="x86") cfg:foo=a,bar=b,atom env:OUTDIR=path/to,OTHER=foo mod m; "#, ); @@ -561,6 +569,14 @@ mod m; assert_eq!("mod m;\n", meta.text); assert_eq!("foo", meta.krate.as_ref().unwrap()); + assert_eq!( + vec![ + "no_std".to_owned(), + "features(f16,f128)".to_owned(), + "cfg(target_arch=\"x86\")".to_owned() + ], + meta.crate_attrs + ); assert_eq!("/lib.rs", meta.path); assert_eq!(2, meta.env.len()); } diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index 0fe17e3075de..c34475bbdf01 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -34,7 +34,8 @@ //! eq: sized //! error: fmt //! fmt: option, result, transmute, coerce_unsized, copy, clone, derive -//! fmt_before_1_89_0: fmt +//! fmt_before_1_93_0: fmt +//! fmt_before_1_89_0: fmt_before_1_93_0 //! fn: sized, tuple //! from: sized, result //! future: pin @@ -42,6 +43,7 @@ //! dispatch_from_dyn: unsize, pin //! hash: sized //! include: +//! include_bytes: //! index: sized //! infallible: //! int_impl: size_of, transmute @@ -57,6 +59,7 @@ //! pin: //! pointee: copy, send, sync, ord, hash, unpin, phantom_data //! range: +//! new_range: //! receiver: deref //! result: //! send: sized @@ -79,6 +82,7 @@ //! offset_of: #![rustc_coherence_is_core] +#![feature(lang_items)] pub mod marker { // region:sized @@ -173,7 +177,9 @@ pub mod marker { // region:clone impl Clone for PhantomData { - fn clone(&self) -> Self { Self } + fn clone(&self) -> Self { + Self + } } // endregion:clone @@ -544,11 +550,11 @@ pub mod ptr { // endregion:non_null // region:addr_of - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] pub macro addr_of($place:expr) { &raw const $place } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] pub macro addr_of_mut($place:expr) { &raw mut $place } @@ -948,6 +954,9 @@ pub mod ops { #[lang = "from_residual"] fn from_residual(residual: R) -> Self; } + pub const trait Residual: Sized { + type TryType: [const] Try; + } #[lang = "Try"] pub trait Try: FromResidual { type Output; @@ -957,6 +966,12 @@ pub mod ops { #[lang = "branch"] fn branch(self) -> ControlFlow; } + #[lang = "into_try_type"] + pub const fn residual_into_try_type, O>( + r: R, + ) -> >::TryType { + FromResidual::from_residual(r) + } impl Try for ControlFlow { type Output = C; @@ -980,6 +995,10 @@ pub mod ops { } } } + + impl Residual for ControlFlow { + type TryType = ControlFlow; + } // region:option impl Try for Option { type Output = T; @@ -1003,6 +1022,10 @@ pub mod ops { } } } + + impl const Residual for Option { + type TryType = Option; + } // endregion:option // region:result // region:from @@ -1032,10 +1055,14 @@ pub mod ops { } } } + + impl const Residual for Result { + type TryType = Result; + } // endregion:from // endregion:result } - pub use self::try_::{ControlFlow, FromResidual, Try}; + pub use self::try_::{ControlFlow, FromResidual, Residual, Try}; // endregion:try // region:add @@ -1126,6 +1153,32 @@ pub mod ops { // endregion:dispatch_from_dyn } +// region:new_range +pub mod range { + #[lang = "RangeCopy"] + pub struct Range { + pub start: Idx, + pub end: Idx, + } + + #[lang = "RangeFromCopy"] + pub struct RangeFrom { + pub start: Idx, + } + + #[lang = "RangeInclusiveCopy"] + pub struct RangeInclusive { + pub start: Idx, + pub end: Idx, + } + + #[lang = "RangeToInclusiveCopy"] + pub struct RangeToInclusive { + pub end: Idx, + } +} +// endregion:new_range + // region:eq pub mod cmp { use crate::marker::PointeeSized; @@ -1142,7 +1195,9 @@ pub mod cmp { // region:builtin_impls impl PartialEq for () { - fn eq(&self, other: &()) -> bool { true } + fn eq(&self, other: &()) -> bool { + true + } } // endregion:builtin_impls @@ -1259,6 +1314,7 @@ pub mod fmt { Unknown, } + // region:fmt_before_1_93_0 #[lang = "format_count"] pub enum Count { Is(usize), @@ -1288,6 +1344,7 @@ pub mod fmt { Placeholder { position, fill, align, flags, precision, width } } } + // endregion:fmt_before_1_93_0 // region:fmt_before_1_89_0 #[lang = "format_unsafe_arg"] @@ -1303,6 +1360,7 @@ pub mod fmt { // endregion:fmt_before_1_89_0 } + // region:fmt_before_1_93_0 #[derive(Copy, Clone)] #[lang = "format_arguments"] pub struct Arguments<'a> { @@ -1341,6 +1399,14 @@ pub mod fmt { } // endregion:!fmt_before_1_89_0 + pub fn from_str_nonconst(s: &'static str) -> Arguments<'a> { + Self::from_str(s) + } + + pub const fn from_str(s: &'static str) -> Arguments<'a> { + Arguments { pieces: &[s], fmt: None, args: &[] } + } + pub const fn as_str(&self) -> Option<&'static str> { match (self.pieces, self.args) { ([], []) => Some(""), @@ -1349,6 +1415,41 @@ pub mod fmt { } } } + // endregion:fmt_before_1_93_0 + + // region:!fmt_before_1_93_0 + #[lang = "format_arguments"] + #[derive(Copy, Clone)] + pub struct Arguments<'a> { + // This is a non-faithful representation of `core::fmt::Arguments`, because the real one + // is too complex for minicore. + message: Option<&'a str>, + } + + impl<'a> Arguments<'a> { + pub unsafe fn new( + _template: &'a [u8; N], + _args: &'a [rt::Argument<'a>; M], + ) -> Arguments<'a> { + Arguments { message: None } + } + + pub fn from_str_nonconst(s: &'static str) -> Arguments<'a> { + Arguments { message: Some(s) } + } + + pub const fn from_str(s: &'static str) -> Arguments<'a> { + Arguments { message: Some(s) } + } + + pub fn as_str(&self) -> Option<&'static str> { + match self.message { + Some(s) => unsafe { Some(&*(s as *const str)) }, + None => None, + } + } + } + // endregion:!fmt_before_1_93_0 // region:derive pub(crate) mod derive { @@ -1519,10 +1620,7 @@ pub mod pin { } // endregion:dispatch_from_dyn // region:coerce_unsized - impl crate::ops::CoerceUnsized> for Pin where - Ptr: crate::ops::CoerceUnsized - { - } + impl crate::ops::CoerceUnsized> for Pin where Ptr: crate::ops::CoerceUnsized {} // endregion:coerce_unsized } // endregion:pin @@ -1591,6 +1689,21 @@ pub mod iter { } } + pub struct Filter { + iter: I, + predicate: P, + } + impl Iterator for Filter + where + P: FnMut(&I::Item) -> bool, + { + type Item = I::Item; + + fn next(&mut self) -> Option { + loop {} + } + } + pub struct FilterMap { iter: I, f: F, @@ -1607,7 +1720,7 @@ pub mod iter { } } } - pub use self::adapters::{FilterMap, Take}; + pub use self::adapters::{Filter, FilterMap, Take}; mod sources { mod repeat { @@ -1658,6 +1771,13 @@ pub mod iter { { loop {} } + fn filter

(self, predicate: P) -> crate::iter::Filter + where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + loop {} + } fn filter_map(self, _f: F) -> crate::iter::FilterMap where Self: Sized, @@ -1744,9 +1864,9 @@ pub mod iter { fn from_iter>(iter: T) -> Self; } } - pub use self::collect::{IntoIterator, FromIterator}; + pub use self::collect::{FromIterator, IntoIterator}; } - pub use self::traits::{IntoIterator, FromIterator, Iterator}; + pub use self::traits::{FromIterator, IntoIterator, Iterator}; } // endregion:iterator @@ -1817,7 +1937,7 @@ mod panicking { #[lang = "panic"] pub const fn panic(expr: &'static str) -> ! { - panic_fmt(crate::fmt::Arguments::new_const(&[expr])) + panic_fmt(crate::fmt::Arguments::from_str(expr)) } } // endregion:panic @@ -1832,6 +1952,10 @@ mod arch { pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) { /* compiler built-in */ } + #[rustc_builtin_macro] + pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) { + /* compiler built-in */ + } } // endregion:asm @@ -1960,6 +2084,14 @@ mod macros { } // endregion:include + // region:include_bytes + #[rustc_builtin_macro] + #[macro_export] + macro_rules! include_bytes { + ($file:expr $(,)?) => {{ /* compiler built-in */ }}; + } + // endregion:include_bytes + // region:concat #[rustc_builtin_macro] #[macro_export] @@ -2039,30 +2171,30 @@ macro_rules! column { pub mod prelude { pub mod v1 { pub use crate::{ - clone::Clone, // :clone - cmp::{Eq, PartialEq}, // :eq - cmp::{Ord, PartialOrd}, // :ord - convert::AsMut, // :as_mut - convert::AsRef, // :as_ref - convert::{From, Into, TryFrom, TryInto}, // :from - default::Default, // :default - iter::{IntoIterator, Iterator, FromIterator}, // :iterator - macros::builtin::{derive, derive_const}, // :derive - marker::Copy, // :copy - marker::Send, // :send - marker::Sized, // :sized - marker::Sync, // :sync - mem::drop, // :drop - mem::size_of, // :size_of - ops::Drop, // :drop - ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}, // :async_fn - ops::{Fn, FnMut, FnOnce}, // :fn - option::Option::{self, None, Some}, // :option - panic, // :panic - result::Result::{self, Err, Ok}, // :result - str::FromStr, // :str - fmt::derive::Debug, // :fmt, derive - hash::derive::Hash, // :hash, derive + clone::Clone, // :clone + cmp::{Eq, PartialEq}, // :eq + cmp::{Ord, PartialOrd}, // :ord + convert::AsMut, // :as_mut + convert::AsRef, // :as_ref + convert::{From, Into, TryFrom, TryInto}, // :from + default::Default, // :default + fmt::derive::Debug, // :fmt, derive + hash::derive::Hash, // :hash, derive + iter::{FromIterator, IntoIterator, Iterator}, // :iterator + macros::builtin::{derive, derive_const}, // :derive + marker::Copy, // :copy + marker::Send, // :send + marker::Sized, // :sized + marker::Sync, // :sync + mem::drop, // :drop + mem::size_of, // :size_of + ops::Drop, // :drop + ops::{AsyncFn, AsyncFnMut, AsyncFnOnce}, // :async_fn + ops::{Fn, FnMut, FnOnce}, // :fn + option::Option::{self, None, Some}, // :option + panic, // :panic + result::Result::{self, Err, Ok}, // :result + str::FromStr, // :str }; } diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml index 82e7c24668fe..6cfb76400e3c 100644 --- a/src/tools/rust-analyzer/crates/tt/Cargo.toml +++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml @@ -15,12 +15,16 @@ doctest = false [dependencies] arrayvec.workspace = true text-size.workspace = true +rustc-hash.workspace = true +indexmap.workspace = true +span = { path = "../span", version = "0.0", default-features = false } stdx.workspace = true intern.workspace = true ra-ap-rustc_lexer.workspace = true [features] +default = [] in-rust-tree = [] [lints] diff --git a/src/tools/rust-analyzer/crates/tt/src/buffer.rs b/src/tools/rust-analyzer/crates/tt/src/buffer.rs index 02a722895a4b..78cf4b956d0c 100644 --- a/src/tools/rust-analyzer/crates/tt/src/buffer.rs +++ b/src/tools/rust-analyzer/crates/tt/src/buffer.rs @@ -1,16 +1,16 @@ //! Stateful iteration over token trees. //! //! We use this as the source of tokens for parser. -use crate::{Leaf, Subtree, TokenTree, TokenTreesView}; +use crate::{Leaf, Subtree, TokenTree, TokenTreesView, dispatch_ref}; -pub struct Cursor<'a, Span> { - buffer: &'a [TokenTree], +pub struct Cursor<'a> { + buffer: TokenTreesView<'a>, index: usize, subtrees_stack: Vec, } -impl<'a, Span: Copy> Cursor<'a, Span> { - pub fn new(buffer: &'a [TokenTree]) -> Self { +impl<'a> Cursor<'a> { + pub fn new(buffer: TokenTreesView<'a>) -> Self { Self { buffer, index: 0, subtrees_stack: Vec::new() } } @@ -23,16 +23,22 @@ impl<'a, Span: Copy> Cursor<'a, Span> { self.subtrees_stack.is_empty() } - fn last_subtree(&self) -> Option<(usize, &'a Subtree)> { + fn at(&self, idx: usize) -> Option { + dispatch_ref! { + match self.buffer.repr => tt => Some(tt.get(idx)?.to_api(self.buffer.span_parts)) + } + } + + fn last_subtree(&self) -> Option<(usize, Subtree)> { self.subtrees_stack.last().map(|&subtree_idx| { - let TokenTree::Subtree(subtree) = &self.buffer[subtree_idx] else { + let Some(TokenTree::Subtree(subtree)) = self.at(subtree_idx) else { panic!("subtree pointing to non-subtree"); }; (subtree_idx, subtree) }) } - pub fn end(&mut self) -> &'a Subtree { + pub fn end(&mut self) -> Subtree { let (last_subtree_idx, last_subtree) = self.last_subtree().expect("called `Cursor::end()` without an open subtree"); // +1 because `Subtree.len` excludes the subtree itself. @@ -46,14 +52,14 @@ impl<'a, Span: Copy> Cursor<'a, Span> { } /// Returns the `TokenTree` at the cursor if it is not at the end of a subtree. - pub fn token_tree(&self) -> Option<&'a TokenTree> { + pub fn token_tree(&self) -> Option { if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() { // +1 because `Subtree.len` excludes the subtree itself. if last_subtree_idx + last_subtree.usize_len() + 1 == self.index { return None; } } - self.buffer.get(self.index) + self.at(self.index) } /// Bump the cursor, and enters a subtree if it is on one. @@ -66,7 +72,7 @@ impl<'a, Span: Copy> Cursor<'a, Span> { "called `Cursor::bump()` when at the end of a subtree" ); } - if let TokenTree::Subtree(_) = self.buffer[self.index] { + if let Some(TokenTree::Subtree(_)) = self.at(self.index) { self.subtrees_stack.push(self.index); } self.index += 1; @@ -81,13 +87,13 @@ impl<'a, Span: Copy> Cursor<'a, Span> { } } // +1 because `Subtree.len` excludes the subtree itself. - if let TokenTree::Subtree(_) = self.buffer[self.index] { + if let Some(TokenTree::Subtree(_)) = self.at(self.index) { self.subtrees_stack.push(self.index); } self.index += 1; } - pub fn peek_two_leaves(&self) -> Option<[&'a Leaf; 2]> { + pub fn peek_two_leaves(&self) -> Option<[Leaf; 2]> { if let Some((last_subtree_idx, last_subtree)) = self.last_subtree() { // +1 because `Subtree.len` excludes the subtree itself. let last_end = last_subtree_idx + last_subtree.usize_len() + 1; @@ -95,14 +101,17 @@ impl<'a, Span: Copy> Cursor<'a, Span> { return None; } } - self.buffer.get(self.index..self.index + 2).and_then(|it| match it { - [TokenTree::Leaf(a), TokenTree::Leaf(b)] => Some([a, b]), + self.at(self.index).zip(self.at(self.index + 1)).and_then(|it| match it { + (TokenTree::Leaf(a), TokenTree::Leaf(b)) => Some([a, b]), _ => None, }) } - pub fn crossed(&self) -> TokenTreesView<'a, Span> { + pub fn crossed(&self) -> TokenTreesView<'a> { assert!(self.is_root()); - TokenTreesView::new(&self.buffer[..self.index]) + TokenTreesView { + repr: self.buffer.repr.get(..self.index).unwrap(), + span_parts: self.buffer.span_parts, + } } } diff --git a/src/tools/rust-analyzer/crates/tt/src/iter.rs b/src/tools/rust-analyzer/crates/tt/src/iter.rs index 2e89d762a0e4..7caacd40dd7e 100644 --- a/src/tools/rust-analyzer/crates/tt/src/iter.rs +++ b/src/tools/rust-analyzer/crates/tt/src/iter.rs @@ -5,58 +5,62 @@ use std::fmt; use arrayvec::ArrayVec; use intern::sym; +use span::Span; -use crate::{Ident, Leaf, MAX_GLUED_PUNCT_LEN, Punct, Spacing, Subtree, TokenTree, TokenTreesView}; +use crate::{ + Ident, Leaf, MAX_GLUED_PUNCT_LEN, Punct, Spacing, Subtree, TokenTree, TokenTreesReprRef, + TokenTreesView, dispatch_ref, +}; #[derive(Clone)] -pub struct TtIter<'a, S> { - inner: std::slice::Iter<'a, TokenTree>, +pub struct TtIter<'a> { + inner: TokenTreesView<'a>, } -impl fmt::Debug for TtIter<'_, S> { +impl fmt::Debug for TtIter<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TtIter").field("remaining", &self.remaining()).finish() } } #[derive(Clone, Copy)] -pub struct TtIterSavepoint<'a, S>(&'a [TokenTree]); +pub struct TtIterSavepoint<'a>(TokenTreesView<'a>); -impl<'a, S: Copy> TtIterSavepoint<'a, S> { - pub fn remaining(self) -> TokenTreesView<'a, S> { - TokenTreesView::new(self.0) +impl<'a> TtIterSavepoint<'a> { + pub fn remaining(self) -> TokenTreesView<'a> { + self.0 } } -impl<'a, S: Copy> TtIter<'a, S> { - pub(crate) fn new(tt: &'a [TokenTree]) -> TtIter<'a, S> { - TtIter { inner: tt.iter() } +impl<'a> TtIter<'a> { + pub(crate) fn new(tt: TokenTreesView<'a>) -> TtIter<'a> { + TtIter { inner: tt } } pub fn expect_char(&mut self, char: char) -> Result<(), ()> { match self.next() { - Some(TtElement::Leaf(&Leaf::Punct(Punct { char: c, .. }))) if c == char => Ok(()), + Some(TtElement::Leaf(Leaf::Punct(Punct { char: c, .. }))) if c == char => Ok(()), _ => Err(()), } } pub fn expect_any_char(&mut self, chars: &[char]) -> Result<(), ()> { match self.next() { - Some(TtElement::Leaf(Leaf::Punct(Punct { char: c, .. }))) if chars.contains(c) => { + Some(TtElement::Leaf(Leaf::Punct(Punct { char: c, .. }))) if chars.contains(&c) => { Ok(()) } _ => Err(()), } } - pub fn expect_subtree(&mut self) -> Result<(&'a Subtree, TtIter<'a, S>), ()> { + pub fn expect_subtree(&mut self) -> Result<(Subtree, TtIter<'a>), ()> { match self.next() { Some(TtElement::Subtree(subtree, iter)) => Ok((subtree, iter)), _ => Err(()), } } - pub fn expect_leaf(&mut self) -> Result<&'a Leaf, ()> { + pub fn expect_leaf(&mut self) -> Result { match self.next() { Some(TtElement::Leaf(it)) => Ok(it), _ => Err(()), @@ -77,30 +81,30 @@ impl<'a, S: Copy> TtIter<'a, S> { } } - pub fn expect_ident(&mut self) -> Result<&'a Ident, ()> { + pub fn expect_ident(&mut self) -> Result { match self.expect_leaf()? { Leaf::Ident(it) if it.sym != sym::underscore => Ok(it), _ => Err(()), } } - pub fn expect_ident_or_underscore(&mut self) -> Result<&'a Ident, ()> { + pub fn expect_ident_or_underscore(&mut self) -> Result { match self.expect_leaf()? { Leaf::Ident(it) => Ok(it), _ => Err(()), } } - pub fn expect_literal(&mut self) -> Result<&'a Leaf, ()> { + pub fn expect_literal(&mut self) -> Result { let it = self.expect_leaf()?; - match it { + match &it { Leaf::Literal(_) => Ok(it), Leaf::Ident(ident) if ident.sym == sym::true_ || ident.sym == sym::false_ => Ok(it), _ => Err(()), } } - pub fn expect_single_punct(&mut self) -> Result<&'a Punct, ()> { + pub fn expect_single_punct(&mut self) -> Result { match self.expect_leaf()? { Leaf::Punct(it) => Ok(it), _ => Err(()), @@ -111,8 +115,8 @@ impl<'a, S: Copy> TtIter<'a, S> { /// /// This method currently may return a single quotation, which is part of lifetime ident and /// conceptually not a punct in the context of mbe. Callers should handle this. - pub fn expect_glued_punct(&mut self) -> Result, MAX_GLUED_PUNCT_LEN>, ()> { - let TtElement::Leaf(&Leaf::Punct(first)) = self.next().ok_or(())? else { + pub fn expect_glued_punct(&mut self) -> Result, ()> { + let TtElement::Leaf(Leaf::Punct(first)) = self.next().ok_or(())? else { return Err(()); }; @@ -140,8 +144,8 @@ impl<'a, S: Copy> TtIter<'a, S> { let _ = self.next().unwrap(); let _ = self.next().unwrap(); res.push(first); - res.push(*second); - res.push(*third.unwrap()); + res.push(second); + res.push(third.unwrap()); } ('-' | '!' | '*' | '/' | '&' | '%' | '^' | '+' | '<' | '=' | '>' | '|', '=', _) | ('-' | '=' | '>', '>', _) @@ -153,7 +157,7 @@ impl<'a, S: Copy> TtIter<'a, S> { | ('|', '|', _) => { let _ = self.next().unwrap(); res.push(first); - res.push(*second); + res.push(second); } _ => res.push(first), } @@ -161,16 +165,20 @@ impl<'a, S: Copy> TtIter<'a, S> { } /// This method won't check for subtrees, so the nth token tree may not be the nth sibling of the current tree. - fn peek_n(&self, n: usize) -> Option<&'a TokenTree> { - self.inner.as_slice().get(n) + fn peek_n(&self, n: usize) -> Option { + dispatch_ref! { + match self.inner.repr => tt => Some(tt.get(n)?.to_api(self.inner.span_parts)) + } } - pub fn peek(&self) -> Option> { - match self.inner.as_slice().first()? { + pub fn peek(&self) -> Option> { + match self.peek_n(0)? { TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf)), TokenTree::Subtree(subtree) => { - let nested_iter = - TtIter { inner: self.inner.as_slice()[1..][..subtree.usize_len()].iter() }; + let nested_repr = self.inner.repr.get(1..subtree.usize_len() + 1).unwrap(); + let nested_iter = TtIter { + inner: TokenTreesView { repr: nested_repr, span_parts: self.inner.span_parts }, + }; Some(TtElement::Subtree(subtree, nested_iter)) } } @@ -181,30 +189,55 @@ impl<'a, S: Copy> TtIter<'a, S> { self.inner.len() == 0 } - pub fn next_span(&self) -> Option { - Some(self.inner.as_slice().first()?.first_span()) + pub fn next_span(&self) -> Option { + Some(self.peek()?.first_span()) } - pub fn remaining(&self) -> TokenTreesView<'a, S> { - TokenTreesView::new(self.inner.as_slice()) + pub fn remaining(&self) -> TokenTreesView<'a> { + self.inner } /// **Warning**: This advances `skip` **flat** token trees, subtrees account for children+1! pub fn flat_advance(&mut self, skip: usize) { - self.inner = self.inner.as_slice()[skip..].iter(); + self.inner.repr = self.inner.repr.get(skip..).unwrap(); } - pub fn savepoint(&self) -> TtIterSavepoint<'a, S> { - TtIterSavepoint(self.inner.as_slice()) + pub fn savepoint(&self) -> TtIterSavepoint<'a> { + TtIterSavepoint(self.inner) } - pub fn from_savepoint(&self, savepoint: TtIterSavepoint<'a, S>) -> TokenTreesView<'a, S> { - let len = (self.inner.as_slice().as_ptr() as usize - savepoint.0.as_ptr() as usize) - / size_of::>(); - TokenTreesView::new(&savepoint.0[..len]) + pub fn from_savepoint(&self, savepoint: TtIterSavepoint<'a>) -> TokenTreesView<'a> { + let len = match (self.inner.repr, savepoint.0.repr) { + ( + TokenTreesReprRef::SpanStorage32(this), + TokenTreesReprRef::SpanStorage32(savepoint), + ) => { + (this.as_ptr() as usize - savepoint.as_ptr() as usize) + / size_of::>() + } + ( + TokenTreesReprRef::SpanStorage64(this), + TokenTreesReprRef::SpanStorage64(savepoint), + ) => { + (this.as_ptr() as usize - savepoint.as_ptr() as usize) + / size_of::>() + } + ( + TokenTreesReprRef::SpanStorage96(this), + TokenTreesReprRef::SpanStorage96(savepoint), + ) => { + (this.as_ptr() as usize - savepoint.as_ptr() as usize) + / size_of::>() + } + _ => panic!("savepoint did not originate from this TtIter"), + }; + TokenTreesView { + repr: savepoint.0.repr.get(..len).unwrap(), + span_parts: savepoint.0.span_parts, + } } - pub fn next_as_view(&mut self) -> Option> { + pub fn next_as_view(&mut self) -> Option> { let savepoint = self.savepoint(); self.next()?; Some(self.from_savepoint(savepoint)) @@ -212,12 +245,12 @@ impl<'a, S: Copy> TtIter<'a, S> { } #[derive(Clone)] -pub enum TtElement<'a, S> { - Leaf(&'a Leaf), - Subtree(&'a Subtree, TtIter<'a, S>), +pub enum TtElement<'a> { + Leaf(Leaf), + Subtree(Subtree, TtIter<'a>), } -impl fmt::Debug for TtElement<'_, S> { +impl fmt::Debug for TtElement<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Leaf(leaf) => f.debug_tuple("Leaf").field(leaf).finish(), @@ -228,9 +261,9 @@ impl fmt::Debug for TtElement<'_, S> { } } -impl TtElement<'_, S> { +impl TtElement<'_> { #[inline] - pub fn first_span(&self) -> S { + pub fn first_span(&self) -> Span { match self { TtElement::Leaf(it) => *it.span(), TtElement::Subtree(it, _) => it.delimiter.open, @@ -238,17 +271,15 @@ impl TtElement<'_, S> { } } -impl<'a, S> Iterator for TtIter<'a, S> { - type Item = TtElement<'a, S>; +impl<'a> Iterator for TtIter<'a> { + type Item = TtElement<'a>; fn next(&mut self) -> Option { - match self.inner.next()? { - TokenTree::Leaf(leaf) => Some(TtElement::Leaf(leaf)), - TokenTree::Subtree(subtree) => { - let nested_iter = - TtIter { inner: self.inner.as_slice()[..subtree.usize_len()].iter() }; - self.inner = self.inner.as_slice()[subtree.usize_len()..].iter(); - Some(TtElement::Subtree(subtree, nested_iter)) - } - } + let result = self.peek()?; + let skip = match &result { + TtElement::Leaf(_) => 1, + TtElement::Subtree(subtree, _) => subtree.usize_len() + 1, + }; + self.inner.repr = self.inner.repr.get(skip..).unwrap(); + Some(result) } } diff --git a/src/tools/rust-analyzer/crates/tt/src/lib.rs b/src/tools/rust-analyzer/crates/tt/src/lib.rs index ea0752250db1..72b0d762ef62 100644 --- a/src/tools/rust-analyzer/crates/tt/src/lib.rs +++ b/src/tools/rust-analyzer/crates/tt/src/lib.rs @@ -5,6 +5,9 @@ #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] +#[cfg(feature = "in-rust-tree")] +extern crate rustc_driver as _; + #[cfg(not(feature = "in-rust-tree"))] extern crate ra_ap_rustc_lexer as rustc_lexer; #[cfg(feature = "in-rust-tree")] @@ -12,16 +15,23 @@ extern crate rustc_lexer; pub mod buffer; pub mod iter; +mod storage; -use std::fmt; +use std::{fmt, slice::SliceIndex}; +use arrayvec::ArrayString; use buffer::Cursor; use intern::Symbol; -use iter::{TtElement, TtIter}; use stdx::{impl_from, itertools::Itertools as _}; +pub use span::Span; pub use text_size::{TextRange, TextSize}; +use crate::storage::{CompressedSpanPart, SpanStorage}; + +pub use self::iter::{TtElement, TtIter}; +pub use self::storage::{TopSubtree, TopSubtreeBuilder}; + pub const MAX_GLUED_PUNCT_LEN: usize = 3; #[derive(Clone, PartialEq, Debug)] @@ -74,13 +84,13 @@ pub enum LitKind { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum TokenTree { - Leaf(Leaf), - Subtree(Subtree), +pub enum TokenTree { + Leaf(Leaf), + Subtree(Subtree), } -impl_from!(Leaf, Subtree for TokenTree); -impl TokenTree { - pub fn first_span(&self) -> S { +impl_from!(Leaf, Subtree for TokenTree); +impl TokenTree { + pub fn first_span(&self) -> Span { match self { TokenTree::Leaf(l) => *l.span(), TokenTree::Subtree(s) => s.delimiter.open, @@ -89,14 +99,14 @@ impl TokenTree { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Leaf { - Literal(Literal), - Punct(Punct), - Ident(Ident), +pub enum Leaf { + Literal(Literal), + Punct(Punct), + Ident(Ident), } -impl Leaf { - pub fn span(&self) -> &S { +impl Leaf { + pub fn span(&self) -> &Span { match self { Leaf::Literal(it) => &it.span, Leaf::Punct(it) => &it.span, @@ -104,282 +114,120 @@ impl Leaf { } } } -impl_from!(Literal, Punct, Ident for Leaf); +impl_from!(Literal, Punct, Ident for Leaf); -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Subtree { - pub delimiter: Delimiter, +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Subtree { + pub delimiter: Delimiter, /// Number of following token trees that belong to this subtree, excluding this subtree. pub len: u32, } -impl Subtree { +impl Subtree { pub fn usize_len(&self) -> usize { self.len as usize } } -#[derive(Clone, PartialEq, Eq, Hash)] -pub struct TopSubtree(pub Box<[TokenTree]>); +#[rust_analyzer::macro_style(braces)] +macro_rules! dispatch_ref { + ( + match $scrutinee:expr => $tt:ident => $body:expr + ) => { + match $scrutinee { + $crate::TokenTreesReprRef::SpanStorage32($tt) => $body, + $crate::TokenTreesReprRef::SpanStorage64($tt) => $body, + $crate::TokenTreesReprRef::SpanStorage96($tt) => $body, + } + }; +} +use dispatch_ref; -impl TopSubtree { - pub fn empty(span: DelimSpan) -> Self { - Self(Box::new([TokenTree::Subtree(Subtree { - delimiter: Delimiter::invisible_delim_spanned(span), - len: 0, - })])) - } - - pub fn invisible_from_leaves(delim_span: S, leaves: [Leaf; N]) -> Self { - let mut builder = TopSubtreeBuilder::new(Delimiter::invisible_spanned(delim_span)); - builder.extend(leaves); - builder.build() - } - - pub fn from_token_trees(delimiter: Delimiter, token_trees: TokenTreesView<'_, S>) -> Self { - let mut builder = TopSubtreeBuilder::new(delimiter); - builder.extend_with_tt(token_trees); - builder.build() - } - - pub fn from_subtree(subtree: SubtreeView<'_, S>) -> Self { - Self(subtree.0.into()) - } - - pub fn view(&self) -> SubtreeView<'_, S> { - SubtreeView::new(&self.0) - } - - pub fn iter(&self) -> TtIter<'_, S> { - self.view().iter() - } - - pub fn top_subtree(&self) -> &Subtree { - self.view().top_subtree() - } - - pub fn top_subtree_delimiter_mut(&mut self) -> &mut Delimiter { - let TokenTree::Subtree(subtree) = &mut self.0[0] else { - unreachable!("the first token tree is always the top subtree"); - }; - &mut subtree.delimiter - } - - pub fn token_trees(&self) -> TokenTreesView<'_, S> { - self.view().token_trees() - } +#[derive(Clone, Copy)] +enum TokenTreesReprRef<'a> { + SpanStorage32(&'a [crate::storage::TokenTree]), + SpanStorage64(&'a [crate::storage::TokenTree]), + SpanStorage96(&'a [crate::storage::TokenTree]), } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TopSubtreeBuilder { - unclosed_subtree_indices: Vec, - token_trees: Vec>, - last_closed_subtree: Option, -} - -impl TopSubtreeBuilder { - pub fn new(top_delimiter: Delimiter) -> Self { - let mut result = Self { - unclosed_subtree_indices: Vec::new(), - token_trees: Vec::new(), - last_closed_subtree: None, - }; - let top_subtree = TokenTree::Subtree(Subtree { delimiter: top_delimiter, len: 0 }); - result.token_trees.push(top_subtree); - result - } - - pub fn open(&mut self, delimiter_kind: DelimiterKind, open_span: S) { - self.unclosed_subtree_indices.push(self.token_trees.len()); - self.token_trees.push(TokenTree::Subtree(Subtree { - delimiter: Delimiter { - open: open_span, - close: open_span, // Will be overwritten on close. - kind: delimiter_kind, - }, - len: 0, - })); - } - - pub fn close(&mut self, close_span: S) { - let last_unclosed_index = self - .unclosed_subtree_indices - .pop() - .expect("attempt to close a `tt::Subtree` when none is open"); - let subtree_len = (self.token_trees.len() - last_unclosed_index - 1) as u32; - let TokenTree::Subtree(subtree) = &mut self.token_trees[last_unclosed_index] else { - unreachable!("unclosed token tree is always a subtree"); - }; - subtree.len = subtree_len; - subtree.delimiter.close = close_span; - self.last_closed_subtree = Some(last_unclosed_index); - } - - /// You cannot call this consecutively, it will only work once after close. - pub fn remove_last_subtree_if_invisible(&mut self) { - let Some(last_subtree_idx) = self.last_closed_subtree else { return }; - if let TokenTree::Subtree(Subtree { - delimiter: Delimiter { kind: DelimiterKind::Invisible, .. }, - .. - }) = self.token_trees[last_subtree_idx] - { - self.token_trees.remove(last_subtree_idx); - self.last_closed_subtree = None; - } - } - - pub fn push(&mut self, leaf: Leaf) { - self.token_trees.push(TokenTree::Leaf(leaf)); - } - - pub fn extend(&mut self, leaves: impl IntoIterator>) { - self.token_trees.extend(leaves.into_iter().map(TokenTree::Leaf)); - } - - /// This does not check the token trees are valid, beware! - pub fn extend_tt_dangerous(&mut self, tt: impl IntoIterator>) { - self.token_trees.extend(tt); - } - - pub fn extend_with_tt(&mut self, tt: TokenTreesView<'_, S>) { - self.token_trees.extend(tt.0.iter().cloned()); - } - - /// Like [`Self::extend_with_tt()`], but makes sure the new tokens will never be - /// joint with whatever comes after them. - pub fn extend_with_tt_alone(&mut self, tt: TokenTreesView<'_, S>) { - if let Some((last, before_last)) = tt.0.split_last() { - self.token_trees.reserve(tt.0.len()); - self.token_trees.extend(before_last.iter().cloned()); - let last = if let TokenTree::Leaf(Leaf::Punct(last)) = last { - let mut last = *last; - last.spacing = Spacing::Alone; - TokenTree::Leaf(Leaf::Punct(last)) - } else { - last.clone() - }; - self.token_trees.push(last); - } - } - - pub fn expected_delimiters(&self) -> impl Iterator> { - self.unclosed_subtree_indices.iter().rev().map(|&subtree_idx| { - let TokenTree::Subtree(subtree) = &self.token_trees[subtree_idx] else { - unreachable!("unclosed token tree is always a subtree") - }; - &subtree.delimiter +impl<'a> TokenTreesReprRef<'a> { + #[inline] + fn get(&self, index: I) -> Option + where + I: SliceIndex< + [crate::storage::TokenTree], + Output = [crate::storage::TokenTree], + >, + I: SliceIndex< + [crate::storage::TokenTree], + Output = [crate::storage::TokenTree], + >, + I: SliceIndex< + [crate::storage::TokenTree], + Output = [crate::storage::TokenTree], + >, + { + Some(match self { + TokenTreesReprRef::SpanStorage32(tt) => { + TokenTreesReprRef::SpanStorage32(tt.get(index)?) + } + TokenTreesReprRef::SpanStorage64(tt) => { + TokenTreesReprRef::SpanStorage64(tt.get(index)?) + } + TokenTreesReprRef::SpanStorage96(tt) => { + TokenTreesReprRef::SpanStorage96(tt.get(index)?) + } }) } - - /// Builds, and remove the top subtree if it has only one subtree child. - pub fn build_skip_top_subtree(mut self) -> TopSubtree { - let top_tts = TokenTreesView::new(&self.token_trees[1..]); - match top_tts.try_into_subtree() { - Some(_) => { - assert!( - self.unclosed_subtree_indices.is_empty(), - "attempt to build an unbalanced `TopSubtreeBuilder`" - ); - TopSubtree(self.token_trees.drain(1..).collect()) - } - None => self.build(), - } - } - - pub fn build(mut self) -> TopSubtree { - assert!( - self.unclosed_subtree_indices.is_empty(), - "attempt to build an unbalanced `TopSubtreeBuilder`" - ); - let total_len = self.token_trees.len() as u32; - let TokenTree::Subtree(top_subtree) = &mut self.token_trees[0] else { - unreachable!("first token tree is always a subtree"); - }; - top_subtree.len = total_len - 1; - TopSubtree(self.token_trees.into_boxed_slice()) - } - - pub fn restore_point(&self) -> SubtreeBuilderRestorePoint { - SubtreeBuilderRestorePoint { - unclosed_subtree_indices_len: self.unclosed_subtree_indices.len(), - token_trees_len: self.token_trees.len(), - last_closed_subtree: self.last_closed_subtree, - } - } - - pub fn restore(&mut self, restore_point: SubtreeBuilderRestorePoint) { - self.unclosed_subtree_indices.truncate(restore_point.unclosed_subtree_indices_len); - self.token_trees.truncate(restore_point.token_trees_len); - self.last_closed_subtree = restore_point.last_closed_subtree; - } } #[derive(Clone, Copy)] -pub struct SubtreeBuilderRestorePoint { - unclosed_subtree_indices_len: usize, - token_trees_len: usize, - last_closed_subtree: Option, +pub struct TokenTreesView<'a> { + repr: TokenTreesReprRef<'a>, + span_parts: &'a [CompressedSpanPart], } -#[derive(Clone, Copy)] -pub struct TokenTreesView<'a, S>(&'a [TokenTree]); - -impl<'a, S: Copy> TokenTreesView<'a, S> { - pub fn new(tts: &'a [TokenTree]) -> Self { - if cfg!(debug_assertions) { - tts.iter().enumerate().for_each(|(idx, tt)| { - if let TokenTree::Subtree(tt) = &tt { - // `<` and not `<=` because `Subtree.len` does not include the subtree node itself. - debug_assert!( - idx + tt.usize_len() < tts.len(), - "`TokenTreeView::new()` was given a cut-in-half list" - ); - } - }); - } - Self(tts) +impl<'a> TokenTreesView<'a> { + pub fn empty() -> Self { + Self { repr: TokenTreesReprRef::SpanStorage32(&[]), span_parts: &[] } } - pub fn iter(&self) -> TtIter<'a, S> { - TtIter::new(self.0) + pub fn iter(&self) -> TtIter<'a> { + TtIter::new(*self) } - pub fn cursor(&self) -> Cursor<'a, S> { - Cursor::new(self.0) + pub fn cursor(&self) -> Cursor<'a> { + Cursor::new(*self) } pub fn len(&self) -> usize { - self.0.len() + dispatch_ref! { + match self.repr => tt => tt.len() + } } pub fn is_empty(&self) -> bool { - self.0.is_empty() + self.len() == 0 } - pub fn try_into_subtree(self) -> Option> { - if let Some(TokenTree::Subtree(subtree)) = self.0.first() - && subtree.usize_len() == (self.0.len() - 1) - { - return Some(SubtreeView::new(self.0)); - } - None + pub fn try_into_subtree(self) -> Option> { + let is_subtree = dispatch_ref! { + match self.repr => tt => matches!( + tt.first(), + Some(crate::storage::TokenTree::Subtree { len, .. }) if (*len as usize) == (tt.len() - 1) + ) + }; + if is_subtree { Some(SubtreeView(self)) } else { None } } - pub fn strip_invisible(self) -> TokenTreesView<'a, S> { + pub fn strip_invisible(self) -> TokenTreesView<'a> { self.try_into_subtree().map(|subtree| subtree.strip_invisible()).unwrap_or(self) } - /// This returns a **flat** structure of tokens (subtrees will be represented by a single node - /// preceding their children), so it isn't suited for most use cases, only for matching leaves - /// at the beginning/end with no subtrees before them. If you need a structured pass, use [`TtIter`]. - pub fn flat_tokens(&self) -> &'a [TokenTree] { - self.0 - } - pub fn split( self, - mut split_fn: impl FnMut(TtElement<'a, S>) -> bool, - ) -> impl Iterator> { + mut split_fn: impl FnMut(TtElement<'a>) -> bool, + ) -> impl Iterator> { let mut subtree_iter = self.iter(); let mut need_to_yield_even_if_empty = true; @@ -401,9 +249,29 @@ impl<'a, S: Copy> TokenTreesView<'a, S> { Some(result) }) } + + pub fn first_span(&self) -> Option { + Some(dispatch_ref! { + match self.repr => tt => tt.first()?.first_span().span(self.span_parts) + }) + } + + pub fn last_span(&self) -> Option { + Some(dispatch_ref! { + match self.repr => tt => tt.last()?.last_span().span(self.span_parts) + }) + } + + pub fn iter_flat_tokens(self) -> impl ExactSizeIterator + use<'a> { + (0..self.len()).map(move |idx| { + dispatch_ref! { + match self.repr => tt => tt[idx].to_api(self.span_parts) + } + }) + } } -impl fmt::Debug for TokenTreesView<'_, S> { +impl fmt::Debug for TokenTreesView<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut iter = self.iter(); while let Some(tt) = iter.next() { @@ -416,14 +284,14 @@ impl fmt::Debug for TokenTreesView<'_, S> { } } -impl fmt::Display for TokenTreesView<'_, S> { +impl fmt::Display for TokenTreesView<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { return token_trees_display(f, self.iter()); - fn subtree_display( - subtree: &Subtree, + fn subtree_display( + subtree: &Subtree, f: &mut fmt::Formatter<'_>, - iter: TtIter<'_, S>, + iter: TtIter<'_>, ) -> fmt::Result { let (l, r) = match subtree.delimiter.kind { DelimiterKind::Parenthesis => ("(", ")"), @@ -437,7 +305,7 @@ impl fmt::Display for TokenTreesView<'_, S> { Ok(()) } - fn token_trees_display(f: &mut fmt::Formatter<'_>, iter: TtIter<'_, S>) -> fmt::Result { + fn token_trees_display(f: &mut fmt::Formatter<'_>, iter: TtIter<'_>) -> fmt::Result { let mut needs_space = false; for child in iter { if needs_space { @@ -448,11 +316,11 @@ impl fmt::Display for TokenTreesView<'_, S> { match child { TtElement::Leaf(Leaf::Punct(p)) => { needs_space = p.spacing == Spacing::Alone; - fmt::Display::fmt(p, f)?; + fmt::Display::fmt(&p, f)?; } - TtElement::Leaf(leaf) => fmt::Display::fmt(leaf, f)?, + TtElement::Leaf(leaf) => fmt::Display::fmt(&leaf, f)?, TtElement::Subtree(subtree, subtree_iter) => { - subtree_display(subtree, f, subtree_iter)? + subtree_display(&subtree, f, subtree_iter)? } } } @@ -463,70 +331,80 @@ impl fmt::Display for TokenTreesView<'_, S> { #[derive(Clone, Copy)] // Invariant: always starts with `Subtree` that covers the entire thing. -pub struct SubtreeView<'a, S>(&'a [TokenTree]); +pub struct SubtreeView<'a>(TokenTreesView<'a>); -impl<'a, S: Copy> SubtreeView<'a, S> { - pub fn new(tts: &'a [TokenTree]) -> Self { - if cfg!(debug_assertions) { - let TokenTree::Subtree(subtree) = &tts[0] else { - panic!("first token tree must be a subtree in `SubtreeView`"); - }; - assert_eq!( - subtree.usize_len(), - tts.len() - 1, - "subtree must cover the entire `SubtreeView`" - ); +impl<'a> SubtreeView<'a> { + pub fn as_token_trees(self) -> TokenTreesView<'a> { + self.0 + } + + pub fn iter(&self) -> TtIter<'a> { + self.token_trees().iter() + } + + pub fn top_subtree(&self) -> Subtree { + dispatch_ref! { + match self.0.repr => tt => { + let crate::storage::TokenTree::Subtree { len, delim_kind, open_span, close_span } = + &tt[0] + else { + unreachable!("the first token tree is always the top subtree"); + }; + Subtree { + delimiter: Delimiter { + open: open_span.span(self.0.span_parts), + close: close_span.span(self.0.span_parts), + kind: *delim_kind, + }, + len: *len, + } + } } - Self(tts) } - pub fn as_token_trees(self) -> TokenTreesView<'a, S> { - TokenTreesView::new(self.0) - } - - pub fn iter(&self) -> TtIter<'a, S> { - TtIter::new(&self.0[1..]) - } - - pub fn top_subtree(&self) -> &'a Subtree { - let TokenTree::Subtree(subtree) = &self.0[0] else { - unreachable!("the first token tree is always the top subtree"); - }; - subtree - } - - pub fn strip_invisible(&self) -> TokenTreesView<'a, S> { + pub fn strip_invisible(&self) -> TokenTreesView<'a> { if self.top_subtree().delimiter.kind == DelimiterKind::Invisible { - TokenTreesView::new(&self.0[1..]) + self.token_trees() } else { - TokenTreesView::new(self.0) + self.0 } } - pub fn token_trees(&self) -> TokenTreesView<'a, S> { - TokenTreesView::new(&self.0[1..]) + pub fn token_trees(&self) -> TokenTreesView<'a> { + let repr = match self.0.repr { + TokenTreesReprRef::SpanStorage32(token_trees) => { + TokenTreesReprRef::SpanStorage32(&token_trees[1..]) + } + TokenTreesReprRef::SpanStorage64(token_trees) => { + TokenTreesReprRef::SpanStorage64(&token_trees[1..]) + } + TokenTreesReprRef::SpanStorage96(token_trees) => { + TokenTreesReprRef::SpanStorage96(&token_trees[1..]) + } + }; + TokenTreesView { repr, ..self.0 } } } -impl fmt::Debug for SubtreeView<'_, S> { +impl fmt::Debug for SubtreeView<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&TokenTreesView(self.0), f) + fmt::Debug::fmt(&self.0, f) } } -impl fmt::Display for SubtreeView<'_, S> { +impl fmt::Display for SubtreeView<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&TokenTreesView(self.0), f) + fmt::Display::fmt(&self.0, f) } } #[derive(Debug, Copy, Clone, PartialEq)] -pub struct DelimSpan { - pub open: S, - pub close: S, +pub struct DelimSpan { + pub open: Span, + pub close: Span, } -impl DelimSpan { +impl DelimSpan { pub fn from_single(sp: Span) -> Self { DelimSpan { open: sp, close: sp } } @@ -536,22 +414,22 @@ impl DelimSpan { } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct Delimiter { - pub open: S, - pub close: S, +pub struct Delimiter { + pub open: Span, + pub close: Span, pub kind: DelimiterKind, } -impl Delimiter { - pub const fn invisible_spanned(span: S) -> Self { +impl Delimiter { + pub const fn invisible_spanned(span: Span) -> Self { Delimiter { open: span, close: span, kind: DelimiterKind::Invisible } } - pub const fn invisible_delim_spanned(span: DelimSpan) -> Self { + pub const fn invisible_delim_spanned(span: DelimSpan) -> Self { Delimiter { open: span.open, close: span.close, kind: DelimiterKind::Invisible } } - pub fn delim_span(&self) -> DelimSpan { + pub fn delim_span(&self) -> DelimSpan { DelimSpan { open: self.open, close: self.close } } } @@ -565,18 +443,57 @@ pub enum DelimiterKind { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Literal { - // escaped - pub symbol: Symbol, - pub span: S, +pub struct Literal { + /// Escaped, text then suffix concatenated. + pub text_and_suffix: Symbol, + pub span: Span, pub kind: LitKind, - pub suffix: Option, + pub suffix_len: u8, } -pub fn token_to_literal(text: &str, span: S) -> Literal -where - S: Copy, -{ +impl Literal { + #[inline] + pub fn text_and_suffix(&self) -> (&str, &str) { + let text_and_suffix = self.text_and_suffix.as_str(); + text_and_suffix.split_at(text_and_suffix.len() - usize::from(self.suffix_len)) + } + + #[inline] + pub fn text(&self) -> &str { + self.text_and_suffix().0 + } + + #[inline] + pub fn suffix(&self) -> &str { + self.text_and_suffix().1 + } + + pub fn new(text: &str, span: Span, kind: LitKind, suffix: &str) -> Self { + const MAX_INLINE_CAPACITY: usize = 30; + let text_and_suffix = if suffix.is_empty() { + Symbol::intern(text) + } else if (text.len() + suffix.len()) < MAX_INLINE_CAPACITY { + let mut text_and_suffix = ArrayString::::new(); + text_and_suffix.push_str(text); + text_and_suffix.push_str(suffix); + Symbol::intern(&text_and_suffix) + } else { + let mut text_and_suffix = String::with_capacity(text.len() + suffix.len()); + text_and_suffix.push_str(text); + text_and_suffix.push_str(suffix); + Symbol::intern(&text_and_suffix) + }; + + Self { text_and_suffix, span, kind, suffix_len: suffix.len().try_into().unwrap() } + } + + #[inline] + pub fn new_no_suffix(text: &str, span: Span, kind: LitKind) -> Self { + Self { text_and_suffix: Symbol::intern(text), span, kind, suffix_len: 0 } + } +} + +pub fn token_to_literal(text: &str, span: Span) -> Literal { use rustc_lexer::LiteralKind; let token = rustc_lexer::tokenize(text, rustc_lexer::FrontmatterAllowed::No).next_tuple(); @@ -585,12 +502,7 @@ where .. },)) = token else { - return Literal { - span, - symbol: Symbol::intern(text), - kind: LitKind::Err(()), - suffix: None, - }; + return Literal::new_no_suffix(text, span, LitKind::Err(())); }; let (kind, start_offset, end_offset) = match kind { @@ -621,27 +533,22 @@ where let (lit, suffix) = text.split_at(suffix_start as usize); let lit = &lit[start_offset..lit.len() - end_offset]; let suffix = match suffix { - "" | "_" => None, + "" | "_" => "", // ill-suffixed literals _ if !matches!(kind, LitKind::Integer | LitKind::Float | LitKind::Err(_)) => { - return Literal { - span, - symbol: Symbol::intern(text), - kind: LitKind::Err(()), - suffix: None, - }; + return Literal::new_no_suffix(text, span, LitKind::Err(())); } - suffix => Some(Symbol::intern(suffix)), + suffix => suffix, }; - Literal { span, symbol: Symbol::intern(lit), kind, suffix } + Literal::new(lit, span, kind, suffix) } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Punct { +pub struct Punct { pub char: char, pub spacing: Spacing, - pub span: S, + pub span: Span, } /// Indicates whether a token can join with the following token to form a @@ -706,25 +613,25 @@ pub enum Spacing { /// Identifier or keyword. #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Ident { +pub struct Ident { pub sym: Symbol, - pub span: S, + pub span: Span, pub is_raw: IdentIsRaw, } -impl Ident { - pub fn new(text: &str, span: S) -> Self { +impl Ident { + pub fn new(text: &str, span: Span) -> Self { // let raw_stripped = IdentIsRaw::split_from_symbol(text.as_ref()); let (is_raw, text) = IdentIsRaw::split_from_symbol(text); Ident { sym: Symbol::intern(text), span, is_raw } } } -fn print_debug_subtree( +fn print_debug_subtree( f: &mut fmt::Formatter<'_>, - subtree: &Subtree, + subtree: &Subtree, level: usize, - iter: TtIter<'_, S>, + iter: TtIter<'_>, ) -> fmt::Result { let align = " ".repeat(level); @@ -748,25 +655,14 @@ fn print_debug_subtree( Ok(()) } -fn print_debug_token( - f: &mut fmt::Formatter<'_>, - level: usize, - tt: TtElement<'_, S>, -) -> fmt::Result { +fn print_debug_token(f: &mut fmt::Formatter<'_>, level: usize, tt: TtElement<'_>) -> fmt::Result { let align = " ".repeat(level); match tt { TtElement::Leaf(leaf) => match leaf { Leaf::Literal(lit) => { - write!( - f, - "{}LITERAL {:?} {}{} {:#?}", - align, - lit.kind, - lit.symbol, - lit.suffix.as_ref().map(|it| it.as_str()).unwrap_or(""), - lit.span - )?; + let (text, suffix) = lit.text_and_suffix(); + write!(f, "{}LITERAL {:?} {}{} {:#?}", align, lit.kind, text, suffix, lit.span)?; } Leaf::Punct(punct) => { write!( @@ -790,26 +686,26 @@ fn print_debug_token( } }, TtElement::Subtree(subtree, subtree_iter) => { - print_debug_subtree(f, subtree, level, subtree_iter)?; + print_debug_subtree(f, &subtree, level, subtree_iter)?; } } Ok(()) } -impl fmt::Debug for TopSubtree { +impl fmt::Debug for TopSubtree { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.view(), f) } } -impl fmt::Display for TopSubtree { +impl fmt::Display for TopSubtree { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.view(), f) } } -impl fmt::Display for Leaf { +impl fmt::Display for Leaf { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Leaf::Ident(it) => fmt::Display::fmt(it, f), @@ -819,155 +715,88 @@ impl fmt::Display for Leaf { } } -impl fmt::Display for Ident { +impl fmt::Display for Ident { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.is_raw.as_str(), f)?; fmt::Display::fmt(&self.sym, f) } } -impl fmt::Display for Literal { +impl fmt::Display for Literal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (text, suffix) = self.text_and_suffix(); match self.kind { - LitKind::Byte => write!(f, "b'{}'", self.symbol), - LitKind::Char => write!(f, "'{}'", self.symbol), - LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", self.symbol), - LitKind::Str => write!(f, "\"{}\"", self.symbol), - LitKind::ByteStr => write!(f, "b\"{}\"", self.symbol), - LitKind::CStr => write!(f, "c\"{}\"", self.symbol), + LitKind::Byte => write!(f, "b'{}'", text), + LitKind::Char => write!(f, "'{}'", text), + LitKind::Integer | LitKind::Float | LitKind::Err(_) => write!(f, "{}", text), + LitKind::Str => write!(f, "\"{}\"", text), + LitKind::ByteStr => write!(f, "b\"{}\"", text), + LitKind::CStr => write!(f, "c\"{}\"", text), LitKind::StrRaw(num_of_hashes) => { let num_of_hashes = num_of_hashes as usize; - write!( - f, - r#"r{0:# { let num_of_hashes = num_of_hashes as usize; - write!( - f, - r#"br{0:# { let num_of_hashes = num_of_hashes as usize; - write!( - f, - r#"cr{0:# fmt::Display for Punct { +impl fmt::Display for Punct { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.char, f) } } -impl Subtree { +impl Subtree { /// Count the number of tokens recursively pub fn count(&self) -> usize { self.usize_len() } } -impl TopSubtree { - /// A simple line string used for debugging - pub fn subtree_as_debug_string(&self, subtree_idx: usize) -> String { - fn debug_subtree( - output: &mut String, - subtree: &Subtree, - iter: &mut std::slice::Iter<'_, TokenTree>, - ) { - let delim = match subtree.delimiter.kind { - DelimiterKind::Brace => ("{", "}"), - DelimiterKind::Bracket => ("[", "]"), - DelimiterKind::Parenthesis => ("(", ")"), - DelimiterKind::Invisible => ("$", "$"), - }; +pub fn pretty(tkns: TokenTreesView<'_>) -> String { + return dispatch_ref! { + match tkns.repr => tt => pretty_impl(tt) + }; - output.push_str(delim.0); - let mut last = None; - let mut idx = 0; - while idx < subtree.len { - let child = iter.next().unwrap(); - debug_token_tree(output, child, last, iter); - last = Some(child); - idx += 1; - } + use crate::storage::TokenTree; - output.push_str(delim.1); - } - - fn debug_token_tree( - output: &mut String, - tt: &TokenTree, - last: Option<&TokenTree>, - iter: &mut std::slice::Iter<'_, TokenTree>, - ) { - match tt { - TokenTree::Leaf(it) => { - let s = match it { - Leaf::Literal(it) => it.symbol.to_string(), - Leaf::Punct(it) => it.char.to_string(), - Leaf::Ident(it) => format!("{}{}", it.is_raw.as_str(), it.sym), - }; - match (it, last) { - (Leaf::Ident(_), Some(&TokenTree::Leaf(Leaf::Ident(_)))) => { - output.push(' '); - output.push_str(&s); - } - (Leaf::Punct(_), Some(TokenTree::Leaf(Leaf::Punct(punct)))) => { - if punct.spacing == Spacing::Alone { - output.push(' '); - output.push_str(&s); - } else { - output.push_str(&s); - } - } - _ => output.push_str(&s), - } - } - TokenTree::Subtree(it) => debug_subtree(output, it, iter), - } - } - - let mut res = String::new(); - debug_token_tree( - &mut res, - &self.0[subtree_idx], - None, - &mut self.0[subtree_idx + 1..].iter(), - ); - res - } -} - -pub fn pretty(mut tkns: &[TokenTree]) -> String { - fn tokentree_to_text(tkn: &TokenTree, tkns: &mut &[TokenTree]) -> String { + fn tokentree_to_text(tkn: &TokenTree, tkns: &mut &[TokenTree]) -> String { match tkn { - TokenTree::Leaf(Leaf::Ident(ident)) => { - format!("{}{}", ident.is_raw.as_str(), ident.sym) + TokenTree::Ident { sym, is_raw, .. } => format!("{}{}", is_raw.as_str(), sym), + &TokenTree::Literal { ref text_and_suffix, kind, suffix_len, span: _ } => { + format!( + "{}", + Literal { + text_and_suffix: text_and_suffix.clone(), + span: Span { + range: TextRange::empty(TextSize::new(0)), + anchor: span::SpanAnchor { + file_id: span::EditionedFileId::from_raw(0), + ast_id: span::FIXUP_ERASED_FILE_AST_ID_MARKER + }, + ctx: span::SyntaxContext::root(span::Edition::Edition2015) + }, + kind, + suffix_len + } + ) } - TokenTree::Leaf(Leaf::Literal(literal)) => format!("{literal}"), - TokenTree::Leaf(Leaf::Punct(punct)) => format!("{}", punct.char), - TokenTree::Subtree(subtree) => { - let (subtree_content, rest) = tkns.split_at(subtree.usize_len()); - let content = pretty(subtree_content); + TokenTree::Punct { char, .. } => format!("{}", char), + TokenTree::Subtree { len, delim_kind, .. } => { + let (subtree_content, rest) = tkns.split_at(*len as usize); + let content = pretty_impl(subtree_content); *tkns = rest; - let (open, close) = match subtree.delimiter.kind { + let (open, close) = match *delim_kind { DelimiterKind::Brace => ("{", "}"), DelimiterKind::Bracket => ("[", "]"), DelimiterKind::Parenthesis => ("(", ")"), @@ -978,18 +807,104 @@ pub fn pretty(mut tkns: &[TokenTree]) -> String { } } - let mut last = String::new(); - let mut last_to_joint = true; + fn pretty_impl(mut tkns: &[TokenTree]) -> String { + let mut last = String::new(); + let mut last_to_joint = true; - while let Some((tkn, rest)) = tkns.split_first() { - tkns = rest; - last = [last, tokentree_to_text(tkn, &mut tkns)].join(if last_to_joint { "" } else { " " }); - last_to_joint = false; - if let TokenTree::Leaf(Leaf::Punct(punct)) = tkn - && punct.spacing == Spacing::Joint - { - last_to_joint = true; + while let Some((tkn, rest)) = tkns.split_first() { + tkns = rest; + last = [last, tokentree_to_text(tkn, &mut tkns)].join(if last_to_joint { + "" + } else { + " " + }); + last_to_joint = false; + if let TokenTree::Punct { spacing, .. } = tkn + && *spacing == Spacing::Joint + { + last_to_joint = true; + } + } + last + } +} + +#[derive(Debug)] +pub enum TransformTtAction<'a> { + Keep, + ReplaceWith(TokenTreesView<'a>), +} + +impl TransformTtAction<'_> { + #[inline] + pub fn remove() -> Self { + Self::ReplaceWith(TokenTreesView::empty()) + } +} + +/// This function takes a token tree, and calls `callback` with each token tree in it. +/// Then it does what the callback says: keeps the tt or replaces it with a (possibly empty) +/// tts view. +pub fn transform_tt<'b>( + tt: &mut TopSubtree, + mut callback: impl FnMut(TokenTree) -> TransformTtAction<'b>, +) { + let mut tt_vec = tt.as_token_trees().iter_flat_tokens().collect::>(); + + // We need to keep a stack of the currently open subtrees, because we need to update + // them if we change the number of items in them. + let mut subtrees_stack = Vec::new(); + let mut i = 0; + while i < tt_vec.len() { + 'pop_finished_subtrees: while let Some(&subtree_idx) = subtrees_stack.last() { + let TokenTree::Subtree(subtree) = &tt_vec[subtree_idx] else { + unreachable!("non-subtree on subtrees stack"); + }; + if i >= subtree_idx + 1 + subtree.usize_len() { + subtrees_stack.pop(); + } else { + break 'pop_finished_subtrees; + } + } + + let current = match &tt_vec[i] { + TokenTree::Leaf(leaf) => TokenTree::Leaf(match leaf { + Leaf::Literal(leaf) => Leaf::Literal(leaf.clone()), + Leaf::Punct(leaf) => Leaf::Punct(*leaf), + Leaf::Ident(leaf) => Leaf::Ident(leaf.clone()), + }), + TokenTree::Subtree(subtree) => TokenTree::Subtree(*subtree), + }; + let action = callback(current); + match action { + TransformTtAction::Keep => { + // This cannot be shared with the replaced case, because then we may push the same subtree + // twice, and will update it twice which will lead to errors. + if let TokenTree::Subtree(_) = &tt_vec[i] { + subtrees_stack.push(i); + } + + i += 1; + } + TransformTtAction::ReplaceWith(replacement) => { + let old_len = 1 + match &tt_vec[i] { + TokenTree::Leaf(_) => 0, + TokenTree::Subtree(subtree) => subtree.usize_len(), + }; + let len_diff = replacement.len() as i64 - old_len as i64; + tt_vec.splice(i..i + old_len, replacement.iter_flat_tokens()); + // Skip the newly inserted replacement, we don't want to visit it. + i += replacement.len(); + + for &subtree_idx in &subtrees_stack { + let TokenTree::Subtree(subtree) = &mut tt_vec[subtree_idx] else { + unreachable!("non-subtree on subtrees stack"); + }; + subtree.len = (i64::from(subtree.len) + len_diff).try_into().unwrap(); + } + } } } - last + + *tt = TopSubtree::from_serialized(tt_vec); } diff --git a/src/tools/rust-analyzer/crates/tt/src/storage.rs b/src/tools/rust-analyzer/crates/tt/src/storage.rs new file mode 100644 index 000000000000..50a1106175ab --- /dev/null +++ b/src/tools/rust-analyzer/crates/tt/src/storage.rs @@ -0,0 +1,992 @@ +//! Spans are memory heavy, and we have a lot of token trees. Storing them straight +//! will waste a lot of memory. So instead we implement a clever compression mechanism: +//! +//! A `TopSubtree` has a list of [`CompressedSpanPart`], which are the parts of a span +//! that tend to be shared between tokens - namely, without the range. The main list +//! of token trees is kept in one of three versions, where we use the smallest version +//! we can for this tree: +//! +//! 1. In the most common version a span is just a `u32`. The bits are divided as follows: +//! there are 4 bits that index into the [`CompressedSpanPart`] list. 20 bits +//! store the range start, and 8 bits store the range length. In experiments, +//! this accounts for 75%-85% of the spans. +//! 2. In the second version a span is 64 bits. 32 bits for the range start, 16 bits +//! for the range length, and 16 bits for the span parts index. This is used in +//! less than 2% of all `TopSubtree`s, but they account for 15%-25% of the spans: +//! those are mostly token tree munchers, that generate a lot of `SyntaxContext`s +//! (because they recurse a lot), which is why they can't fit in the first version, +//! and tend to generate a lot of code. +//! 3. The third version is practically unused; 65,535 bytes for a token and 65,535 +//! unique span parts is more than enough for everybody. However, someone may still +//! create a macro that requires more, therefore we have this version as a backup: +//! it uses 96 bits, 32 for each of the range start, length and span parts index. + +use std::fmt; + +use intern::Symbol; +use rustc_hash::FxBuildHasher; +use span::{Span, SpanAnchor, SyntaxContext, TextRange, TextSize}; + +use crate::{ + DelimSpan, DelimiterKind, IdentIsRaw, LitKind, Spacing, SubtreeView, TokenTreesReprRef, + TokenTreesView, TtIter, dispatch_ref, +}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct CompressedSpanPart { + pub(crate) anchor: SpanAnchor, + pub(crate) ctx: SyntaxContext, +} + +impl CompressedSpanPart { + #[inline] + fn from_span(span: &Span) -> Self { + Self { anchor: span.anchor, ctx: span.ctx } + } + + #[inline] + fn recombine(&self, range: TextRange) -> Span { + Span { range, anchor: self.anchor, ctx: self.ctx } + } +} + +pub(crate) trait SpanStorage: Copy { + fn can_hold(text_range: TextRange, span_parts_index: usize) -> bool; + + fn new(text_range: TextRange, span_parts_index: usize) -> Self; + + fn text_range(&self) -> TextRange; + + fn span_parts_index(&self) -> usize; + + #[inline] + fn span(&self, span_parts: &[CompressedSpanPart]) -> Span { + span_parts[self.span_parts_index()].recombine(self.text_range()) + } +} + +#[inline] +const fn n_bits_mask(n: u32) -> u32 { + (1 << n) - 1 +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct SpanStorage32(u32); + +impl SpanStorage32 { + const SPAN_PARTS_BIT: u32 = 4; + const LEN_BITS: u32 = 8; + const OFFSET_BITS: u32 = 20; +} + +const _: () = assert!( + (SpanStorage32::SPAN_PARTS_BIT + SpanStorage32::LEN_BITS + SpanStorage32::OFFSET_BITS) + == u32::BITS +); + +impl SpanStorage for SpanStorage32 { + #[inline] + fn can_hold(text_range: TextRange, span_parts_index: usize) -> bool { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + offset <= n_bits_mask(Self::OFFSET_BITS) + && len <= n_bits_mask(Self::LEN_BITS) + && span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT) + } + + #[inline] + fn new(text_range: TextRange, span_parts_index: usize) -> Self { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + debug_assert!(offset <= n_bits_mask(Self::OFFSET_BITS)); + debug_assert!(len <= n_bits_mask(Self::LEN_BITS)); + debug_assert!(span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT)); + + Self( + (offset << (Self::LEN_BITS + Self::SPAN_PARTS_BIT)) + | (len << Self::SPAN_PARTS_BIT) + | span_parts_index, + ) + } + + #[inline] + fn text_range(&self) -> TextRange { + let offset = TextSize::new(self.0 >> (Self::SPAN_PARTS_BIT + Self::LEN_BITS)); + let len = TextSize::new((self.0 >> Self::SPAN_PARTS_BIT) & n_bits_mask(Self::LEN_BITS)); + TextRange::at(offset, len) + } + + #[inline] + fn span_parts_index(&self) -> usize { + (self.0 & n_bits_mask(Self::SPAN_PARTS_BIT)) as usize + } +} + +impl fmt::Debug for SpanStorage32 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SpanStorage32") + .field("text_range", &self.text_range()) + .field("span_parts_index", &self.span_parts_index()) + .finish() + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct SpanStorage64 { + offset: u32, + len_and_parts: u32, +} + +impl SpanStorage64 { + const SPAN_PARTS_BIT: u32 = 16; + const LEN_BITS: u32 = 16; +} + +const _: () = assert!((SpanStorage64::SPAN_PARTS_BIT + SpanStorage64::LEN_BITS) == u32::BITS); + +impl SpanStorage for SpanStorage64 { + #[inline] + fn can_hold(text_range: TextRange, span_parts_index: usize) -> bool { + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + len <= n_bits_mask(Self::LEN_BITS) && span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT) + } + + #[inline] + fn new(text_range: TextRange, span_parts_index: usize) -> Self { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + debug_assert!(len <= n_bits_mask(Self::LEN_BITS)); + debug_assert!(span_parts_index <= n_bits_mask(Self::SPAN_PARTS_BIT)); + + Self { offset, len_and_parts: (len << Self::SPAN_PARTS_BIT) | span_parts_index } + } + + #[inline] + fn text_range(&self) -> TextRange { + let offset = TextSize::new(self.offset); + let len = TextSize::new(self.len_and_parts >> Self::SPAN_PARTS_BIT); + TextRange::at(offset, len) + } + + #[inline] + fn span_parts_index(&self) -> usize { + (self.len_and_parts & n_bits_mask(Self::SPAN_PARTS_BIT)) as usize + } +} + +impl fmt::Debug for SpanStorage64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SpanStorage64") + .field("text_range", &self.text_range()) + .field("span_parts_index", &self.span_parts_index()) + .finish() + } +} + +impl From for SpanStorage64 { + #[inline] + fn from(value: SpanStorage32) -> Self { + SpanStorage64::new(value.text_range(), value.span_parts_index()) + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct SpanStorage96 { + offset: u32, + len: u32, + parts: u32, +} + +impl SpanStorage for SpanStorage96 { + #[inline] + fn can_hold(_text_range: TextRange, _span_parts_index: usize) -> bool { + true + } + + #[inline] + fn new(text_range: TextRange, span_parts_index: usize) -> Self { + let offset = u32::from(text_range.start()); + let len = u32::from(text_range.len()); + let span_parts_index = span_parts_index as u32; + + Self { offset, len, parts: span_parts_index } + } + + #[inline] + fn text_range(&self) -> TextRange { + let offset = TextSize::new(self.offset); + let len = TextSize::new(self.len); + TextRange::at(offset, len) + } + + #[inline] + fn span_parts_index(&self) -> usize { + self.parts as usize + } +} + +impl fmt::Debug for SpanStorage96 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SpanStorage96") + .field("text_range", &self.text_range()) + .field("span_parts_index", &self.span_parts_index()) + .finish() + } +} + +impl From for SpanStorage96 { + #[inline] + fn from(value: SpanStorage32) -> Self { + SpanStorage96::new(value.text_range(), value.span_parts_index()) + } +} + +impl From for SpanStorage96 { + #[inline] + fn from(value: SpanStorage64) -> Self { + SpanStorage96::new(value.text_range(), value.span_parts_index()) + } +} + +// We don't use structs or enum nesting here to save padding. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) enum TokenTree { + Literal { text_and_suffix: Symbol, span: S, kind: LitKind, suffix_len: u8 }, + Punct { char: char, spacing: Spacing, span: S }, + Ident { sym: Symbol, span: S, is_raw: IdentIsRaw }, + Subtree { len: u32, delim_kind: DelimiterKind, open_span: S, close_span: S }, +} + +impl TokenTree { + #[inline] + pub(crate) fn first_span(&self) -> &S { + match self { + TokenTree::Literal { span, .. } => span, + TokenTree::Punct { span, .. } => span, + TokenTree::Ident { span, .. } => span, + TokenTree::Subtree { open_span, .. } => open_span, + } + } + + #[inline] + pub(crate) fn last_span(&self) -> &S { + match self { + TokenTree::Literal { span, .. } => span, + TokenTree::Punct { span, .. } => span, + TokenTree::Ident { span, .. } => span, + TokenTree::Subtree { close_span, .. } => close_span, + } + } + + #[inline] + pub(crate) fn to_api(&self, span_parts: &[CompressedSpanPart]) -> crate::TokenTree { + match self { + TokenTree::Literal { text_and_suffix, span, kind, suffix_len } => { + crate::TokenTree::Leaf(crate::Leaf::Literal(crate::Literal { + text_and_suffix: text_and_suffix.clone(), + span: span.span(span_parts), + kind: *kind, + suffix_len: *suffix_len, + })) + } + TokenTree::Punct { char, spacing, span } => { + crate::TokenTree::Leaf(crate::Leaf::Punct(crate::Punct { + char: *char, + spacing: *spacing, + span: span.span(span_parts), + })) + } + TokenTree::Ident { sym, span, is_raw } => { + crate::TokenTree::Leaf(crate::Leaf::Ident(crate::Ident { + sym: sym.clone(), + span: span.span(span_parts), + is_raw: *is_raw, + })) + } + TokenTree::Subtree { len, delim_kind, open_span, close_span } => { + crate::TokenTree::Subtree(crate::Subtree { + delimiter: crate::Delimiter { + open: open_span.span(span_parts), + close: close_span.span(span_parts), + kind: *delim_kind, + }, + len: *len, + }) + } + } + } + + #[inline] + fn convert>(self) -> TokenTree { + match self { + TokenTree::Literal { text_and_suffix, span, kind, suffix_len } => { + TokenTree::Literal { text_and_suffix, span: span.into(), kind, suffix_len } + } + TokenTree::Punct { char, spacing, span } => { + TokenTree::Punct { char, spacing, span: span.into() } + } + TokenTree::Ident { sym, span, is_raw } => { + TokenTree::Ident { sym, span: span.into(), is_raw } + } + TokenTree::Subtree { len, delim_kind, open_span, close_span } => TokenTree::Subtree { + len, + delim_kind, + open_span: open_span.into(), + close_span: close_span.into(), + }, + } + } +} + +// This is used a lot, make sure it doesn't grow unintentionally. +const _: () = { + assert!(size_of::>() == 16); + assert!(size_of::>() == 24); + assert!(size_of::>() == 32); +}; + +#[rust_analyzer::macro_style(braces)] +macro_rules! dispatch { + ( + match $scrutinee:expr => $tt:ident => $body:expr + ) => { + match $scrutinee { + TopSubtreeRepr::SpanStorage32($tt) => $body, + TopSubtreeRepr::SpanStorage64($tt) => $body, + TopSubtreeRepr::SpanStorage96($tt) => $body, + } + }; +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) enum TopSubtreeRepr { + SpanStorage32(Box<[TokenTree]>), + SpanStorage64(Box<[TokenTree]>), + SpanStorage96(Box<[TokenTree]>), +} + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct TopSubtree { + repr: TopSubtreeRepr, + span_parts: Box<[CompressedSpanPart]>, +} + +impl TopSubtree { + pub fn empty(span: DelimSpan) -> Self { + Self { + repr: TopSubtreeRepr::SpanStorage96(Box::new([TokenTree::Subtree { + len: 0, + delim_kind: DelimiterKind::Invisible, + open_span: SpanStorage96::new(span.open.range, 0), + close_span: SpanStorage96::new(span.close.range, 1), + }])), + span_parts: Box::new([ + CompressedSpanPart::from_span(&span.open), + CompressedSpanPart::from_span(&span.close), + ]), + } + } + + pub fn invisible_from_leaves( + delim_span: Span, + leaves: [crate::Leaf; N], + ) -> Self { + let mut builder = TopSubtreeBuilder::new(crate::Delimiter::invisible_spanned(delim_span)); + builder.extend(leaves); + builder.build() + } + + pub fn from_token_trees(delimiter: crate::Delimiter, token_trees: TokenTreesView<'_>) -> Self { + let mut builder = TopSubtreeBuilder::new(delimiter); + builder.extend_with_tt(token_trees); + builder.build() + } + + pub fn from_serialized(tt: Vec) -> Self { + let mut tt = tt.into_iter(); + let Some(crate::TokenTree::Subtree(top_subtree)) = tt.next() else { + panic!("first must always come the top subtree") + }; + let mut builder = TopSubtreeBuilder::new(top_subtree.delimiter); + for tt in tt { + builder.push_token_tree(tt); + } + builder.build() + } + + pub fn from_subtree(subtree: SubtreeView<'_>) -> Self { + let mut builder = TopSubtreeBuilder::new(subtree.top_subtree().delimiter); + builder.extend_with_tt(subtree.token_trees()); + builder.build() + } + + pub fn view(&self) -> SubtreeView<'_> { + let repr = match &self.repr { + TopSubtreeRepr::SpanStorage32(token_trees) => { + TokenTreesReprRef::SpanStorage32(token_trees) + } + TopSubtreeRepr::SpanStorage64(token_trees) => { + TokenTreesReprRef::SpanStorage64(token_trees) + } + TopSubtreeRepr::SpanStorage96(token_trees) => { + TokenTreesReprRef::SpanStorage96(token_trees) + } + }; + SubtreeView(TokenTreesView { repr, span_parts: &self.span_parts }) + } + + pub fn iter(&self) -> TtIter<'_> { + self.view().iter() + } + + pub fn top_subtree(&self) -> crate::Subtree { + self.view().top_subtree() + } + + pub fn set_top_subtree_delimiter_kind(&mut self, kind: DelimiterKind) { + dispatch! { + match &mut self.repr => tt => { + let TokenTree::Subtree { delim_kind, .. } = &mut tt[0] else { + unreachable!("the first token tree is always the top subtree"); + }; + *delim_kind = kind; + } + } + } + + fn ensure_can_hold(&mut self, range: TextRange) { + fn can_hold(_: &[TokenTree], range: TextRange) -> bool { + S::can_hold(range, 0) + } + let can_hold = dispatch! { + match &self.repr => tt => can_hold(tt, range) + }; + if can_hold { + return; + } + + // Otherwise, we do something very junky: recreate the entire tree. Hopefully this should be rare. + let mut builder = TopSubtreeBuilder::new(self.top_subtree().delimiter); + builder.extend_with_tt(self.token_trees()); + builder.ensure_can_hold(range, 0); + *self = builder.build(); + } + + pub fn set_top_subtree_delimiter_span(&mut self, span: DelimSpan) { + self.ensure_can_hold(span.open.range); + self.ensure_can_hold(span.close.range); + fn do_it(tt: &mut [TokenTree], span: DelimSpan) { + let TokenTree::Subtree { open_span, close_span, .. } = &mut tt[0] else { + unreachable!() + }; + *open_span = S::new(span.open.range, 0); + *close_span = S::new(span.close.range, 1); + } + dispatch! { + match &mut self.repr => tt => do_it(tt, span) + } + self.span_parts[0] = CompressedSpanPart::from_span(&span.open); + self.span_parts[1] = CompressedSpanPart::from_span(&span.close); + } + + /// Note: this cannot change spans. + pub fn set_token(&mut self, idx: usize, leaf: crate::Leaf) { + fn do_it( + tt: &mut [TokenTree], + idx: usize, + span_parts: &[CompressedSpanPart], + leaf: crate::Leaf, + ) { + assert!( + !matches!(tt[idx], TokenTree::Subtree { .. }), + "`TopSubtree::set_token()` must be called on a leaf" + ); + let existing_span_compressed = *tt[idx].first_span(); + let existing_span = existing_span_compressed.span(span_parts); + assert_eq!( + *leaf.span(), + existing_span, + "`TopSubtree::set_token()` cannot change spans" + ); + match leaf { + crate::Leaf::Literal(leaf) => { + tt[idx] = TokenTree::Literal { + text_and_suffix: leaf.text_and_suffix, + span: existing_span_compressed, + kind: leaf.kind, + suffix_len: leaf.suffix_len, + } + } + crate::Leaf::Punct(leaf) => { + tt[idx] = TokenTree::Punct { + char: leaf.char, + spacing: leaf.spacing, + span: existing_span_compressed, + } + } + crate::Leaf::Ident(leaf) => { + tt[idx] = TokenTree::Ident { + sym: leaf.sym, + span: existing_span_compressed, + is_raw: leaf.is_raw, + } + } + } + } + dispatch! { + match &mut self.repr => tt => do_it(tt, idx, &self.span_parts, leaf) + } + } + + pub fn token_trees(&self) -> TokenTreesView<'_> { + self.view().token_trees() + } + + pub fn as_token_trees(&self) -> TokenTreesView<'_> { + self.view().as_token_trees() + } + + pub fn change_every_ast_id(&mut self, mut callback: impl FnMut(&mut span::ErasedFileAstId)) { + for span_part in &mut self.span_parts { + callback(&mut span_part.anchor.ast_id); + } + } +} + +#[rust_analyzer::macro_style(braces)] +macro_rules! dispatch_builder { + ( + match $scrutinee:expr => $tt:ident => $body:expr + ) => { + match $scrutinee { + TopSubtreeBuilderRepr::SpanStorage32($tt) => $body, + TopSubtreeBuilderRepr::SpanStorage64($tt) => $body, + TopSubtreeBuilderRepr::SpanStorage96($tt) => $body, + } + }; +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +enum TopSubtreeBuilderRepr { + SpanStorage32(Vec>), + SpanStorage64(Vec>), + SpanStorage96(Vec>), +} + +type FxIndexSet = indexmap::IndexSet; + +/// In any tree, the first two subtree parts are reserved for the top subtree. +/// +/// We do it because `TopSubtree` exposes an API to modify the top subtree, therefore it's more convenient +/// this way, and it's unlikely to affect memory usage. +const RESERVED_SPAN_PARTS_LEN: usize = 2; + +#[derive(Debug, Clone)] +pub struct TopSubtreeBuilder { + unclosed_subtree_indices: Vec, + token_trees: TopSubtreeBuilderRepr, + span_parts: FxIndexSet, + last_closed_subtree: Option, + /// We need to keep those because they are not inside `span_parts`, see [`RESERVED_SPAN_PARTS_LEN`]. + top_subtree_spans: DelimSpan, +} + +impl TopSubtreeBuilder { + pub fn new(top_delimiter: crate::Delimiter) -> Self { + let mut result = Self { + unclosed_subtree_indices: Vec::new(), + token_trees: TopSubtreeBuilderRepr::SpanStorage32(Vec::new()), + span_parts: FxIndexSet::default(), + last_closed_subtree: None, + top_subtree_spans: top_delimiter.delim_span(), + }; + result.ensure_can_hold(top_delimiter.open.range, 0); + result.ensure_can_hold(top_delimiter.close.range, 1); + fn push_first(tt: &mut Vec>, top_delimiter: crate::Delimiter) { + tt.push(TokenTree::Subtree { + len: 0, + delim_kind: top_delimiter.kind, + open_span: S::new(top_delimiter.open.range, 0), + close_span: S::new(top_delimiter.close.range, 1), + }); + } + dispatch_builder! { + match &mut result.token_trees => tt => push_first(tt, top_delimiter) + } + result + } + + fn span_part_index(&mut self, part: CompressedSpanPart) -> usize { + self.span_parts.insert_full(part).0 + RESERVED_SPAN_PARTS_LEN + } + + fn switch_repr>(repr: &mut Vec>) -> Vec> { + let repr = std::mem::take(repr); + repr.into_iter().map(|tt| tt.convert()).collect() + } + + /// Ensures we have a representation that can hold these values. + fn ensure_can_hold(&mut self, text_range: TextRange, span_parts_index: usize) { + match &mut self.token_trees { + TopSubtreeBuilderRepr::SpanStorage32(token_trees) => { + if SpanStorage32::can_hold(text_range, span_parts_index) { + // Can hold. + } else if SpanStorage64::can_hold(text_range, span_parts_index) { + self.token_trees = + TopSubtreeBuilderRepr::SpanStorage64(Self::switch_repr(token_trees)); + } else { + self.token_trees = + TopSubtreeBuilderRepr::SpanStorage96(Self::switch_repr(token_trees)); + } + } + TopSubtreeBuilderRepr::SpanStorage64(token_trees) => { + if SpanStorage64::can_hold(text_range, span_parts_index) { + // Can hold. + } else { + self.token_trees = + TopSubtreeBuilderRepr::SpanStorage96(Self::switch_repr(token_trees)); + } + } + TopSubtreeBuilderRepr::SpanStorage96(_) => { + // Can hold anything. + } + } + } + + /// Not to be exposed, this assumes the subtree's children will be filled in immediately. + fn push_subtree(&mut self, subtree: crate::Subtree) { + let open_span_parts_index = + self.span_part_index(CompressedSpanPart::from_span(&subtree.delimiter.open)); + self.ensure_can_hold(subtree.delimiter.open.range, open_span_parts_index); + let close_span_parts_index = + self.span_part_index(CompressedSpanPart::from_span(&subtree.delimiter.close)); + self.ensure_can_hold(subtree.delimiter.close.range, close_span_parts_index); + fn do_it( + tt: &mut Vec>, + open_span_parts_index: usize, + close_span_parts_index: usize, + subtree: crate::Subtree, + ) { + let open_span = S::new(subtree.delimiter.open.range, open_span_parts_index); + let close_span = S::new(subtree.delimiter.close.range, close_span_parts_index); + tt.push(TokenTree::Subtree { + len: subtree.len, + delim_kind: subtree.delimiter.kind, + open_span, + close_span, + }); + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, open_span_parts_index, close_span_parts_index, subtree) + } + } + + pub fn open(&mut self, delimiter_kind: DelimiterKind, open_span: Span) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&open_span)); + self.ensure_can_hold(open_span.range, span_parts_index); + fn do_it( + token_trees: &mut Vec>, + delimiter_kind: DelimiterKind, + range: TextRange, + span_parts_index: usize, + ) -> usize { + let open_span = S::new(range, span_parts_index); + token_trees.push(TokenTree::Subtree { + len: 0, + delim_kind: delimiter_kind, + open_span, + close_span: open_span, // Will be overwritten on close. + }); + token_trees.len() - 1 + } + let subtree_idx = dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, delimiter_kind, open_span.range, span_parts_index) + }; + self.unclosed_subtree_indices.push(subtree_idx); + } + + pub fn close(&mut self, close_span: Span) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&close_span)); + let range = close_span.range; + self.ensure_can_hold(range, span_parts_index); + + let last_unclosed_index = self + .unclosed_subtree_indices + .pop() + .expect("attempt to close a `tt::Subtree` when none is open"); + fn do_it( + token_trees: &mut [TokenTree], + last_unclosed_index: usize, + range: TextRange, + span_parts_index: usize, + ) { + let token_trees_len = token_trees.len(); + let TokenTree::Subtree { len, delim_kind: _, open_span: _, close_span } = + &mut token_trees[last_unclosed_index] + else { + unreachable!("unclosed token tree is always a subtree"); + }; + *len = (token_trees_len - last_unclosed_index - 1) as u32; + *close_span = S::new(range, span_parts_index); + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, last_unclosed_index, range, span_parts_index) + } + self.last_closed_subtree = Some(last_unclosed_index); + } + + /// You cannot call this consecutively, it will only work once after close. + pub fn remove_last_subtree_if_invisible(&mut self) { + let Some(last_subtree_idx) = self.last_closed_subtree else { return }; + fn do_it(tt: &mut Vec>, last_subtree_idx: usize) { + if let TokenTree::Subtree { delim_kind: DelimiterKind::Invisible, .. } = + tt[last_subtree_idx] + { + tt.remove(last_subtree_idx); + } + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, last_subtree_idx) + } + self.last_closed_subtree = None; + } + + fn push_literal(&mut self, leaf: crate::Literal) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&leaf.span)); + let range = leaf.span.range; + self.ensure_can_hold(range, span_parts_index); + fn do_it( + tt: &mut Vec>, + range: TextRange, + span_parts_index: usize, + leaf: crate::Literal, + ) { + tt.push(TokenTree::Literal { + text_and_suffix: leaf.text_and_suffix, + span: S::new(range, span_parts_index), + kind: leaf.kind, + suffix_len: leaf.suffix_len, + }) + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, range, span_parts_index, leaf) + } + } + + fn push_punct(&mut self, leaf: crate::Punct) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&leaf.span)); + let range = leaf.span.range; + self.ensure_can_hold(range, span_parts_index); + fn do_it( + tt: &mut Vec>, + range: TextRange, + span_parts_index: usize, + leaf: crate::Punct, + ) { + tt.push(TokenTree::Punct { + char: leaf.char, + spacing: leaf.spacing, + span: S::new(range, span_parts_index), + }) + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, range, span_parts_index, leaf) + } + } + + fn push_ident(&mut self, leaf: crate::Ident) { + let span_parts_index = self.span_part_index(CompressedSpanPart::from_span(&leaf.span)); + let range = leaf.span.range; + self.ensure_can_hold(range, span_parts_index); + fn do_it( + tt: &mut Vec>, + range: TextRange, + span_parts_index: usize, + leaf: crate::Ident, + ) { + tt.push(TokenTree::Ident { + sym: leaf.sym, + span: S::new(range, span_parts_index), + is_raw: leaf.is_raw, + }) + } + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt, range, span_parts_index, leaf) + } + } + + pub fn push(&mut self, leaf: crate::Leaf) { + match leaf { + crate::Leaf::Literal(leaf) => self.push_literal(leaf), + crate::Leaf::Punct(leaf) => self.push_punct(leaf), + crate::Leaf::Ident(leaf) => self.push_ident(leaf), + } + } + + fn push_token_tree(&mut self, tt: crate::TokenTree) { + match tt { + crate::TokenTree::Leaf(leaf) => self.push(leaf), + crate::TokenTree::Subtree(subtree) => self.push_subtree(subtree), + } + } + + pub fn extend(&mut self, leaves: impl IntoIterator) { + leaves.into_iter().for_each(|leaf| self.push(leaf)); + } + + pub fn extend_with_tt(&mut self, tt: TokenTreesView<'_>) { + fn do_it( + this: &mut TopSubtreeBuilder, + tt: &[TokenTree], + span_parts: &[CompressedSpanPart], + ) { + for tt in tt { + this.push_token_tree(tt.to_api(span_parts)); + } + } + dispatch_ref! { + match tt.repr => tt_repr => do_it(self, tt_repr, tt.span_parts) + } + } + + /// Like [`Self::extend_with_tt()`], but makes sure the new tokens will never be + /// joint with whatever comes after them. + pub fn extend_with_tt_alone(&mut self, tt: TokenTreesView<'_>) { + self.extend_with_tt(tt); + fn do_it(tt: &mut [TokenTree]) { + if let Some(TokenTree::Punct { spacing, .. }) = tt.last_mut() { + *spacing = Spacing::Alone; + } + } + if !tt.is_empty() { + dispatch_builder! { + match &mut self.token_trees => tt => do_it(tt) + } + } + } + + pub fn expected_delimiters(&self) -> impl Iterator { + self.unclosed_subtree_indices.iter().rev().map(|&subtree_idx| { + dispatch_builder! { + match &self.token_trees => tt => { + let TokenTree::Subtree { delim_kind, .. } = tt[subtree_idx] else { + unreachable!("unclosed token tree is always a subtree") + }; + delim_kind + } + } + }) + } + + /// Builds, and remove the top subtree if it has only one subtree child. + pub fn build_skip_top_subtree(mut self) -> TopSubtree { + fn remove_first_if_needed( + tt: &mut Vec>, + top_delim_span: &mut DelimSpan, + span_parts: &FxIndexSet, + ) { + let tt_len = tt.len(); + let Some(TokenTree::Subtree { len, open_span, close_span, .. }) = tt.get_mut(1) else { + return; + }; + if (*len as usize) != (tt_len - 2) { + // Subtree does not cover the whole tree (minus 2; itself, and the top span). + return; + } + + // Now we need to adjust the spans, because we assume that the first two spans are always reserved. + let top_open_span = span_parts + .get_index(open_span.span_parts_index() - RESERVED_SPAN_PARTS_LEN) + .unwrap() + .recombine(open_span.text_range()); + let top_close_span = span_parts + .get_index(close_span.span_parts_index() - RESERVED_SPAN_PARTS_LEN) + .unwrap() + .recombine(close_span.text_range()); + *top_delim_span = DelimSpan { open: top_open_span, close: top_close_span }; + // Can't remove the top spans from the map, as maybe they're used by other things as well. + // Now we need to reencode the spans, because their parts index changed: + *open_span = S::new(open_span.text_range(), 0); + *close_span = S::new(close_span.text_range(), 1); + + tt.remove(0); + } + dispatch_builder! { + match &mut self.token_trees => tt => remove_first_if_needed(tt, &mut self.top_subtree_spans, &self.span_parts) + } + self.build() + } + + pub fn build(mut self) -> TopSubtree { + assert!( + self.unclosed_subtree_indices.is_empty(), + "attempt to build an unbalanced `TopSubtreeBuilder`" + ); + fn finish_top_len(tt: &mut [TokenTree]) { + let total_len = tt.len() as u32; + let TokenTree::Subtree { len, .. } = &mut tt[0] else { + unreachable!("first token tree is always a subtree"); + }; + *len = total_len - 1; + } + dispatch_builder! { + match &mut self.token_trees => tt => finish_top_len(tt) + } + + let span_parts = [ + CompressedSpanPart::from_span(&self.top_subtree_spans.open), + CompressedSpanPart::from_span(&self.top_subtree_spans.close), + ] + .into_iter() + .chain(self.span_parts.iter().copied()) + .collect(); + + let repr = match self.token_trees { + TopSubtreeBuilderRepr::SpanStorage32(tt) => { + TopSubtreeRepr::SpanStorage32(tt.into_boxed_slice()) + } + TopSubtreeBuilderRepr::SpanStorage64(tt) => { + TopSubtreeRepr::SpanStorage64(tt.into_boxed_slice()) + } + TopSubtreeBuilderRepr::SpanStorage96(tt) => { + TopSubtreeRepr::SpanStorage96(tt.into_boxed_slice()) + } + }; + + TopSubtree { repr, span_parts } + } + + pub fn restore_point(&self) -> SubtreeBuilderRestorePoint { + let token_trees_len = dispatch_builder! { + match &self.token_trees => tt => tt.len() + }; + SubtreeBuilderRestorePoint { + unclosed_subtree_indices_len: self.unclosed_subtree_indices.len(), + token_trees_len, + last_closed_subtree: self.last_closed_subtree, + } + } + + pub fn restore(&mut self, restore_point: SubtreeBuilderRestorePoint) { + self.unclosed_subtree_indices.truncate(restore_point.unclosed_subtree_indices_len); + dispatch_builder! { + match &mut self.token_trees => tt => tt.truncate(restore_point.token_trees_len) + } + self.last_closed_subtree = restore_point.last_closed_subtree; + } +} + +#[derive(Clone, Copy)] +pub struct SubtreeBuilderRestorePoint { + unclosed_subtree_indices_len: usize, + token_trees_len: usize, + last_closed_subtree: Option, +} diff --git a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml index bd6c8331e66c..ce7ea53b5373 100644 --- a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml +++ b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml @@ -16,7 +16,7 @@ doctest = false tracing.workspace = true walkdir = "2.5.0" crossbeam-channel.workspace = true -notify = "8.0.0" +notify = "8.2.0" rayon = "1.10.0" stdx.workspace = true diff --git a/src/tools/rust-analyzer/docs/book/README.md b/src/tools/rust-analyzer/docs/book/README.md index 0a3161f3af38..cd4d8783a4d2 100644 --- a/src/tools/rust-analyzer/docs/book/README.md +++ b/src/tools/rust-analyzer/docs/book/README.md @@ -6,7 +6,7 @@ The rust analyzer manual uses [mdbook](https://rust-lang.github.io/mdBook/). To run the documentation site locally: -```shell +```bash cargo install mdbook cargo xtask codegen cd docs/book diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index fe1ea57c9b18..8460c2c7d0cf 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -323,10 +323,18 @@ each of them, with the working directory being the workspace root (i.e., the folder containing the `Cargo.toml`). This can be overwritten by changing `#rust-analyzer.check.invocationStrategy#`. -If `$saved_file` is part of the command, rust-analyzer will pass -the absolute path of the saved file to the provided command. This is -intended to be used with non-Cargo build systems. -Note that `$saved_file` is experimental and may be removed in the future. +It supports two interpolation syntaxes, both mainly intended to be used with +[non-Cargo build systems](./non_cargo_based_projects.md): + +- If `{saved_file}` is part of the command, rust-analyzer will pass + the absolute path of the saved file to the provided command. + (A previous version, `$saved_file`, also works.) +- If `{label}` is part of the command, rust-analyzer will pass the + Cargo package ID, which can be used with `cargo check -p`, or a build label from + `rust-project.json`. If `{label}` is included, rust-analyzer behaves much like + [`"rust-analyzer.check.workspace": false`](#check.workspace). + + An example command would be: @@ -1070,6 +1078,13 @@ Default: `true` Show function parameter name inlay hints at the call site. +## rust-analyzer.inlayHints.parameterHints.missingArguments.enable {#inlayHints.parameterHints.missingArguments.enable} + +Default: `false` + +Show parameter name inlay hints for missing arguments at the call site. + + ## rust-analyzer.inlayHints.rangeExclusiveHints.enable {#inlayHints.rangeExclusiveHints.enable} Default: `false` @@ -1118,6 +1133,13 @@ Default: `false` Hide inlay parameter type hints for closures. +## rust-analyzer.inlayHints.typeHints.hideInferredTypes {#inlayHints.typeHints.hideInferredTypes} + +Default: `false` + +Hide inlay type hints for inferred types. + + ## rust-analyzer.inlayHints.typeHints.hideNamedConstructor {#inlayHints.typeHints.hideNamedConstructor} Default: `false` @@ -1296,6 +1318,16 @@ These proc-macros will be ignored when trying to expand them. This config takes a map of crate names with the exported proc-macro names to ignore as values. +## rust-analyzer.procMacro.processes {#procMacro.processes} + +Default: `1` + +Number of proc-macro server processes to spawn. + +Controls how many independent `proc-macro-srv` processes rust-analyzer +runs in parallel to handle macro expansion. + + ## rust-analyzer.procMacro.server {#procMacro.server} Default: `null` @@ -1327,6 +1359,32 @@ Default: `false` Exclude tests from find-all-references and call-hierarchy. +## rust-analyzer.rename.showConflicts {#rename.showConflicts} + +Default: `true` + +Whether to warn when a rename will cause conflicts (change the meaning of the code). + + +## rust-analyzer.runnables.bench.command {#runnables.bench.command} + +Default: `"bench"` + +Subcommand used for bench runnables instead of `bench`. + + +## rust-analyzer.runnables.bench.overrideCommand {#runnables.bench.overrideCommand} + +Default: `null` + +Override the command used for bench runnables. +The first element of the array should be the program to execute (for example, `cargo`). + +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +replace the package name, target option (such as `--bin` or `--example`), the target name and +the test name (name of test function or test mod path). + + ## rust-analyzer.runnables.command {#runnables.command} Default: `null` @@ -1334,6 +1392,18 @@ Default: `null` Command to be executed instead of 'cargo' for runnables. +## rust-analyzer.runnables.doctest.overrideCommand {#runnables.doctest.overrideCommand} + +Default: `null` + +Override the command used for bench runnables. +The first element of the array should be the program to execute (for example, `cargo`). + +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +replace the package name, target option (such as `--bin` or `--example`), the target name and +the test name (name of test function or test mod path). + + ## rust-analyzer.runnables.extraArgs {#runnables.extraArgs} Default: `[]` @@ -1360,6 +1430,25 @@ they will end up being interpreted as options to [`rustc`’s built-in test harness (“libtestâ€)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). +## rust-analyzer.runnables.test.command {#runnables.test.command} + +Default: `"test"` + +Subcommand used for test runnables instead of `test`. + + +## rust-analyzer.runnables.test.overrideCommand {#runnables.test.overrideCommand} + +Default: `null` + +Override the command used for test runnables. +The first element of the array should be the program to execute (for example, `cargo`). + +Use the placeholders `${package}`, `${target_arg}`, `${target}`, `${test_name}` to dynamically +replace the package name, target option (such as `--bin` or `--example`), the target name and +the test name (name of test function or test mod path). + + ## rust-analyzer.rustc.source {#rustc.source} Default: `null` @@ -1540,33 +1629,83 @@ though Cargo might be the eventual consumer. Default: `null` -Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. +Configure a command that rust-analyzer can invoke to +obtain configuration. -[`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`. -`progress_label` is used for the title in progress indicators, whereas `files_to_watch` -is used to determine which build system-specific files should be watched in order to -reload rust-analyzer. +This is an alternative to manually generating +`rust-project.json`: it enables rust-analyzer to generate +rust-project.json on the fly, and regenerate it when +switching or modifying projects. + +This is an object with three fields: + +* `command`: the shell command to invoke + +* `filesToWatch`: which build system-specific files should +be watched to trigger regenerating the configuration + +* `progressLabel`: the name of the command, used in +progress indicators in the IDE + +Here's an example of a valid configuration: -Below is an example of a valid configuration: ```json "rust-analyzer.workspace.discoverConfig": { "command": [ "rust-project", - "develop-json" + "develop-json", + "{arg}" ], - "progressLabel": "rust-analyzer", + "progressLabel": "buck2/rust-project", "filesToWatch": [ "BUCK" ] } ``` -## On `DiscoverWorkspaceConfig::command` +## Argument Substitutions + +If `command` includes the argument `{arg}`, that argument will be substituted +with the JSON-serialized form of the following enum: + +```norun +#[derive(PartialEq, Clone, Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum DiscoverArgument { + Path(AbsPathBuf), + Buildfile(AbsPathBuf), +} +``` + +rust-analyzer will use the path invocation to find and +generate a `rust-project.json` and therefore a +workspace. Example: + + +```norun +rust-project develop-json '{ "path": "myproject/src/main.rs" }' +``` + +rust-analyzer will use build file invocations to update an +existing workspace. Example: + +Or with a build file and the configuration above: + +```norun +rust-project develop-json '{ "buildfile": "myproject/BUCK" }' +``` + +As a reference for implementors, buck2's `rust-project` +will likely be useful: +. + +## Discover Command Output **Warning**: This format is provisional and subject to change. -[`DiscoverWorkspaceConfig::command`] *must* return a JSON object corresponding to -`DiscoverProjectData::Finished`: +The discover command should output JSON objects, one per +line (JSONL format). These objects should correspond to +this Rust data type: ```norun #[derive(Debug, Clone, Deserialize, Serialize)] @@ -1579,7 +1718,14 @@ enum DiscoverProjectData { } ``` -As JSON, `DiscoverProjectData::Finished` is: +For example, a progress event: + +```json +{"kind":"progress","message":"generating rust-project.json"} +``` + +A finished event can look like this (expanded and +commented for readability): ```json { @@ -1587,7 +1733,7 @@ As JSON, `DiscoverProjectData::Finished` is: "kind": "finished", // the file used by a non-Cargo build system to define // a package or target. - "buildfile": "rust-analyzer/BUILD", + "buildfile": "rust-analyzer/BUCK", // the contents of a rust-project.json, elided for brevity "project": { "sysroot": "foo", @@ -1596,41 +1742,9 @@ As JSON, `DiscoverProjectData::Finished` is: } ``` -It is encouraged, but not required, to use the other variants on `DiscoverProjectData` -to provide a more polished end-user experience. - -`DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, which will be -substituted with the JSON-serialized form of the following enum: - -```norun -#[derive(PartialEq, Clone, Debug, Serialize)] -#[serde(rename_all = "camelCase")] -pub enum DiscoverArgument { - Path(AbsPathBuf), - Buildfile(AbsPathBuf), -} -``` - -The JSON representation of `DiscoverArgument::Path` is: - -```json -{ - "path": "src/main.rs" -} -``` - -Similarly, the JSON representation of `DiscoverArgument::Buildfile` is: - -```json -{ - "buildfile": "BUILD" -} -``` - -`DiscoverArgument::Path` is used to find and generate a `rust-project.json`, and -therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to to update an -existing workspace. As a reference for implementors, buck2's `rust-project` will likely -be useful: . +Only the finished event is required, but the other +variants are encouraged to give users more feedback about +progress or errors. ## rust-analyzer.workspace.symbol.search.excludeImports {#workspace.symbol.search.excludeImports} diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/README.md b/src/tools/rust-analyzer/docs/book/src/contributing/README.md index c95a1dba6249..bb2b6081ad95 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/README.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/README.md @@ -4,7 +4,7 @@ rust-analyzer is an ordinary Rust project, which is organized as a Cargo workspa So, just ```bash -$ cargo test +cargo test ``` should be enough to get you started! @@ -203,14 +203,14 @@ It is enabled by `RA_COUNT=1`. To measure time for from-scratch analysis, use something like this: ```bash -$ cargo run --release -p rust-analyzer -- analysis-stats ../chalk/ +cargo run --release -p rust-analyzer -- analysis-stats ../chalk/ ``` For measuring time of incremental analysis, use either of these: ```bash -$ cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --highlight ../chalk/chalk-engine/src/logic.rs -$ cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --complete ../chalk/chalk-engine/src/logic.rs:94:0 +cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --highlight ../chalk/chalk-engine/src/logic.rs +cargo run --release -p rust-analyzer -- analysis-bench ../chalk/ --complete ../chalk/chalk-engine/src/logic.rs:94:0 ``` Look for `fn benchmark_xxx` tests for a quick way to reproduce performance problems. @@ -283,7 +283,8 @@ repository. We use the [rustc-josh-sync](https://github.com/rust-lang/josh-sync) repositories. You can find documentation of the tool [here](https://github.com/rust-lang/josh-sync). You can install the synchronization tool using the following commands: -``` + +```bash cargo install --locked --git https://github.com/rust-lang/josh-sync ``` diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md b/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md index 67653ebd7437..50f60bcdccc1 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/architecture.md @@ -10,7 +10,7 @@ See also these implementation-related blog posts: * * -* +* * * diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/debugging.md b/src/tools/rust-analyzer/docs/book/src/contributing/debugging.md index fcda664f5ed3..ace9be025ab4 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/debugging.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/debugging.md @@ -68,7 +68,7 @@ while d == 4 { // set a breakpoint here and change the value However for this to work, you will need to enable debug_assertions in your build -```rust +```bash RUSTFLAGS='--cfg debug_assertions' cargo build --release ``` diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md b/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md index 5922f0b551d6..5d21c37806dd 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md @@ -1,5 +1,5 @@ replaced | LL | do_something(Type); - | ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type` + | ------------ ^^^^ the trait `dependency::Trait` is not implemented for `dep_2_reexport::Type` | | | required by a bound introduced by this call | @@ -17,7 +17,7 @@ LL | pub trait Trait { LL | pub trait Trait { | --------------- this is the found trait = help: you can use `cargo tree` to explore your dependency tree -help: the trait `Trait` is implemented for `dependency::Type` +help: the trait `dependency::Trait` is implemented for `dependency::Type` --> replaced | LL | impl Trait for Type { @@ -64,11 +64,11 @@ LL | pub trait Trait { | --------------- this is the trait that was imported = help: you can use `cargo tree` to explore your dependency tree -error[E0277]: the trait bound `OtherType: Trait` is not satisfied +error[E0277]: the trait bound `OtherType: dependency::Trait` is not satisfied --> replaced | LL | do_something(OtherType); - | ------------ ^^^^^^^^^ the trait `Trait` is not implemented for `OtherType` + | ------------ ^^^^^^^^^ the trait `dependency::Trait` is not implemented for `OtherType` | | | required by a bound introduced by this call | @@ -83,7 +83,7 @@ LL | pub trait Trait { LL | pub trait Trait { | --------------- this is the found trait = help: you can use `cargo tree` to explore your dependency tree -help: the trait `Trait` is implemented for `dependency::Type` +help: the trait `dependency::Trait` is implemented for `dependency::Type` --> replaced | LL | impl Trait for Type { @@ -144,7 +144,51 @@ note: function defined here LL | pub fn do_something_trait(_: Box) {} | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error[E0277]: `?` couldn't convert the error to `dependency::Error` + --> replaced + | +LL | fn main() -> Result<(), Error> { + | ----------------- expected `dependency::Error` because of this +... +LL | Err(Error2)?; + | -----------^ the trait `From` is not implemented for `dependency::Error` + | | + | this can't be annotated with `?` because it has type `Result<_, Error2>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait +help: the trait `From` is not implemented for `dependency::Error` + but trait `From<()>` is implemented for it + --> replaced + | +LL | impl From<()> for Error { + | ^^^^^^^^^^^^^^^^^^^^^^^ + = help: for that trait implementation, expected `()`, found `Error2` + = note: there are multiple different versions of crate `dependency` in the dependency graph + = help: you can use `cargo tree` to explore your dependency tree + +error[E0277]: `?` couldn't convert the error to `dependency::OtherError` + --> replaced + | +LL | fn foo() -> Result<(), OtherError> { + | ---------------------- expected `dependency::OtherError` because of this +LL | Err(Error2)?; + | -----------^ the trait `From` is not implemented for `dependency::OtherError` + | | + | this can't be annotated with `?` because it has type `Result<_, Error2>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait +help: the following other types implement trait `From` + --> replaced + | +LL | impl From<()> for OtherError { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From<()>` +... +LL | impl From for OtherError { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From` + = note: there are multiple different versions of crate `dependency` in the dependency graph + = help: you can use `cargo tree` to explore your dependency tree + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0277, E0308, E0599. For more information about an error, try `rustc --explain E0277`. \ No newline at end of file diff --git a/tests/run-make/doctests-junit/doctest-2021.xml b/tests/run-make/doctests-junit/doctest-2021.xml new file mode 100644 index 000000000000..5facfb80ce62 --- /dev/null +++ b/tests/run-make/doctests-junit/doctest-2021.xml @@ -0,0 +1 @@ + diff --git a/tests/run-make/doctests-junit/doctest-2024.xml b/tests/run-make/doctests-junit/doctest-2024.xml new file mode 100644 index 000000000000..4f94f01c3e32 --- /dev/null +++ b/tests/run-make/doctests-junit/doctest-2024.xml @@ -0,0 +1,3 @@ + + + diff --git a/tests/run-make/doctests-junit/doctest.rs b/tests/run-make/doctests-junit/doctest.rs new file mode 100644 index 000000000000..1873d63a49c6 --- /dev/null +++ b/tests/run-make/doctests-junit/doctest.rs @@ -0,0 +1,14 @@ +/// ``` +/// assert_eq!(doctest::add(2, 2), 4); +/// ``` +/// +/// ```should_panic +/// assert_eq!(doctest::add(2, 2), 5); +/// ``` +/// +/// ```compile_fail +/// assert_eq!(doctest::add(2, 2), "banana"); +/// ``` +pub fn add(a: i32, b: i32) -> i32 { + a + b +} diff --git a/tests/run-make/doctests-junit/rmake.rs b/tests/run-make/doctests-junit/rmake.rs new file mode 100644 index 000000000000..e3198502bb17 --- /dev/null +++ b/tests/run-make/doctests-junit/rmake.rs @@ -0,0 +1,45 @@ +// Check rustdoc's test JUnit (XML) output against snapshots. + +//@ ignore-cross-compile (running doctests) +//@ ignore-stage1 (rustdoc depends on a fix in libtest) +//@ needs-unwind (test file contains `should_panic` test) + +use std::path::Path; + +use run_make_support::{cwd, diff, python_command, rustc, rustdoc}; + +fn main() { + let rlib = cwd().join("libdoctest.rlib"); + rustc().input("doctest.rs").crate_type("rlib").output(&rlib).run(); + + run_doctests(&rlib, "2021", "doctest-2021.xml"); + run_doctests(&rlib, "2024", "doctest-2024.xml"); +} + +#[track_caller] +fn run_doctests(rlib: &Path, edition: &str, expected_xml: &str) { + let rustdoc_out = rustdoc() + .input("doctest.rs") + .args(&[ + "--test", + "--test-args=-Zunstable-options", + "--test-args=--test-threads=1", + "--test-args=--format=junit", + ]) + .edition(edition) + .env("RUST_BACKTRACE", "0") + .extern_("doctest", rlib.display().to_string()) + .run(); + let rustdoc_stdout = &rustdoc_out.stdout_utf8(); + + // FIXME: merged output of compile_fail tests is broken + if edition != "2024" { + python_command().arg("validate_junit.py").stdin_buf(rustdoc_stdout).run(); + } + + diff() + .expected_file(expected_xml) + .actual_text("output", rustdoc_stdout) + .normalize(r#"\b(time|total_time|compilation_time)="[0-9.]+""#, r#"$1="$$TIME""#) + .run(); +} diff --git a/tests/run-make/doctests-junit/validate_junit.py b/tests/run-make/doctests-junit/validate_junit.py new file mode 100755 index 000000000000..a9cb0a059563 --- /dev/null +++ b/tests/run-make/doctests-junit/validate_junit.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python + +# Trivial Python script that reads lines from stdin, and checks that each line +# is a well-formed XML document. +# +# This takes advantage of the fact that Python has a built-in XML parser, +# whereas doing the same check in Rust would require us to pull in an XML +# crate just for this relatively-minor test. +# +# If you're trying to remove Python scripts from the test suite, think twice +# before removing this one. You could do so, but it's probably not worth it. + +import sys +import xml.etree.ElementTree as ET + +# Read the entire output and try to decode it as XML. +junit = sys.stdin.read() +try: + ET.fromstring(junit) +except ET.ParseError: + print("Invalid xml: %r" % junit) + raise diff --git a/tests/run-make/dump-ice-to-disk/rmake.rs b/tests/run-make/dump-ice-to-disk/rmake.rs index 09a34cdeb5e7..319cbc6e0ca8 100644 --- a/tests/run-make/dump-ice-to-disk/rmake.rs +++ b/tests/run-make/dump-ice-to-disk/rmake.rs @@ -18,13 +18,16 @@ //! # Test history //! //! The previous rmake.rs iteration of this test was flaky for unknown reason on -//! `i686-pc-windows-gnu` *specifically*, so assertion failures in this test was made extremely -//! verbose to help diagnose why the ICE messages was different. It appears that backtraces on -//! `i686-pc-windows-gnu` specifically are quite unpredictable in how many backtrace frames are -//! involved. +//! `i686-pc-windows-gnu`, so assertion failures in this test was made extremely verbose to help +//! diagnose why the ICE messages was different. It appears that backtraces on `i686-pc-windows-gnu` +//! specifically are quite unpredictable in how many backtrace frames are involved. +//! +//! Disabled on `i686-pc-windows-msvc` as well, because sometimes the middle portion of the ICE +//! backtrace becomes ``. //@ ignore-cross-compile (exercising ICE dump on host) //@ ignore-i686-pc-windows-gnu (unwind mechanism produces unpredictable backtraces) +//@ ignore-i686-pc-windows-msvc (sometimes partial backtrace becomes ``) use std::cell::OnceCell; use std::path::{Path, PathBuf}; diff --git a/tests/rustdoc/extern/auxiliary/extern-links.rs b/tests/run-make/duplicate-dependency-no-disambiguate/foo-v1.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/extern-links.rs rename to tests/run-make/duplicate-dependency-no-disambiguate/foo-v1.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs b/tests/run-make/duplicate-dependency-no-disambiguate/foo-v2.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/src-links-external.rs rename to tests/run-make/duplicate-dependency-no-disambiguate/foo-v2.rs diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/main.rs b/tests/run-make/duplicate-dependency-no-disambiguate/main.rs new file mode 100644 index 000000000000..eae6b8b4527d --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/main.rs @@ -0,0 +1,10 @@ +#![feature(custom_inner_attributes)] +#![rustfmt::skip] // use_foo must be referenced before foo + +// Load foo-v2 through use-foo +use use_foo as _; + +// Make sure we don't disambiguate this as foo-v2. +use foo as _; + +fn main() {} diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/main.stderr b/tests/run-make/duplicate-dependency-no-disambiguate/main.stderr new file mode 100644 index 000000000000..23caa2caaef6 --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/main.stderr @@ -0,0 +1,12 @@ +error[E0464]: multiple candidates for `rlib` dependency `foo` found + --> main.rs:8:5 + | +LL | use foo as _; + | ^^^ + | + = note: candidate #1: /build-root/test/run-make/duplicate-dependency-no-disambiguate/rmake_out/libfoo-v1.rlib + = note: candidate #2: /build-root/test/run-make/duplicate-dependency-no-disambiguate/rmake_out/libfoo-v2.rlib + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0464`. diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/rmake.rs b/tests/run-make/duplicate-dependency-no-disambiguate/rmake.rs new file mode 100644 index 000000000000..7dd6f3840dfa --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/rmake.rs @@ -0,0 +1,54 @@ +//@ needs-target-std + +use run_make_support::{Rustc, cwd, diff, regex, rust_lib_name, rustc}; + +fn rustc_with_common_args() -> Rustc { + let mut rustc = rustc(); + rustc.remap_path_prefix(cwd(), "$DIR"); + rustc.edition("2018"); // Don't require `extern crate` + rustc +} + +fn main() { + rustc_with_common_args() + .input("foo-v1.rs") + .crate_type("rlib") + .crate_name("foo") + .extra_filename("-v1") + .metadata("-v1") + .run(); + + rustc_with_common_args() + .input("foo-v2.rs") + .crate_type("rlib") + .crate_name("foo") + .extra_filename("-v2") + .metadata("-v2") + .run(); + + rustc_with_common_args() + .input("use-foo.rs") + .crate_type("rlib") + .extern_("foo", rust_lib_name("foo-v2")) + .run(); + + let stderr = rustc_with_common_args() + .input("main.rs") + .extern_("foo", rust_lib_name("foo-v1")) + .extern_("foo", rust_lib_name("foo-v2")) + .extern_("use_foo", rust_lib_name("use_foo")) + .library_search_path(cwd()) + .ui_testing() + .run_fail() + .stderr_utf8(); + + diff() + .expected_file("main.stderr") + .normalize( + regex::escape(run_make_support::build_root().canonicalize().unwrap().to_str().unwrap()), + "/build-root", + ) + .normalize(r"\\", "/") + .actual_text("(rustc)", &stderr) + .run(); +} diff --git a/tests/run-make/duplicate-dependency-no-disambiguate/use-foo.rs b/tests/run-make/duplicate-dependency-no-disambiguate/use-foo.rs new file mode 100644 index 000000000000..15c1d27f1b95 --- /dev/null +++ b/tests/run-make/duplicate-dependency-no-disambiguate/use-foo.rs @@ -0,0 +1 @@ +use foo as _; diff --git a/tests/run-make/duplicate-dependency/rmake.rs b/tests/run-make/duplicate-dependency/rmake.rs index 762d97e4311f..274db933feb8 100644 --- a/tests/run-make/duplicate-dependency/rmake.rs +++ b/tests/run-make/duplicate-dependency/rmake.rs @@ -11,7 +11,7 @@ fn rustc_with_common_args() -> Rustc { fn main() { rustc_with_common_args() - .input("foo-v1.rs") + .input(cwd().join("foo-v1.rs")) .crate_type("rlib") .crate_name("foo") .extra_filename("-v1") @@ -19,7 +19,7 @@ fn main() { .run(); rustc_with_common_args() - .input("foo-v2.rs") + .input(cwd().join("foo-v2.rs")) .crate_type("rlib") .crate_name("foo") .extra_filename("-v2") @@ -27,7 +27,7 @@ fn main() { .run(); rustc_with_common_args() - .input("re-export-foo.rs") + .input(cwd().join("re-export-foo.rs")) .crate_type("rlib") .extern_("foo", rust_lib_name("foo-v2")) .run(); diff --git a/tests/run-make/env-dep-info/macro_def.rs b/tests/run-make/env-dep-info/macro_def.rs index e328eae48326..17d27ebfba3c 100644 --- a/tests/run-make/env-dep-info/macro_def.rs +++ b/tests/run-make/env-dep-info/macro_def.rs @@ -6,7 +6,7 @@ use proc_macro::*; #[proc_macro] pub fn access_env_vars(_: TokenStream) -> TokenStream { - let _ = tracked_env::var("EXISTING_PROC_MACRO_ENV"); - let _ = tracked_env::var("NONEXISTENT_PROC_MACEO_ENV"); + let _ = tracked::env_var("EXISTING_PROC_MACRO_ENV"); + let _ = tracked::env_var("NONEXISTENT_PROC_MACEO_ENV"); TokenStream::new() } diff --git a/tests/run-make/frontmatter-no-trailing-newline/rmake.rs b/tests/run-make/frontmatter-no-trailing-newline/rmake.rs new file mode 100644 index 000000000000..204062201ad3 --- /dev/null +++ b/tests/run-make/frontmatter-no-trailing-newline/rmake.rs @@ -0,0 +1,19 @@ +// Regression test for issue #151882 +// See https://github.com/rust-lang/rust/issues/151882 + +//@ only-nightly +//@ needs-target-std + +use run_make_support::{rfs, rustc}; + +fn main() { + rfs::write("test.rs", b"----"); + + // Ensure rustc does not ICE when parsing a file with frontmatter syntax + // that has no trailing newline + rustc() + .input("test.rs") + .run_fail() + .assert_stderr_contains("invalid infostring for frontmatter") + .assert_stderr_not_contains("unexpectedly panicked"); +} diff --git a/tests/run-make/invalid-tmpdir-env-var/rmake.rs b/tests/run-make/invalid-tmpdir-env-var/rmake.rs deleted file mode 100644 index c5b9dca33a94..000000000000 --- a/tests/run-make/invalid-tmpdir-env-var/rmake.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ needs-target-std -// -// When the TMP (on Windows) or TMPDIR (on Unix) variable is set to an invalid -// or non-existing directory, this used to cause an internal compiler error (ICE). After the -// addition of proper error handling in #28430, this test checks that the expected message is -// printed. -// See https://github.com/rust-lang/rust/issues/14698 - -use run_make_support::{is_windows, rustc}; - -// NOTE: This is not a UI test despite its simplicity, as the error message contains a path -// with some variability that is difficult to normalize - -fn main() { - let mut rustc = rustc(); - if is_windows() { - rustc.env("TMP", "fake"); - } else { - rustc.env("TMPDIR", "fake"); - } - rustc.input("foo.rs").run_fail().assert_stderr_contains("couldn't create a temp dir"); -} diff --git a/tests/run-make/invalid-tmpdir-env-var/foo.rs b/tests/run-make/invalid-tmpdir-no-ice/foo.rs similarity index 100% rename from tests/run-make/invalid-tmpdir-env-var/foo.rs rename to tests/run-make/invalid-tmpdir-no-ice/foo.rs diff --git a/tests/run-make/invalid-tmpdir-no-ice/rmake.rs b/tests/run-make/invalid-tmpdir-no-ice/rmake.rs new file mode 100644 index 000000000000..a62592757879 --- /dev/null +++ b/tests/run-make/invalid-tmpdir-no-ice/rmake.rs @@ -0,0 +1,22 @@ +//@ needs-target-std +// +// When the TMP (on Windows) or TMPDIR (on Unix) variable is set to an invalid +// or non-existing directory, this used to cause an internal compiler error (ICE). +// See https://github.com/rust-lang/rust/issues/14698 + +use run_make_support::{is_windows, rustc}; + +// NOTE: This is not a UI test despite its simplicity, as the error message contains a path +// with some variability that is difficult to normalize + +fn main() { + let mut rustc = rustc(); + if is_windows() { + rustc.env("TMP", "fake"); + } else { + rustc.env("TMPDIR", "fake"); + } + let result = rustc.input("foo.rs").run_unchecked(); + // Ensure that rustc doesn't ICE by checking the exit code isn't 101. + assert_ne!(result.status().code(), Some(101)); +} diff --git a/tests/run-make/issue-149402-suggest-unresolve/foo.rs b/tests/run-make/issue-149402-suggest-unresolve/foo.rs new file mode 100644 index 000000000000..8456990829b4 --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/foo.rs @@ -0,0 +1,6 @@ +fn foo() { + let x = Vec::new(); + x.push(Complete::Item { name: "hello" }); +} + +fn main() {} diff --git a/tests/run-make/issue-149402-suggest-unresolve/nightly.err b/tests/run-make/issue-149402-suggest-unresolve/nightly.err new file mode 100644 index 000000000000..8e122e3da388 --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/nightly.err @@ -0,0 +1,18 @@ +error[E0433]: cannot find type `Complete` in this scope + --> foo.rs:3:12 + | +3 | x.push(Complete::Item { name: "hello" }); + | ^^^^^^^^ use of undeclared type `Complete` + | +help: there is an enum variant `core::ops::CoroutineState::Complete` and 1 other; try using the variant's enum + | +3 - x.push(Complete::Item { name: "hello" }); +3 + x.push(core::ops::CoroutineState::Item { name: "hello" }); + | +3 - x.push(Complete::Item { name: "hello" }); +3 + x.push(std::ops::CoroutineState::Item { name: "hello" }); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/run-make/issue-149402-suggest-unresolve/output.diff b/tests/run-make/issue-149402-suggest-unresolve/output.diff new file mode 100644 index 000000000000..196c0326a714 --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/output.diff @@ -0,0 +1,16 @@ +@@ -3,6 +3,15 @@ + | + 3 | x.push(Complete::Item { name: "hello" }); + | ^^^^^^^^ use of undeclared type `Complete` ++ | ++help: there is an enum variant `core::ops::CoroutineState::Complete` and 1 other; try using the variant's enum ++ | ++3 - x.push(Complete::Item { name: "hello" }); ++3 + x.push(core::ops::CoroutineState::Item { name: "hello" }); ++ | ++3 - x.push(Complete::Item { name: "hello" }); ++3 + x.push(std::ops::CoroutineState::Item { name: "hello" }); ++ | + + error: aborting due to 1 previous error + diff --git a/tests/run-make/issue-149402-suggest-unresolve/rmake.rs b/tests/run-make/issue-149402-suggest-unresolve/rmake.rs new file mode 100644 index 000000000000..5bca0c0206cb --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/rmake.rs @@ -0,0 +1,29 @@ +//! Check that unstable name-resolution suggestions are omitted on stable. +//! +//! Regression test for . +//! +//@ only-nightly +//@ needs-target-std + +use run_make_support::{diff, rustc, similar}; + +fn main() { + let stable_like = rustc() + .env("RUSTC_BOOTSTRAP", "-1") + .edition("2024") + .input("foo.rs") + .run_fail() + .stderr_utf8(); + + assert!(!stable_like.contains("CoroutineState::Complete")); + diff().expected_file("stable.err").actual_text("stable_like", &stable_like).run(); + + let nightly = rustc().edition("2024").input("foo.rs").run_fail().stderr_utf8(); + + assert!(nightly.contains("CoroutineState::Complete")); + diff().expected_file("nightly.err").actual_text("nightly", &nightly).run(); + + let stderr_diff = + similar::TextDiff::from_lines(&stable_like, &nightly).unified_diff().to_string(); + diff().expected_file("output.diff").actual_text("diff", stderr_diff).run(); +} diff --git a/tests/run-make/issue-149402-suggest-unresolve/stable.err b/tests/run-make/issue-149402-suggest-unresolve/stable.err new file mode 100644 index 000000000000..f980d4548f64 --- /dev/null +++ b/tests/run-make/issue-149402-suggest-unresolve/stable.err @@ -0,0 +1,9 @@ +error[E0433]: cannot find type `Complete` in this scope + --> foo.rs:3:12 + | +3 | x.push(Complete::Item { name: "hello" }); + | ^^^^^^^^ use of undeclared type `Complete` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/run-make/libstd-no-protected/rmake.rs b/tests/run-make/libstd-no-protected/rmake.rs index 4091406d46e2..75a1dcc4a7d0 100644 --- a/tests/run-make/libstd-no-protected/rmake.rs +++ b/tests/run-make/libstd-no-protected/rmake.rs @@ -15,10 +15,8 @@ type SymbolTable<'data> = run_make_support::object::read::elf::SymbolTable<'data fn main() { // Find libstd-...rlib - let sysroot = rustc().print("sysroot").run().stdout_utf8(); - let sysroot = sysroot.trim(); - let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib"); - let mut libs = shallow_find_files(&target_sysroot, |path| { + let sysroot_libs_dir = rustc().print("target-libdir").target(target()).run().stdout_utf8(); + let mut libs = shallow_find_files(sysroot_libs_dir.trim(), |path| { has_prefix(path, "libstd-") && has_suffix(path, ".rlib") }); assert_eq!(libs.len(), 1); diff --git a/tests/run-make/libtest-junit/validate_junit.py b/tests/run-make/libtest-junit/validate_junit.py index f92473751b03..a9cb0a059563 100755 --- a/tests/run-make/libtest-junit/validate_junit.py +++ b/tests/run-make/libtest-junit/validate_junit.py @@ -13,10 +13,10 @@ import sys import xml.etree.ElementTree as ET -# Try to decode line in order to ensure it is a valid XML document -for line in sys.stdin: - try: - ET.fromstring(line) - except ET.ParseError: - print("Invalid xml: %r" % line) - raise +# Read the entire output and try to decode it as XML. +junit = sys.stdin.read() +try: + ET.fromstring(junit) +except ET.ParseError: + print("Invalid xml: %r" % junit) + raise diff --git a/tests/run-make/mir-opt-bisect-limit/main.rs b/tests/run-make/mir-opt-bisect-limit/main.rs new file mode 100644 index 000000000000..674275b10fcd --- /dev/null +++ b/tests/run-make/mir-opt-bisect-limit/main.rs @@ -0,0 +1,11 @@ +#![crate_type = "lib"] +#![no_std] + +#[inline(never)] +pub fn callee(x: u64) -> u64 { + x.wrapping_mul(3).wrapping_add(7) +} + +pub fn caller(a: u64, b: u64) -> u64 { + callee(a) + callee(b) +} diff --git a/tests/run-make/mir-opt-bisect-limit/rmake.rs b/tests/run-make/mir-opt-bisect-limit/rmake.rs new file mode 100644 index 000000000000..fa77cb7d8c35 --- /dev/null +++ b/tests/run-make/mir-opt-bisect-limit/rmake.rs @@ -0,0 +1,119 @@ +use std::path::Path; + +use run_make_support::{CompletedProcess, rfs, rustc}; + +struct Case { + name: &'static str, + flags: &'static [&'static str], + expect_inline_dump: bool, + expect_running: ExpectedCount, + expect_not_running: ExpectedCount, +} + +enum ExpectedCount { + Exactly(usize), + AtLeastOne, + Zero, +} + +fn main() { + let cases = [ + Case { + name: "limit0", + flags: &["-Zmir-opt-bisect-limit=0"], + expect_inline_dump: false, + expect_running: ExpectedCount::Exactly(0), + expect_not_running: ExpectedCount::AtLeastOne, + }, + Case { + name: "limit1", + flags: &["-Zmir-opt-bisect-limit=1"], + expect_inline_dump: false, + expect_running: ExpectedCount::Exactly(1), + expect_not_running: ExpectedCount::AtLeastOne, + }, + Case { + name: "huge_limit", + flags: &["-Zmir-opt-bisect-limit=1000000000"], + expect_inline_dump: true, + expect_running: ExpectedCount::AtLeastOne, + expect_not_running: ExpectedCount::Zero, + }, + Case { + name: "limit0_with_force_enable_inline", + flags: &["-Zmir-opt-bisect-limit=0", "-Zmir-enable-passes=+Inline"], + expect_inline_dump: false, + expect_running: ExpectedCount::Exactly(0), + expect_not_running: ExpectedCount::AtLeastOne, + }, + ]; + + for case in cases { + let (inline_dumped, running_count, not_running_count, output) = + compile_case(case.name, case.flags); + + assert_eq!( + inline_dumped, case.expect_inline_dump, + "{}: unexpected Inline dump presence", + case.name + ); + + assert_expected_count( + running_count, + case.expect_running, + &format!("{}: running count", case.name), + ); + assert_expected_count( + not_running_count, + case.expect_not_running, + &format!("{}: NOT running count", case.name), + ); + } +} + +fn compile_case(dump_dir: &str, extra_flags: &[&str]) -> (bool, usize, usize, CompletedProcess) { + if Path::new(dump_dir).exists() { + rfs::remove_dir_all(dump_dir); + } + rfs::create_dir_all(dump_dir); + + let mut cmd = rustc(); + cmd.input("main.rs") + .arg("--emit=mir") + .arg("-Zmir-opt-level=2") + .arg("-Copt-level=2") + .arg("-Zthreads=1") + .arg("-Zdump-mir=Inline") + .arg(format!("-Zdump-mir-dir={dump_dir}")); + + for &flag in extra_flags { + cmd.arg(flag); + } + + let output = cmd.run(); + let (running_count, not_running_count) = bisect_line_counts(&output); + (has_inline_dump_file(dump_dir), running_count, not_running_count, output) +} + +fn assert_expected_count(actual: usize, expected: ExpectedCount, context: &str) { + match expected { + ExpectedCount::Exactly(n) => assert_eq!(actual, n, "{context}"), + ExpectedCount::AtLeastOne => assert!(actual > 0, "{context}"), + ExpectedCount::Zero => assert_eq!(actual, 0, "{context}"), + } +} + +fn has_inline_dump_file(dir: &str) -> bool { + rfs::read_dir(dir) + .flatten() + .any(|entry| entry.file_name().to_string_lossy().contains(".Inline.")) +} + +fn bisect_line_counts(output: &CompletedProcess) -> (usize, usize) { + let stderr = output.stderr_utf8(); + let running_count = + stderr.lines().filter(|line| line.starts_with("BISECT: running pass (")).count(); + let not_running_count = + stderr.lines().filter(|line| line.starts_with("BISECT: NOT running pass (")).count(); + (running_count, not_running_count) +} diff --git a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr index 7196a1a6fed7..d680ae1aca1d 100644 --- a/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr +++ b/tests/run-make/missing-unstable-trait-bound/missing-bound.stderr @@ -1,9 +1,10 @@ -error[E0277]: the trait bound `T: Step` is not satisfied +error[E0277]: `std::ops::Range` is not an iterator --> missing-bound.rs:2:14 | 2 | for _ in t {} - | ^ the trait `Step` is not implemented for `T` + | ^ `Range` is not an iterator | + = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait = note: required for `std::ops::Range` to implement `Iterator` = note: required for `std::ops::Range` to implement `IntoIterator` diff --git a/tests/run-make/no-builtins-linker-plugin-lto/main.rs b/tests/run-make/no-builtins-linker-plugin-lto/main.rs new file mode 100644 index 000000000000..f96605be8949 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/main.rs @@ -0,0 +1,3 @@ +fn main() { + no_builtins::foo(); +} diff --git a/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs b/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs new file mode 100644 index 000000000000..a56c1d6b4133 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/no_builtins.rs @@ -0,0 +1,4 @@ +#![no_builtins] + +#[inline(never)] +pub fn foo() {} diff --git a/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs b/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs new file mode 100644 index 000000000000..713308567737 --- /dev/null +++ b/tests/run-make/no-builtins-linker-plugin-lto/rmake.rs @@ -0,0 +1,53 @@ +//@ only-x86_64-unknown-linux-gnu + +use std::fs; +use std::path::Path; + +use run_make_support::{cwd, has_extension, llvm_ar, llvm_bcanalyzer, rust_lib_name, rustc}; + +// A regression test for #146133. + +fn main() { + // Compile a `#![no_builtins]` rlib crate with `-Clinker-plugin-lto`. + // It is acceptable to generate bitcode for rlib, so there is no need to check something. + rustc().input("no_builtins.rs").crate_type("rlib").linker_plugin_lto("on").run(); + + // Checks that rustc's LTO doesn't emit any bitcode to the linker. + let stdout = rustc() + .input("main.rs") + .extern_("no_builtins", rust_lib_name("no_builtins")) + .lto("thin") + .print("link-args") + .arg("-Csave-temps") + .arg("-Clinker-features=-lld") + .run() + .stdout_utf8(); + for object in stdout + .split_whitespace() + .map(|s| s.trim_matches('"')) + .filter(|path| has_extension(path, "rlib") || has_extension(path, "o")) + { + let object_path = if !fs::exists(object).unwrap() { + cwd().join(object) + } else { + Path::new(object).to_path_buf() + }; + if has_extension(object, "rlib") { + let ar_stdout = llvm_ar().arg("t").arg(&object_path).run().stdout_utf8(); + llvm_ar().extract().arg(&object_path).run(); + for object in ar_stdout.split_whitespace().filter(|o| has_extension(o, "o")) { + let object_path = cwd().join(object); + not_bitcode(&object_path); + } + } else { + not_bitcode(&object_path); + } + } +} + +fn not_bitcode(object: &Path) { + llvm_bcanalyzer() + .input(object) + .run_fail() + .assert_stderr_contains("llvm-bcanalyzer: Invalid record at top-level"); +} diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs index f6f7f7cece6e..e102d2904a80 100644 --- a/tests/run-make/print-check-cfg/rmake.rs +++ b/tests/run-make/print-check-cfg/rmake.rs @@ -14,51 +14,55 @@ struct CheckCfg { enum Contains { Some { contains: &'static [&'static str], doesnt_contain: &'static [&'static str] }, - Only(&'static str), + Nothing, } fn main() { - check(CheckCfg { args: &[], contains: Contains::Only("any()=any()") }); + check(CheckCfg { args: &[], contains: Contains::Nothing }); check(CheckCfg { args: &["--check-cfg=cfg()"], contains: Contains::Some { - contains: &["unix", "miri"], - doesnt_contain: &["any()", "any()=any()"], + contains: &["cfg(unix, values(none()))", "cfg(miri, values(none()))"], + doesnt_contain: &["cfg(any())"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(any())"], contains: Contains::Some { - contains: &["any()", "unix", r#"target_feature="crt-static""#], + contains: &["cfg(any())", "cfg(unix, values(none()))"], doesnt_contain: &["any()=any()"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(feature)"], contains: Contains::Some { - contains: &["unix", "miri", "feature"], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + contains: &[ + "cfg(unix, values(none()))", + "cfg(miri, values(none()))", + "cfg(feature, values(none()))", + ], + doesnt_contain: &["cfg(any())", "cfg(feature)"], }, }); check(CheckCfg { args: &[r#"--check-cfg=cfg(feature, values(none(), "", "test", "lol"))"#], contains: Contains::Some { - contains: &["feature", "feature=\"\"", "feature=\"test\"", "feature=\"lol\""], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + contains: &[r#"cfg(feature, values("", "lol", "test", none()))"#], + doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(feature, values())"], contains: Contains::Some { - contains: &["feature="], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature"], + contains: &["cfg(feature, values())"], + doesnt_contain: &["cfg(any())", "cfg(feature, values(none()))", "cfg(feature)"], }, }); check(CheckCfg { args: &["--check-cfg=cfg(feature, values())", "--check-cfg=cfg(feature, values(none()))"], contains: Contains::Some { - contains: &["feature"], - doesnt_contain: &["any()", "any()=any()", "feature=none()", "feature="], + contains: &["cfg(feature, values(none()))"], + doesnt_contain: &["cfg(any())", "cfg(feature, values())"], }, }); check(CheckCfg { @@ -67,8 +71,8 @@ fn main() { r#"--check-cfg=cfg(feature, values("tmp"))"#, ], contains: Contains::Some { - contains: &["unix", "miri", "feature=any()"], - doesnt_contain: &["any()", "any()=any()", "feature", "feature=", "feature=\"tmp\""], + contains: &["cfg(feature, values(any()))"], + doesnt_contain: &["cfg(any())", r#"cfg(feature, values("tmp"))"#], }, }); check(CheckCfg { @@ -78,8 +82,12 @@ fn main() { r#"--check-cfg=cfg(feature, values("tmp"))"#, ], contains: Contains::Some { - contains: &["has_foo", "has_bar", "feature=\"tmp\""], - doesnt_contain: &["any()", "any()=any()", "feature"], + contains: &[ + "cfg(has_foo, values(none()))", + "cfg(has_bar, values(none()))", + r#"cfg(feature, values("tmp"))"#, + ], + doesnt_contain: &["cfg(any())", "cfg(feature)"], }, }); } @@ -94,16 +102,15 @@ fn check(CheckCfg { args, contains }: CheckCfg) { for l in stdout.lines() { assert!(l == l.trim()); - if let Some((left, right)) = l.split_once('=') { - if right != "any()" && right != "" { - assert!(right.starts_with("\"")); - assert!(right.ends_with("\"")); - } - assert!(!left.contains("\"")); - } else { - assert!(!l.contains("\"")); - } - assert!(found.insert(l.to_string()), "{}", &l); + assert!(l.starts_with("cfg("), "{l}"); + assert!(l.ends_with(")"), "{l}"); + assert_eq!( + l.chars().filter(|c| *c == '(').count(), + l.chars().filter(|c| *c == ')').count(), + "{l}" + ); + assert!(l.chars().filter(|c| *c == '"').count() % 2 == 0, "{l}"); + assert!(found.insert(l.to_string()), "{l}"); } match contains { @@ -131,9 +138,8 @@ fn check(CheckCfg { args, contains }: CheckCfg) { ); } } - Contains::Only(only) => { - assert!(found.contains(&only.to_string()), "{:?} != {:?}", &only, &found); - assert!(found.len() == 1, "len: {}, instead of 1", found.len()); + Contains::Nothing => { + assert!(found.len() == 0, "len: {}, instead of 0", found.len()); } } } diff --git a/tests/run-make/remap-path-prefix-consts/location-caller.rs b/tests/run-make/remap-path-prefix-consts/location-caller.rs new file mode 100644 index 000000000000..70685e032e4a --- /dev/null +++ b/tests/run-make/remap-path-prefix-consts/location-caller.rs @@ -0,0 +1,21 @@ +// Reproducer from https://github.com/rust-lang/rust/issues/148328#issuecomment-3473688412 +#[inline(always)] +pub const fn the_path() -> &'static str { + std::panic::Location::caller().file() +} + +#[inline(never)] +pub fn the_path2() -> &'static str { + const { std::panic::Location::caller().file() } +} + +// Reproducer from https://github.com/rust-lang/rust/issues/148328#issuecomment-3473761194 +pub const fn the_path_len() -> usize { + std::panic::Location::caller().file().len() +} + +pub type Array = [u8; the_path_len()]; + +pub fn the_zeroed_path_len_array() -> Array { + [0; _] +} diff --git a/tests/run-make/remap-path-prefix-consts/rmake.rs b/tests/run-make/remap-path-prefix-consts/rmake.rs new file mode 100644 index 000000000000..07b5e2f97414 --- /dev/null +++ b/tests/run-make/remap-path-prefix-consts/rmake.rs @@ -0,0 +1,115 @@ +//@ ignore-cross-compile (relocations in generic ELF against `arm-unknown-linux-gnueabihf`) +//@ needs-target-std + +use run_make_support::{bin_name, cwd, run, rustc}; + +fn main() { + // No remapping - relative paths + { + let runner_bin = bin_name("runner-no-remap-rel-paths"); + + let mut location_caller = rustc(); + location_caller.crate_type("lib").input("location-caller.rs"); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input("runner.rs").output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // No remapping - absolute paths + { + let runner_bin = bin_name("runner-no-remap-abs-paths"); + + let mut location_caller = rustc(); + location_caller.crate_type("lib").input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input(cwd().join("runner.rs")).output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // No remapping - mixed paths + { + let runner_bin = bin_name("runner-no-remap-mixed-paths"); + + let mut location_caller = rustc(); + location_caller.crate_type("lib").input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input("runner.rs").output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // Remapping current working directory + { + let runner_bin = bin_name("runner-remap-cwd"); + + let mut location_caller = rustc(); + location_caller + .crate_type("lib") + .remap_path_prefix(cwd(), "/remapped") + .input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner + .crate_type("bin") + .remap_path_prefix(cwd(), "/remapped") + .input(cwd().join("runner.rs")) + .output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // Remapping current working directory - only in the dependency + { + let runner_bin = bin_name("runner-remap-cwd-only-dep"); + + let mut location_caller = rustc(); + location_caller + .crate_type("lib") + .remap_path_prefix(cwd(), "/remapped") + .input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner.crate_type("bin").input(cwd().join("runner.rs")).output(&runner_bin); + runner.run(); + + run(&runner_bin); + } + + // Remapping current working directory - different scopes + { + let runner_bin = bin_name("runner-remap-cwd-diff-scope"); + + let mut location_caller = rustc(); + location_caller + .crate_type("lib") + .remap_path_prefix(cwd(), "/remapped") + .arg("--remap-path-scope=object") + .input(cwd().join("location-caller.rs")); + location_caller.run(); + + let mut runner = rustc(); + runner + .crate_type("bin") + .remap_path_prefix(cwd(), "/remapped") + .arg("--remap-path-scope=diagnostics") + .input(cwd().join("runner.rs")) + .output(&runner_bin); + runner.run(); + + run(&runner_bin); + } +} diff --git a/tests/run-make/remap-path-prefix-consts/runner.rs b/tests/run-make/remap-path-prefix-consts/runner.rs new file mode 100644 index 000000000000..d67dbe3b398a --- /dev/null +++ b/tests/run-make/remap-path-prefix-consts/runner.rs @@ -0,0 +1,19 @@ +// Verifies that the paths are the same and consistent between this crate and location_caller crate. +// +// https://github.com/rust-lang/rust/issues/148328 + +extern crate location_caller; + +fn main() { + { + // Assert both paths are the same + let the_path = location_caller::the_path(); + let the_path2 = location_caller::the_path2(); + assert_eq!(the_path, the_path2); + } + + { + // Let's make sure we don't read OOB memory + println!("{:?}", location_caller::the_zeroed_path_len_array()); + } +} diff --git a/tests/run-make/remap-path-prefix-dwarf/rmake.rs b/tests/run-make/remap-path-prefix-dwarf/rmake.rs index 3b88fca0bb7f..ab6c1fb70d68 100644 --- a/tests/run-make/remap-path-prefix-dwarf/rmake.rs +++ b/tests/run-make/remap-path-prefix-dwarf/rmake.rs @@ -105,7 +105,7 @@ fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) { let mut rustc_sm = rustc(); rustc_sm.input(cwd().join("src/some_value.rs")); rustc_sm.arg("-Cdebuginfo=2"); - rustc_sm.arg(format!("-Zremap-path-scope={}", scope)); + rustc_sm.arg(format!("--remap-path-scope={}", scope)); rustc_sm.arg("--remap-path-prefix"); rustc_sm.arg(format!("{}=/REMAPPED", cwd().display())); rustc_sm.arg("-Csplit-debuginfo=off"); @@ -117,7 +117,7 @@ fn check_dwarf_deps(scope: &str, dwarf_test: DwarfDump) { rustc_pv.input(cwd().join("src/print_value.rs")); rustc_pv.output(&print_value_rlib); rustc_pv.arg("-Cdebuginfo=2"); - rustc_pv.arg(format!("-Zremap-path-scope={}", scope)); + rustc_pv.arg(format!("--remap-path-scope={}", scope)); rustc_pv.arg("--remap-path-prefix"); rustc_pv.arg(format!("{}=/REMAPPED", cwd().display())); rustc_pv.arg("-Csplit-debuginfo=off"); @@ -158,8 +158,8 @@ fn check_dwarf(test: DwarfTest) { rustc.arg("-Cdebuginfo=2"); if let Some(scope) = test.scope { match scope { - ScopeType::Object => rustc.arg("-Zremap-path-scope=object"), - ScopeType::Diagnostics => rustc.arg("-Zremap-path-scope=diagnostics"), + ScopeType::Object => rustc.arg("--remap-path-scope=object"), + ScopeType::Diagnostics => rustc.arg("--remap-path-scope=diagnostics"), }; if is_darwin() { rustc.arg("-Csplit-debuginfo=off"); diff --git a/tests/run-make/remap-path-prefix-std/rmake.rs b/tests/run-make/remap-path-prefix-std/rmake.rs new file mode 100644 index 000000000000..f5179038a9b1 --- /dev/null +++ b/tests/run-make/remap-path-prefix-std/rmake.rs @@ -0,0 +1,53 @@ +// This test makes sure that we do not leak paths to the checkout +// (ie. /checkout in CI) in the distributed `libstd` debuginfo. +// +// This test only runs on Linux and dist builder (or with `rust.remap-debuginfo = true` +// set in your `bootstrap.toml`). + +//@ needs-std-remap-debuginfo +//@ only-linux + +use std::path::PathBuf; + +use run_make_support::{llvm_dwarfdump, rfs, rustc, shallow_find_files, source_root}; + +fn main() { + // Find the target libdir for the current target + let target_libdir = { + let output = rustc().print("target-libdir").run(); + let stdout = output.stdout_utf8(); + let path = PathBuf::from(stdout.trim()); + + // Assert that the target-libdir path exists + assert!(path.exists(), "target-libdir: {path:?} does not exists"); + + path + }; + + // Find all the `libstd-.*.rlib` files under the libdir + let libstd_rlibs = shallow_find_files(&target_libdir, |p| { + if let Some(filename) = p.file_name() + && let filename = filename.to_string_lossy() + { + filename.starts_with("libstd-") && filename.ends_with(".rlib") + } else { + false + } + }); + + // Assert that there is only one rlib for the `libstd` + let [libstd_rlib] = &libstd_rlibs[..] else { + unreachable!("multiple libstd rlib: {libstd_rlibs:?} in {target_libdir:?}"); + }; + + // Symlink the libstd rlib here to avoid absolute paths from llvm-dwarfdump own output + // and not from the debuginfo it-self + rfs::symlink_file(libstd_rlib, "libstd.rlib"); + + // Check that there is only `/rustc/` paths and no `/checkout`, `/home`, or whatever + llvm_dwarfdump() + .input("libstd.rlib") + .run() + .assert_stdout_contains("/rustc/") + .assert_stdout_not_contains(source_root().to_string_lossy()); +} diff --git a/tests/run-make/remap-path-prefix/rmake.rs b/tests/run-make/remap-path-prefix/rmake.rs index b75ca9e796ac..3b866476e950 100644 --- a/tests/run-make/remap-path-prefix/rmake.rs +++ b/tests/run-make/remap-path-prefix/rmake.rs @@ -12,7 +12,9 @@ fn main() { let mut out_simple = rustc(); let mut out_object = rustc(); let mut out_macro = rustc(); + let mut out_doc = rustc(); let mut out_diagobj = rustc(); + let mut out_diagdocobj = rustc(); out_simple .remap_path_prefix("auxiliary", "/the/aux") .crate_type("lib") @@ -28,23 +30,39 @@ fn main() { .crate_type("lib") .emit("metadata") .input("auxiliary/lib.rs"); + out_doc + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); out_diagobj .remap_path_prefix("auxiliary", "/the/aux") .crate_type("lib") .emit("metadata") .input("auxiliary/lib.rs"); + out_diagdocobj + .remap_path_prefix("auxiliary", "/the/aux") + .crate_type("lib") + .emit("metadata") + .input("auxiliary/lib.rs"); out_simple.run(); rmeta_contains("/the/aux/lib.rs"); rmeta_not_contains("auxiliary"); - out_object.arg("-Zremap-path-scope=object"); - out_macro.arg("-Zremap-path-scope=macro"); - out_diagobj.arg("-Zremap-path-scope=diagnostics,object"); + out_object.arg("--remap-path-scope=object"); + out_macro.arg("--remap-path-scope=macro"); + out_doc.arg("--remap-path-scope=documentation").arg("-Zunstable-options"); + out_diagobj.arg("--remap-path-scope=diagnostics,object"); + out_diagdocobj + .arg("--remap-path-scope=diagnostics,documentation,object") + .arg("-Zunstable-options"); if is_darwin() { out_object.arg("-Csplit-debuginfo=off"); out_macro.arg("-Csplit-debuginfo=off"); + out_doc.arg("-Csplit-debuginfo=off"); out_diagobj.arg("-Csplit-debuginfo=off"); + out_diagdocobj.arg("-Csplit-debuginfo=off"); } out_object.run(); @@ -53,8 +71,14 @@ fn main() { out_macro.run(); rmeta_contains("/the/aux/lib.rs"); rmeta_contains("auxiliary"); + out_doc.run(); + rmeta_contains("/the/aux/lib.rs"); + rmeta_contains("auxiliary"); out_diagobj.run(); rmeta_contains("/the/aux/lib.rs"); + rmeta_contains("auxiliary"); + out_diagdocobj.run(); + rmeta_contains("/the/aux/lib.rs"); rmeta_not_contains("auxiliary"); } diff --git a/tests/run-make/reproducible-build/rmake.rs b/tests/run-make/reproducible-build/rmake.rs index 93fc30de07d7..993c2c8092a6 100644 --- a/tests/run-make/reproducible-build/rmake.rs +++ b/tests/run-make/reproducible-build/rmake.rs @@ -199,13 +199,9 @@ fn diff_dir_test(crate_type: CrateType, remap_type: RemapType) { .arg(format!("--remap-path-prefix={}=/b", base_dir.join("test").display())); } RemapType::Cwd { is_empty } => { - // FIXME(Oneirical): Building with crate type set to `bin` AND having -Cdebuginfo=2 - // (or `-g`, the shorthand form) enabled will cause reproducibility failures - // for multiple platforms. - // See https://github.com/rust-lang/rust/issues/89911 // FIXME(#129117): Windows rlib + `-Cdebuginfo=2` + `-Z remap-cwd-prefix=.` seems // to be unreproducible. - if !matches!(crate_type, CrateType::Bin) && !is_windows() { + if !is_windows() { compiler1.arg("-Cdebuginfo=2"); compiler2.arg("-Cdebuginfo=2"); } diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index 90ba424ffe94..d281d820f47b 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -15,7 +15,11 @@ fn main() { // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking // the linker to display its version number with a link-arg. assert_rustc_uses_lld( - rustc().crate_type("cdylib").target("custom-target.json").input("lib.rs"), + rustc() + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Zunstable-options") + .input("lib.rs"), ); // But it can also be disabled via linker features. diff --git a/tests/run-make/rustc-help/help-v.diff b/tests/run-make/rustc-help/help-v.diff index 60a9dfbe201d..94ed6a0ed027 100644 --- a/tests/run-make/rustc-help/help-v.diff +++ b/tests/run-make/rustc-help/help-v.diff @@ -1,4 +1,4 @@ -@@ -65,10 +65,28 @@ +@@ -65,10 +65,31 @@ Set a codegen option -V, --version Print version info and exit -v, --verbose Use verbose output @@ -20,6 +20,9 @@ + --remap-path-prefix = + Remap source names in all output (compiler messages + and output files) ++ --remap-path-scope ++ Defines which scopes of paths should be remapped by ++ `--remap-path-prefix` + @path Read newline separated options from `path` Additional help: diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout index c41cb5e3bde8..0acbb766c155 100644 --- a/tests/run-make/rustc-help/help-v.stdout +++ b/tests/run-make/rustc-help/help-v.stdout @@ -51,7 +51,7 @@ Options: --explain Provide a detailed explanation of an error message --test Build a test harness --target - Target triple for which the code is compiled + Target tuple for which the code is compiled -A, --allow Set lint allowed -W, --warn Set lint warnings --force-warn @@ -83,6 +83,9 @@ Options: --remap-path-prefix = Remap source names in all output (compiler messages and output files) + --remap-path-scope + Defines which scopes of paths should be remapped by + `--remap-path-prefix` @path Read newline separated options from `path` Additional help: diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout index 5e13a900484d..4075dd028299 100644 --- a/tests/run-make/rustc-help/help.stdout +++ b/tests/run-make/rustc-help/help.stdout @@ -51,7 +51,7 @@ Options: --explain Provide a detailed explanation of an error message --test Build a test harness --target - Target triple for which the code is compiled + Target tuple for which the code is compiled -A, --allow Set lint allowed -W, --warn Set lint warnings --force-warn diff --git a/tests/run-make/rustc-help/rmake.rs b/tests/run-make/rustc-help/rmake.rs index 85e90e6352d0..17811ef18449 100644 --- a/tests/run-make/rustc-help/rmake.rs +++ b/tests/run-make/rustc-help/rmake.rs @@ -18,4 +18,34 @@ fn main() { // Check the diff between `rustc --help` and `rustc --help -v`. let help_v_diff = similar::TextDiff::from_lines(&help, &help_v).unified_diff().to_string(); diff().expected_file("help-v.diff").actual_text("actual", &help_v_diff).run(); + + // Check that all help options can be invoked at once + let codegen_help = bare_rustc().arg("-Chelp").run().stdout_utf8(); + let unstable_help = bare_rustc().arg("-Zhelp").run().stdout_utf8(); + let lints_help = bare_rustc().arg("-Whelp").run().stdout_utf8(); + let expected_all = format!("{help}{codegen_help}{unstable_help}{lints_help}"); + let all_help = bare_rustc().args(["--help", "-Chelp", "-Zhelp", "-Whelp"]).run().stdout_utf8(); + diff() + .expected_text( + "(rustc --help && rustc -Chelp && rustc -Zhelp && rustc -Whelp)", + &expected_all, + ) + .actual_text("(rustc --help -Chelp -Zhelp -Whelp)", &all_help) + .run(); + + // Check that the ordering of help options is respected + // Note that this is except for `-Whelp`, which always comes last + let expected_ordered_help = format!("{unstable_help}{codegen_help}{help}{lints_help}"); + let ordered_help = + bare_rustc().args(["-Whelp", "-Zhelp", "-Chelp", "--help"]).run().stdout_utf8(); + diff() + .expected_text( + "(rustc -Whelp && rustc -Zhelp && rustc -Chelp && rustc --help)", + &expected_ordered_help, + ) + .actual_text("(rustc -Whelp -Zhelp -Chelp --help)", &ordered_help) + .run(); + + // Test that `rustc --help` does not suppress invalid flag errors + let help = bare_rustc().arg("--help --invalid-flag").run_fail().stdout_utf8(); } diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout index 49eaf7e2e1e0..4e28be347cbb 100644 --- a/tests/run-make/rustdoc-default-output/output-default.stdout +++ b/tests/run-make/rustdoc-default-output/output-default.stdout @@ -154,6 +154,10 @@ Options: Comma separated list of types of output for rustdoc to emit --no-run Compile doctests without running them + --merge-doctests yes|no|auto + Force all doctests to be compiled as a single binary, + instead of one binary per test. If merging fails, + rustdoc will emit a hard error. --remap-path-prefix FROM=TO Remap source names in compiler messages --show-type-layout diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep1.rs b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs new file mode 100644 index 000000000000..b62f31c982b7 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs @@ -0,0 +1,10 @@ +pub struct Dep1; +pub struct Dep2; +pub struct Dep3; +pub struct Dep4; + +//@ hasraw crates.js 'dep1' +//@ hasraw search.index/name/*.js 'Dep1' +//@ has dep1/index.html +#[doc(alias = "dep1_missing")] +pub struct Dep5; diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep2.rs b/tests/run-make/rustdoc-merge-directory-alias/dep2.rs new file mode 100644 index 000000000000..2df4452413c2 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep2.rs @@ -0,0 +1,4 @@ +//@ hasraw crates.js 'dep2' +//@ hasraw search.index/name/*.js 'Second' +//@ has dep2/index.html +pub struct Second; diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs b/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs new file mode 100644 index 000000000000..74236aef47ea --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs @@ -0,0 +1,4 @@ +//@ !hasraw crates.js 'dep_missing' +//@ !hasraw search.index/name/*.js 'DepMissing' +//@ has dep_missing/index.html +pub struct DepMissing; diff --git a/tests/run-make/rustdoc-merge-directory-alias/rmake.rs b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs new file mode 100644 index 000000000000..096eb4a487c1 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs @@ -0,0 +1,88 @@ +// Running --merge=finalize without an input crate root should not trigger ICE. +// Issue: https://github.com/rust-lang/rust/issues/146646 + +//@ needs-target-std + +use run_make_support::{htmldocck, path, rustdoc}; + +fn main() { + let out_dir = path("out"); + let merged_dir = path("merged"); + let parts_out_dir = path("parts"); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + rustdoc() + .input("dep2.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + let output2 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output2.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output3 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output3.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + // dep_missing is different, because --parts-out-dir is not supplied + rustdoc().input("dep_missing.rs").out_dir(&out_dir).run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output4 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output4.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + htmldocck().arg(&out_dir).arg("dep1.rs").run(); + htmldocck().arg(&out_dir).arg("dep2.rs").run(); + htmldocck().arg(&out_dir).arg("dep_missing.rs").run(); +} diff --git a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs index d43aa9b90ac7..8660556564f1 100644 --- a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs +++ b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs @@ -5,8 +5,14 @@ use run_make_support::{cwd, rustc, rustdoc}; fn main() { let out_dir = "rustdoc-target-spec-json-path"; - rustc().crate_type("lib").input("dummy_core.rs").target("target.json").run(); + rustc() + .arg("-Zunstable-options") + .crate_type("lib") + .input("dummy_core.rs") + .target("target.json") + .run(); rustdoc() + .arg("-Zunstable-options") .input("my_crate.rs") .out_dir(out_dir) .library_search_path(cwd()) diff --git a/tests/run-make/short-ice/rmake.rs b/tests/run-make/short-ice/rmake.rs index dbe0f692aefb..043f880abcf7 100644 --- a/tests/run-make/short-ice/rmake.rs +++ b/tests/run-make/short-ice/rmake.rs @@ -12,40 +12,53 @@ // - FIXME(#143198): On `x86_64-pc-windows-msvc`: full backtrace sometimes do not contain matching // count of short backtrace markers (e.g. 5x end marker, but 3x start marker). -use run_make_support::rustc; +use run_make_support::CompletedProcess; fn main() { - let rust_test_1 = - rustc().set_backtrace_level("1").input("src/lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); - let rust_test_2 = rustc() - .set_backtrace_level("full") - .input("src/lib.rs") - .arg("-Ztreat-err-as-bug=1") - .run_fail(); + // Run the same command twice with `RUST_BACKTRACE=1` and `RUST_BACKTRACE=full`. + let configure_rustc = || { + let mut rustc = run_make_support::rustc(); + rustc.input("src/lib.rs").arg("-Ztreat-err-as-bug=1"); + rustc + }; + let rustc_bt_short = configure_rustc().set_backtrace_level("1").run_fail(); + let rustc_bt_full = configure_rustc().set_backtrace_level("full").run_fail(); - let mut rust_test_log_1 = rust_test_1.stderr_utf8(); - rust_test_log_1.push_str(&rust_test_1.stdout_utf8()); - let rust_test_log_1 = rust_test_log_1.as_str(); + // Combine stderr and stdout for subsequent checks. + let concat_stderr_stdout = + |proc: &CompletedProcess| format!("{}\n{}", proc.stderr_utf8(), proc.stdout_utf8()); + let output_bt_short = &concat_stderr_stdout(&rustc_bt_short); + let output_bt_full = &concat_stderr_stdout(&rustc_bt_full); - let mut rust_test_log_2 = rust_test_2.stderr_utf8(); - rust_test_log_2.push_str(&rust_test_2.stdout_utf8()); - let rust_test_log_2 = rust_test_log_2.as_str(); + // Count how many lines of output mention symbols or paths in + // `rustc_query_impl`, which are the kinds of + // stack frames we want to be omitting in short backtraces. + let rustc_query_count_short = count_lines_with(output_bt_short, "rustc_query_impl"); + let rustc_query_count_full = count_lines_with(output_bt_full, "rustc_query_impl"); - let rustc_query_count_full = count_lines_with(rust_test_log_2, "rustc_query_"); + // Dump both outputs in full to make debugging easier, especially on CI. + // Use `--no-capture --force-rerun` to view output even when the test is passing. + println!("=== BEGIN SHORT BACKTRACE ===\n{output_bt_short}\n=== END SHORT BACKTRACE === "); + println!("=== BEGIN FULL BACKTRACE ===\n{output_bt_full}\n=== END FULL BACKTRACE === "); assert!( - rust_test_log_1.lines().count() < rust_test_log_2.lines().count(), - "Short backtrace should be shorter than full backtrace.\nShort backtrace:\n\ - {rust_test_log_1}\nFull backtrace:\n{rust_test_log_2}" + output_bt_short.lines().count() < output_bt_full.lines().count(), + "Short backtrace should be shorter than full backtrace" ); + + let n_begin = count_lines_with(output_bt_full, "__rust_begin_short_backtrace"); + let n_end = count_lines_with(output_bt_full, "__rust_end_short_backtrace"); + assert!(n_begin + n_end > 0, "Full backtrace should contain short-backtrace markers"); assert_eq!( - count_lines_with(rust_test_log_2, "__rust_begin_short_backtrace"), - count_lines_with(rust_test_log_2, "__rust_end_short_backtrace"), - "Full backtrace should contain the short backtrace markers.\nFull backtrace:\n\ - {rust_test_log_2}" + n_begin, n_end, + "Full backtrace should contain equal numbers of begin and end markers" + ); + + assert!( + rustc_query_count_short + 5 < rustc_query_count_full, + "Short backtrace should have omitted more query plumbing lines \ + (actual: {rustc_query_count_short} vs {rustc_query_count_full})" ); - assert!(count_lines_with(rust_test_log_1, "rustc_query_") + 5 < rustc_query_count_full); - assert!(rustc_query_count_full > 5); } fn count_lines_with(s: &str, search: &str) -> usize { diff --git a/tests/run-make/simd-ffi/rmake.rs b/tests/run-make/simd-ffi/rmake.rs index c6315073fa8c..054ea402a698 100644 --- a/tests/run-make/simd-ffi/rmake.rs +++ b/tests/run-make/simd-ffi/rmake.rs @@ -17,6 +17,9 @@ fn main() { "arm-unknown-linux-gnueabi".to_owned(), ]); } + if llvm_components_contain("amdgpu") { + targets.push("amdgcn-amd-amdhsa".to_owned()); + } let mut x86_archs = Vec::new(); if llvm_components_contain("x86") { x86_archs.append(&mut vec!["i686", "x86_64"]); @@ -52,21 +55,25 @@ fn main() { // enabled by-default for i686 and ARM; these features will be invalid // on some platforms, but LLVM just prints a warning so that's fine for // now. + let mut cmd = rustc(); + cmd.target(&target).emit("llvm-ir,asm").input("simd.rs"); let target_feature = if target.starts_with("i686") || target.starts_with("x86") { "+sse2" } else if target.starts_with("arm") || target.starts_with("aarch64") { "-soft-float,+neon" } else if target.starts_with("mips") { "+msa,+fp64" + } else if target.starts_with("amdgcn") { + cmd.arg("-Ctarget-cpu=gfx900"); + "" } else { panic!("missing target_feature case for {target}"); }; - rustc() - .target(&target) - .emit("llvm-ir,asm") - .input("simd.rs") - .arg(format!("-Ctarget-feature={target_feature}")) - .arg(&format!("-Cextra-filename=-{target}")) - .run(); + + if !target_feature.is_empty() { + cmd.arg(format!("-Ctarget-feature={target_feature}")); + } + + cmd.arg(&format!("-Cextra-filename=-{target}")).run(); } } diff --git a/tests/run-make/split-debuginfo/rmake.rs b/tests/run-make/split-debuginfo/rmake.rs index e53b71010781..0d311607a11a 100644 --- a/tests/run-make/split-debuginfo/rmake.rs +++ b/tests/run-make/split-debuginfo/rmake.rs @@ -171,8 +171,7 @@ enum RemapPathPrefix { Unspecified, } -/// `-Zremap-path-scope`. See -/// . +/// `--remap-path-scope` #[derive(Debug, Clone)] enum RemapPathScope { /// Comma-separated list of remap scopes: `macro`, `diagnostics`, `debuginfo`, `object`, `all`. @@ -921,7 +920,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } @@ -950,7 +949,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); FileAssertions { expected_files: BTreeSet::from(["foo", "foo.dwp"]) } @@ -1202,7 +1201,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); @@ -1242,7 +1241,7 @@ mod shared_linux_other_tests { .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) - .arg(format!("-Zremap-path-scope={scope}")) + .arg(format!("--remap-path-scope={scope}")) .run(); let found_files = cwd_filenames(); @@ -1356,7 +1355,7 @@ fn main() { // NOTE: these combinations are not exhaustive, because while porting to rmake.rs initially I // tried to preserve the existing test behavior closely. Notably, no attempt was made to // exhaustively cover all cases in the 6-fold Cartesian product of `{,-Csplit=debuginfo=...}` x - // `{,-Cdebuginfo=...}` x `{,--remap-path-prefix}` x `{,-Zremap-path-scope=...}` x + // `{,-Cdebuginfo=...}` x `{,--remap-path-prefix}` x `{,--remap-path-scope=...}` x // `{,-Zsplit-dwarf-kind=...}` x `{,-Clinker-plugin-lto}`. If you really want to, you can // identify which combination isn't exercised with a 6-layers nested for loop iterating through // each of the cli flag enum variants. diff --git a/tests/run-make/sysroot-crates-are-unstable/rmake.rs b/tests/run-make/sysroot-crates-are-unstable/rmake.rs index 20ad01bef61d..3b75e4d90d96 100644 --- a/tests/run-make/sysroot-crates-are-unstable/rmake.rs +++ b/tests/run-make/sysroot-crates-are-unstable/rmake.rs @@ -28,13 +28,17 @@ fn check_crate_is_unstable(cr: &Crate) { print!("- Verifying that sysroot crate '{name}' is an unstable crate ..."); - // Trying to use this crate from a user program should fail. - let output = rustc() - .crate_type("rlib") - .extern_(name, path) - .input("-") - .stdin_buf(format!("extern crate {name};")) - .run_fail(); + // Checking if rmeta path exists + let rmeta_path = path.with_extension("rmeta"); + + let mut cmd = rustc(); + cmd.crate_type("rlib").extern_(name, path); // Pass the rlib + + if rmeta_path.exists() { + cmd.extern_(name, &rmeta_path); + } + + let output = cmd.input("-").stdin_buf(format!("extern crate {name};")).run_fail(); // Make sure it failed for the intended reason, not some other reason. // (The actual feature required varies between crates.) @@ -44,8 +48,8 @@ fn check_crate_is_unstable(cr: &Crate) { } fn get_unstable_sysroot_crates() -> Vec { - let sysroot = PathBuf::from(rustc().print("sysroot").run().stdout_utf8().trim()); - let sysroot_libs_dir = sysroot.join("lib").join("rustlib").join(target()).join("lib"); + let sysroot_libs_dir = + PathBuf::from(rustc().print("target-libdir").target(target()).run().stdout_utf8().trim()); println!("Sysroot libs dir: {sysroot_libs_dir:?}"); // Generate a list of all library crates in the sysroot. diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 7c30a5b21b33..6c88f3164e9e 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs @@ -15,11 +15,27 @@ fn main() { .run_fail() .assert_stderr_contains("error loading target specification"); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("my-incomplete-platform.json") .run_fail() .assert_stderr_contains("missing field `llvm-target`"); + let _ = rustc() + .input("foo.rs") + .target("my-x86_64-unknown-linux-gnu-platform") + .crate_type("lib") + .emit("asm") + .run_fail() + .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); + let _ = rustc() + .input("foo.rs") + .target("my-awesome-platform.json") + .crate_type("lib") + .emit("asm") + .run_fail() + .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); rustc() + .arg("-Zunstable-options") .env("RUST_TARGET_PATH", ".") .input("foo.rs") .target("my-awesome-platform") @@ -27,6 +43,7 @@ fn main() { .emit("asm") .run(); rustc() + .arg("-Zunstable-options") .env("RUST_TARGET_PATH", ".") .input("foo.rs") .target("my-x86_64-unknown-linux-gnu-platform") @@ -52,27 +69,31 @@ fn main() { .actual_text("test-platform-2", test_platform_2) .run(); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("endianness-mismatch") .run_fail() .assert_stderr_contains(r#""data-layout" claims architecture is little-endian"#); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("mismatching-data-layout") .crate_type("lib") .run_fail() .assert_stderr_contains("data-layout for target"); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("require-explicit-cpu") .crate_type("lib") .run_fail() .assert_stderr_contains("target requires explicitly specifying a cpu"); rustc() + .arg("-Zunstable-options") .input("foo.rs") .target("require-explicit-cpu") .crate_type("lib") .arg("-Ctarget-cpu=generic") .run(); - rustc().target("require-explicit-cpu").arg("--print=target-cpus").run(); + rustc().arg("-Zunstable-options").target("require-explicit-cpu").print("target-cpus").run(); } diff --git a/tests/run-make/track-path-dep-info/macro_def.rs b/tests/run-make/track-path-dep-info/macro_def.rs index 8777ce21f8b8..b7271cac2344 100644 --- a/tests/run-make/track-path-dep-info/macro_def.rs +++ b/tests/run-make/track-path-dep-info/macro_def.rs @@ -1,4 +1,4 @@ -#![feature(track_path)] +#![feature(proc_macro_tracked_path)] #![crate_type = "proc-macro"] extern crate proc_macro; @@ -6,6 +6,6 @@ use proc_macro::*; #[proc_macro] pub fn access_tracked_paths(_: TokenStream) -> TokenStream { - tracked_path::path("emojis.txt"); + tracked::path("emojis.txt"); TokenStream::new() } diff --git a/tests/run-make/translation/rmake.rs b/tests/run-make/translation/rmake.rs index 86078888c2e1..4d7fd71a2f4a 100644 --- a/tests/run-make/translation/rmake.rs +++ b/tests/run-make/translation/rmake.rs @@ -10,6 +10,9 @@ //@ needs-symlink //@ needs-subprocess +// FIXME(151366) Currently `-Ztranslate-additional-ftl` is currently broken +//@ ignore-test + #![deny(warnings)] use std::path::{Path, PathBuf}; diff --git a/tests/run-make/wasm-emscripten-cdylib/foo.rs b/tests/run-make/wasm-emscripten-cdylib/foo.rs new file mode 100644 index 000000000000..08ad8e7b5c61 --- /dev/null +++ b/tests/run-make/wasm-emscripten-cdylib/foo.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn foo() -> i32 { + 42 +} diff --git a/tests/run-make/wasm-emscripten-cdylib/rmake.rs b/tests/run-make/wasm-emscripten-cdylib/rmake.rs new file mode 100644 index 000000000000..ef5fc17c2bbe --- /dev/null +++ b/tests/run-make/wasm-emscripten-cdylib/rmake.rs @@ -0,0 +1,25 @@ +//! Check that cdylib crate type is supported for the wasm32-unknown-emscripten +//! target and produces a valid Emscripten dynamic library. + +//@ only-wasm32-unknown-emscripten + +use run_make_support::{bare_rustc, rfs, wasmparser}; + +fn main() { + bare_rustc().input("foo.rs").target("wasm32-unknown-emscripten").crate_type("cdylib").run(); + + // Verify the output is a valid wasm file with a dylink.0 section + let file = rfs::read("foo.wasm"); + let mut has_dylink = false; + + for payload in wasmparser::Parser::new(0).parse_all(&file) { + let payload = payload.unwrap(); + if let wasmparser::Payload::CustomSection(s) = payload { + if s.name() == "dylink.0" { + has_dylink = true; + } + } + } + + assert!(has_dylink, "expected dylink.0 section in emscripten cdylib output"); +} diff --git a/tests/rustdoc-gui/anchor-navigable.goml b/tests/rustdoc-gui/anchor-navigable.goml index 61d7c89d434f..db7fc3bbf182 100644 --- a/tests/rustdoc-gui/anchor-navigable.goml +++ b/tests/rustdoc-gui/anchor-navigable.goml @@ -7,5 +7,5 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // We check that ".item-info" is bigger than its content. move-cursor-to: ".impl" -assert-property: (".impl > a.anchor", {"offsetWidth": "8"}) +assert-property: (".impl > a.anchor", {"offsetWidth": "16"}) assert-css: (".impl > a.anchor", {"left": "-8px"}) diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml index 3168c8e17c52..eaec73f50e97 100644 --- a/tests/rustdoc-gui/anchors.goml +++ b/tests/rustdoc-gui/anchors.goml @@ -14,9 +14,9 @@ define-function: ( assert-css: ("#toggle-all-docs", {"color": |main_color|}) assert-css: (".main-heading h1 span", {"color": |main_heading_type_color|}) assert-css: ( - ".rightside a.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, - ALL, + ".rightside a.src", + {"color": |src_link_color|, "text-decoration": "none"}, + ALL, ) compare-elements-css: ( ".rightside a.src", @@ -31,25 +31,39 @@ define-function: ( move-cursor-to: ".main-heading a.src" assert-css: ( - ".main-heading a.src", - {"color": |src_link_color|, "text-decoration": "underline solid " + |src_link_color|}, + ".main-heading a.src", + {"color": |src_link_color|, "text-decoration": "underline"}, ) move-cursor-to: ".impl-items .rightside a.src" assert-css: ( - ".impl-items .rightside a.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + ".impl-items .rightside a.src", + {"color": |src_link_color|, "text-decoration": "none"}, ) move-cursor-to: ".impl-items a.rightside.src" assert-css: ( - ".impl-items a.rightside.src", - {"color": |src_link_color|, "text-decoration": "none solid " + |src_link_color|}, + ".impl-items a.rightside.src", + {"color": |src_link_color|, "text-decoration": "none"}, ) + // Now we ensure that the `§` anchor is "reachable" for users on trait methods. + // To ensure the anchor is not hovered, we move the cursor to another item. + move-cursor-to: "#search-button" + // By default, the anchor is not displayed. + wait-for-css: ("#method\.vroum .anchor", {"display": "none"}) + // Once we move the cursor to the method, the anchor should appear. + move-cursor-to: "#method\.vroum .code-header" + assert-css-false: ("#method\.vroum .anchor", {"display": "none"}) + // Now we move the cursor to the anchor to check there is no gap between the method and the + // anchor, making the anchor disappear and preventing users to click on it. + // To make it work, we need to first move it between the method and the anchor. + store-position: ("#method\.vroum .code-header", {"x": method_x, "y": method_y}) + move-cursor-to: (|method_x| - 2, |method_y|) + // Anchor should still be displayed. + assert-css-false: ("#method\.vroum .anchor", {"display": "none"}) + go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" // Since we changed page, we need to set the theme again. - set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} - // We reload the page so the local storage settings are being used. - reload: + call-function: ("switch-theme", {"theme": |theme|}) assert-css: ("#top-doc-prose-title", {"color": |title_color|}) diff --git a/tests/rustdoc-gui/copy-code.goml b/tests/rustdoc-gui/copy-code.goml index a6fb816c4bd6..eb003ef5e1ca 100644 --- a/tests/rustdoc-gui/copy-code.goml +++ b/tests/rustdoc-gui/copy-code.goml @@ -1,5 +1,6 @@ // Checks that the "copy code" button is not triggering JS error and its display // isn't broken. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" define-function: ( @@ -42,7 +43,31 @@ store-size: (".example-wrap:nth-of-type(1) .copy-button", { }) assert: |copy_height| > 0 && |copy_width| > 0 -// Checking same things for the copy button when there is no run button. + +// We now check that copying code when line numbers are displayed don't include these line numbers. + +// First we ensure that the clipboard is empty. +assert-clipboard: "" + +// We make the line numbers appear. +call-function: ("open-settings-menu", {}) +click: "#line-numbers" +wait-for-local-storage: {"rustdoc-line-numbers": "true" } + +// We close the settings menu. +call-function: ("close-settings-menu", {}) + +// We ensure that there are actually line numbers generated in the DOM. +assert-text: (".example-wrap pre.rust code span[data-nosnippet]", "1") +// We make the copy button appear. +move-cursor-to: ".example-wrap pre.rust code" +wait-for-css: (".example-wrap .button-holder", {"visibility": "visible"}) +// We click on the copy button. +click: ".example-wrap .button-holder .copy-button" +assert-clipboard: 'println!("nothing fancy"); +println!("but with two lines!");' + +// Back to UI checks, checking same things for the copy button when there is no run button. go-to: "file://" + |DOC_PATH| + "/lib2/sub_mod/struct.Foo.html" call-function: ("check-copy-button", {}) // Ensure there is no run button. diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml index a182124aced2..92ec0eb43a31 100644 --- a/tests/rustdoc-gui/docblock-code-block-line-number.goml +++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml @@ -1,9 +1,14 @@ // Checks that the setting "line numbers" is working as expected. include: "utils.goml" + go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html" +// Otherwise, we can't check text color +show-text: true + +store-value: (line_numbers_selector, ".example-wrap pre.rust code [data-nosnippet]") // We check that without this setting, there is no line number displayed. -assert-false: "pre.example-line-numbers" +assert-count: (|line_numbers_selector|, 0) // All corners should be rounded. assert-css: ( @@ -17,14 +22,16 @@ assert-css: ( ALL, ) -// We set the setting to show the line numbers on code examples. -set-local-storage: {"rustdoc-line-numbers": "true"} -reload: -// We wait for the line numbers to be added into the DOM by the JS... -wait-for: ".digits-1 pre" +// Before we add line numbers, we get the X position of a span in a code example that we will +// use later on to ensure that when we disable the line numbers, it goes back to its original +// position. +store-position: (".example-wrap code .macro", {"x": span_x_pos}) -// Otherwise, we can't check text color -show-text: true +// We enable the setting to show the line numbers on code examples. +call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) +// We ensure that there are actually line numbers generated in the DOM. +assert-text: (".example-wrap pre.rust code span[data-nosnippet]", "1") +assert-position-false: (".example-wrap code .macro", {"x": |span_x_pos|}) // Let's now check some CSS properties... define-function: ( @@ -68,20 +75,18 @@ call-function: ("check-colors", { // Now, try changing the setting dynamically. We'll turn it off, using the settings menu, // and make sure it goes away. -// First, open the settings menu. -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" -assert-css: ("#settings", {"display": "block"}) +call-function: ("switch-line-numbers-setting", {"expected_status": "false"}) +assert: ".digits-1.hide-lines" -// Then, click the toggle button. -click: "input#line-numbers" -wait-for: ".digits-1.hide-lines" -assert-local-storage: {"rustdoc-line-numbers": "false" } +// The line numbers not being displayed, their "space" should have disappear as well. +assert-position: (".example-wrap code .macro", {"x": |span_x_pos|}) // Finally, turn it on again. -click: "input#line-numbers" +call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) wait-for: ".digits-1:not(.hide-lines)" -assert-local-storage: {"rustdoc-line-numbers": "true" } + +// The line numbers are being displayed, their "space" should be back. +assert-position-false: (".example-wrap code .macro", {"x": |span_x_pos|}) // Same check with scraped examples line numbers. go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" @@ -119,26 +124,14 @@ call-function: ("check-padding", { }) define-function: ("check-line-numbers-existence", [], block { - assert-local-storage: {"rustdoc-line-numbers": "true" } - assert-false: ".example-line-numbers" - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" - - // Then, click the toggle button. - click: "input#line-numbers" - wait-for-local-storage-false: {"rustdoc-line-numbers": "true" } - assert-false: ".example-line-numbers" + assert-local-storage: {"rustdoc-line-numbers": "true"} + assert-count-false: (|line_numbers_selector|, 0) + call-function: ("switch-line-numbers-setting", {"expected_status": "false"}) // Line numbers should still be there. - assert-css: ("[data-nosnippet]", { "display": "block"}) - // Now disabling the setting. - click: "input#line-numbers" - wait-for-local-storage: {"rustdoc-line-numbers": "true" } - assert-false: ".example-line-numbers" - // Line numbers should still be there. - assert-css: ("[data-nosnippet]", { "display": "block"}) - // Closing settings menu. - click: "rustdoc-toolbar .settings-menu" - wait-for-css: ("#settings", {"display": "none"}) + assert-count-false: (|line_numbers_selector|, 0) + assert-css: (|line_numbers_selector|, {"display": "block"}) + // Now re-enabling the setting. + call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) }) // Checking that turning off the line numbers setting won't remove line numbers from scraped @@ -168,16 +161,11 @@ assert: ".example-wrap > pre.rust" assert-count: (".example-wrap", 2) assert-count: (".example-wrap.digits-1", 2) -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" - -// Then, click the toggle button. -click: "input#line-numbers" +// Disabling the line numbers setting. +call-function: ("switch-line-numbers-setting", {"expected_status": "false"}) wait-for-count: (".example-wrap.digits-1.hide-lines", 2) -assert-local-storage-false: {"rustdoc-line-numbers": "true" } -// Now turning off the setting. -click: "input#line-numbers" +// Now re-enabling the setting. +call-function: ("switch-line-numbers-setting", {"expected_status": "true"}) wait-for-count: (".example-wrap.digits-1", 2) wait-for-count: (".example-wrap.digits-1.hide-lines", 0) -assert-local-storage: {"rustdoc-line-numbers": "true" } diff --git a/tests/rustdoc-gui/font-serif-change.goml b/tests/rustdoc-gui/font-serif-change.goml index 1e9f21c35416..32e95cdc6ee1 100644 --- a/tests/rustdoc-gui/font-serif-change.goml +++ b/tests/rustdoc-gui/font-serif-change.goml @@ -1,4 +1,5 @@ // Ensures that the font serif change is working as expected. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // By default, it should be the serif fonts. @@ -8,8 +9,7 @@ assert-css: ("body", {"font-family": |serif_font|}) assert-css: ("p code", {"font-family": |serif_code_font|}) // We now switch to the sans serif font -click: "main .settings-menu" -wait-for: "#sans-serif-fonts" +call-function: ("open-settings-menu", {}) click: "#sans-serif-fonts" store-value: (font, '"Fira Sans", sans-serif') @@ -23,8 +23,7 @@ assert-css: ("body", {"font-family": |font|}) assert-css: ("p code", {"font-family": |code_font|}) // We switch back to the serif font -click: "main .settings-menu" -wait-for: "#sans-serif-fonts" +call-function: ("open-settings-menu", {}) click: "#sans-serif-fonts" assert-css: ("body", {"font-family": |serif_font|}) diff --git a/tests/rustdoc-gui/headings.goml b/tests/rustdoc-gui/headings.goml index 94d80a3e3df5..391234b78ebd 100644 --- a/tests/rustdoc-gui/headings.goml +++ b/tests/rustdoc-gui/headings.goml @@ -221,14 +221,14 @@ call-function: ( define-function: ( "check-since-color", - [theme], + [theme, color], block { call-function: ("switch-theme", {"theme": |theme|}) - assert-css: (".since", {"color": "#808080"}, ALL) + assert-css: (".since", {"color": |color|}, ALL) }, ) go-to: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html" -call-function: ("check-since-color", {"theme": "ayu"}) -call-function: ("check-since-color", {"theme": "dark"}) -call-function: ("check-since-color", {"theme": "light"}) +call-function: ("check-since-color", {"theme": "ayu", "color": "#808080"}) +call-function: ("check-since-color", {"theme": "dark", "color": "#d0d0d0"}) +call-function: ("check-since-color", {"theme": "light", "color": "#808080"}) diff --git a/tests/rustdoc-gui/implementors.goml b/tests/rustdoc-gui/implementors.goml index b39b95c1a9bf..d4542c6f7817 100644 --- a/tests/rustdoc-gui/implementors.goml +++ b/tests/rustdoc-gui/implementors.goml @@ -1,19 +1,46 @@ // The goal of this test is to check that the external trait implementors, generated with JS, // have the same display than the "local" ones. go-to: "file://" + |DOC_PATH| + "/implementors/trait.Whatever.html" -assert: "#implementors-list" -// There are supposed to be two implementors listed. -assert-count: ("#implementors-list .impl", 2) +wait-for-css: ("#implementors-list", {"display": "block"}) +// There are supposed to be four implementors listed. +assert-count: ("#implementors-list .impl", 4) +// There are supposed to be two non-negative implementors. +assert-count: ("#implementors-list .negative-marker ~ *", 2) // Now we check that both implementors have an anchor, an ID and a similar DOM. -assert: ("#implementors-list .impl:nth-child(1) > a.anchor") -assert-attribute: ("#implementors-list .impl:nth-child(1)", {"id": "impl-Whatever-for-Struct"}) -assert-attribute: ("#implementors-list .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever-for-Struct"}) -assert: "#implementors-list .impl:nth-child(1) > .code-header" +define-function: ( + "check-dom", + [id], + block { + assert-attribute: (|id| + " > a.anchor", {"href": |id|}) + assert: |id| + " > .code-header" + }, +) -assert: ("#implementors-list .impl:nth-child(2) > a.anchor") -assert-attribute: ("#implementors-list .impl:nth-child(2)", {"id": "impl-Whatever-1"}) -assert-attribute: ("#implementors-list .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"}) -assert: "#implementors-list .impl:nth-child(2) > .code-header" +call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct2"}) +call-function: ("check-dom", {"id": "#impl-Whatever-2"}) +call-function: ("check-dom", {"id": "#impl-Whatever-for-Struct"}) +call-function: ("check-dom", {"id": "#impl-Whatever-3"}) + +// Ensure that negative impl are sorted first. +assert-property: ( + "#implementors-list > *:nth-child(1) > h3", + {"textContent": "impl !Whatever for Struct2"}, +) +assert-property: ( + "#implementors-list > *:nth-child(2) > h3", + {"textContent": "impl !Whatever for StructToImplOnReexport"}, +) +// Third one is the negative marker. +assert-attribute: ("#implementors-list > *:nth-child(3)", {"class": "negative-marker"}) +// This one is a `` so the selector is a bit different. +assert-property: ( + "#implementors-list > *:nth-child(4) section > h3", + {"textContent": "impl Whatever for Struct"}, +) +assert-property: ( + "#implementors-list > *:nth-child(5) > h3", + {"textContent": "impl Whatever for Foo"}, +) go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HasEmptyTraits.html" compare-elements-position-near-false: ( @@ -39,3 +66,8 @@ assert-count: ("#implementors-list .impl", 1) go-to: "file://" + |DOC_PATH| + "/http/trait.HttpTrait.html" assert-count: ("#implementors-list .impl", 1) assert-attribute: ("#implementors-list .impl a.trait", {"href": "../http/trait.HttpTrait.html"}) + +// Now we check that if JS is disabled, the implementors list will be visible. +javascript: false +reload: +assert-css: ("#implementors-list", {"display": "block"}) diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml index a363175c1ddb..ae1509c6fa4f 100644 --- a/tests/rustdoc-gui/links-color.goml +++ b/tests/rustdoc-gui/links-color.goml @@ -41,7 +41,7 @@ define-function: ( move-cursor-to: "dd a[href='long_code_block_link/index.html']" assert-css: ( "dd a[href='long_code_block_link/index.html']", - {"text-decoration": "underline solid " + |mod|}, + {"text-decoration": "underline"}, ) }, ) diff --git a/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml b/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml new file mode 100644 index 000000000000..29a2096bba89 --- /dev/null +++ b/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml @@ -0,0 +1,34 @@ +// Ensure that topbar popover menus content can be scrolled on mobile. +go-to: "file://" + |DOC_PATH| + "/lib2/index.html" +store-value: (window_height, 500) +set-window-size: (400, |window_height|) + +include: "utils.goml" + +// We open the settings menu +call-function: ("open-settings-menu", {}) +// We ensure it's not scrolled down yet. +assert-property: ("#settings .settings", {"scrollTop": 0}) +// We ensure its height is smaller than the window's, but its content's height is bigger. +store-property: ("#settings .settings", {"offsetHeight": menu_height, "scrollHeight": scroll_height}) +assert: |menu_height| < |window_height| && |scroll_height| > |window_height| + +// We scroll to the last element of the menu. +scroll-to: "#settings .setting-line:last-of-type input" +// The item should be visible now, and so the Y scroll value should have changed. +// Note: The `scrollTop` value will change if settings are added or removed. +assert-property: ("#settings .settings", {"scrollTop": 335}) + +// Now we open the help menu. +click: ".help-menu a" +wait-for: "#help" +// We ensure it's not scrolled down yet. +assert-property: ("#help .content", {"scrollTop": 0}) +// We ensure its height is smaller than the window's, but its content's height is bigger. +store-property: ("#help .content", {"offsetHeight": menu_height, "scrollHeight": scroll_height}) +assert: |menu_height| < |window_height| && |scroll_height| > |window_height| + +// We scroll to the last element of the menu. +scroll-to: "#help .infos > :last-child" +// The item should be visible now, and so the Y scroll value should have changed. +assert-property: ("#help .content", {"scrollTop": 339}) diff --git a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml index 342bd726694e..dbf80ae34912 100644 --- a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml +++ b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml @@ -1,6 +1,8 @@ // This test ensures that the "Auto-hide item contents for large items" setting is working as // expected. +include: "utils.goml" + // We need to disable this check because `trait.impl/test_docs/trait.Iterator.js` doesn't exist. fail-on-request-error: false @@ -9,8 +11,7 @@ define-function: ( [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-large-items": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#auto-hide-large-items", {"checked": |setting_attribute_value|}) assert-attribute: (".item-decl .type-contents-toggle", {"open": |toggle_attribute_value|}) } diff --git a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml index 02d4ce8855fd..89c1a8b0e98e 100644 --- a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml +++ b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml @@ -1,13 +1,14 @@ // This test ensures that the "Auto-hide item methods' documentation" setting is working as // expected. +include: "utils.goml" + define-function: ( "check-setting", [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-method-docs": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#auto-hide-method-docs", {"checked": |setting_attribute_value|}) assert-attribute: (".toggle.method-toggle", {"open": |toggle_attribute_value|}) } diff --git a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml index 4af1e829b31c..81c26bfb7f3a 100644 --- a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml +++ b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml @@ -1,12 +1,13 @@ // Checks that the setting "auto hide trait implementations" is working as expected. +include: "utils.goml" + define-function: ( "check-setting", [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-trait-implementations": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#auto-hide-trait-implementations", {"checked": |setting_attribute_value|}) assert-attribute: ("#trait-implementations-list > details", {"open": |toggle_attribute_value|}, ALL) } diff --git a/tests/rustdoc-gui/setting-go-to-only-result.goml b/tests/rustdoc-gui/setting-go-to-only-result.goml index 5a9c81e0b836..72c1e2bf59ca 100644 --- a/tests/rustdoc-gui/setting-go-to-only-result.goml +++ b/tests/rustdoc-gui/setting-go-to-only-result.goml @@ -1,12 +1,14 @@ -// Checks that the setting "Directly go to item in search if there is only one result " is working as expected. +// Checks that the setting "Directly go to item in search if there is only one result " is working +// as expected. + +include: "utils.goml" define-function: ( "check-setting", [storage_value, setting_attribute_value], block { assert-local-storage: {"rustdoc-go-to-only-result": |storage_value|} - click: "rustdoc-toolbar .settings-menu" - wait-for: "#settings" + call-function: ("open-settings-menu", {}) assert-property: ("#go-to-only-result", {"checked": |setting_attribute_value|}) } ) @@ -25,8 +27,7 @@ wait-for: "#search" assert-document-property: ({"URL": "/lib2/index.html"}, CONTAINS) // Now we change its value. -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) click: "#go-to-only-result" assert-local-storage: {"rustdoc-go-to-only-result": "true"} diff --git a/tests/rustdoc-gui/setting-hide-deprecated.goml b/tests/rustdoc-gui/setting-hide-deprecated.goml new file mode 100644 index 000000000000..0fefe00f9457 --- /dev/null +++ b/tests/rustdoc-gui/setting-hide-deprecated.goml @@ -0,0 +1,107 @@ +// Test that the "hide deprecated" setting is correctly handled. + +include: "utils.goml" + +go-to: "file://" + |DOC_PATH| + "/lib2/deprecated/index.html" +store-value: (deprecated_class, ".deprecated") + +// There should be two deprecated items listed on the module page: +// `DeprecatedStruct` and `DeprecatedTrait`. +assert-count: ("dt" + |deprecated_class|, 2) +// `DeprecatedStruct` and `DeprecatedTrait` should be displayed for now. +assert-css: ("dt" + |deprecated_class|, {"display": "block"}, ALL) + +// We enable the "hide deprecated items" setting. +call-function: ("open-settings-menu", {}) +click: "#hide-deprecated-items" +// None of them should be displayed anymore. +wait-for-css: ("dt" + |deprecated_class|, {"display": "none"}, ALL) + +// We disable the setting. +click: "#hide-deprecated-items" +// All of them should be displayed back. +wait-for-css: ("dt" + |deprecated_class|, {"display": "block"}, ALL) + +// Now we go to a trait with a deprecated method and a deprecated associated const. +go-to: "file://" + |DOC_PATH| + "/lib2/deprecated/trait.NormalTrait.html" + +// There should be two deprecated items. +assert-count: ("details" + |deprecated_class|, 2) +// They should be displayed for now. +assert-css: ("details" + |deprecated_class|, {"display": "block"}, ALL) + +// We enable the "hide deprecated items" setting. +call-function: ("open-settings-menu", {}) +click: "#hide-deprecated-items" + +// They shouldn't be displayed anymore. +wait-for-css: ("details" + |deprecated_class|, {"display": "none"}, ALL) + +// We disable the setting. +click: "#hide-deprecated-items" +// All of them should be displayed back. +wait-for-css: ("details" + |deprecated_class|, {"display": "block"}, ALL) + +// We now go to a struct with a deprecated method which implements a deprecated trait and a trait +// with deprecated associated items. +go-to: "file://" + |DOC_PATH| + "/lib2/deprecated/struct.NonDeprecatedStruct.html" + +// There should be five deprecated items (six minus one "future" deprecated)... +assert-count: ("details" + |deprecated_class|, 5) +// One of which being a deprecated impl because the trait itself is deprecated. +assert-count: ("details.implementors-toggle" + |deprecated_class|, 1) +// And another has `since = "TBD"` and should NOT have the `deprecated` class. +assert: "details:not(" + |deprecated_class| + ") #method\.future_deprecated_fn" +// They should all be displayed for now. +assert-css: ("details" + |deprecated_class|, {"display": "block"}, ALL) + +// We enable the "hide deprecated items" setting. +call-function: ("open-settings-menu", {}) +click: "#hide-deprecated-items" + +// They shouldn't be displayed anymore. +wait-for-css: ("details" + |deprecated_class|, {"display": "none"}, ALL) + +// We disable the setting. +click: "#hide-deprecated-items" +// All of them should be displayed back. +wait-for-css: ("details" + |deprecated_class|, {"display": "block"}, ALL) + +// And now we check with the search results. +call-function: ("perform-search", {"query": "deprecated::depr"}) +// There should be at least 7 results. +store-count: ("#results ul.search-results.active > a", nb_search_results) +assert: |nb_search_results| >= 7 +// There should be at least 5 deprecated items. +store-count: ("#results ul.search-results.active > a" + |deprecated_class|, nb_deprecated_results) +assert: |nb_search_results| >= 5 +// Deprecated items should all be displayed. +assert-css: ("#results ul.search-results.active > a" + |deprecated_class|, {"display": "grid"}, ALL) +// The "X deprecated items hidden by setting" element should not be displayed. +assert-text: ( + "#results ul.search-results.active .deprecated-count", + "5 deprecated items hidden by setting", +) +assert-css: ("#results ul.search-results.active .deprecated-count", {"display": "none"}) +// We enable the "hide deprecated items" setting. +call-function: ("open-settings-menu", {}) +click: "#hide-deprecated-items" +// None of them should be displayed anymore. +wait-for-css: ( + "#results ul.search-results.active > a" + |deprecated_class|, + {"display": "none"}, + ALL, +) +// The "X deprecated items hidden by setting" element should be displayed. +assert-css: ("#results ul.search-results.active .deprecated-count", {"display": "block"}) + +// Finally we check that the future deprecated item doesn't have the deprecated class in the search +// and therefore isn't impacted by the setting. +call-function: ("perform-search", {"query": '"future_deprecated_fn"'}) +assert-text: ( + "#results ul.search-results.active > a:not(" + |deprecated_class| + ") .path", + " lib2::deprecated::NonDeprecatedStruct::future_deprecated_fn", +) +// The "X deprecated items hidden by setting" element should now be empty, and therefore not displayed. +assert-text: ("#results ul.search-results.active .deprecated-count", "") +assert-css: ("#results ul.search-results.active .deprecated-count", {"display": "none"}) diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index 7a163103b5ab..85994be468d3 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -1,20 +1,18 @@ // This test ensures that the settings menu display is working as expected and that // the settings page is also rendered as expected. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" show-text: true // needed when we check for colors below. // First, we check that the settings page doesn't exist. assert-false: "#settings" -// We now click on the settings button. -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) // Store the line margin to compare with the settings.html later. store-css: (".setting-line", {"margin": setting_line_margin}) // Let's close it by clicking on the same button. -click: "rustdoc-toolbar .settings-menu" -wait-for-css: ("#settings", {"display": "none"}) +call-function: ("close-settings-menu", {}) // Let's check that pressing "ESCAPE" is closing it. click: "rustdoc-toolbar .settings-menu" @@ -28,8 +26,7 @@ write: "test" // To be SURE that the search will be run. press-key: 'Enter' wait-for: "#alternative-display #search" -click: "rustdoc-toolbar .settings-menu" -wait-for-css: ("#settings", {"display": "block"}) +call-function: ("open-settings-menu", {}) // Ensure that the search is still displayed. wait-for: "#alternative-display #search" assert: "#main-content.hidden" @@ -41,8 +38,7 @@ set-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false" // We reload the page so the local storage settings are being used. reload: -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) // We check that the "Use system theme" is disabled. assert-property: ("#theme-system-preference", {"checked": "false"}) diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index f828516d7624..3183650b555a 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -49,7 +49,7 @@ assert-property: ("rustdoc-topbar", {"clientHeight": "45"}) // so the target is not obscured by the topbar. click: ".sidebar-menu-toggle" click: ".sidebar-elems section .block li > a" -assert-position: ("#method\.must_use", {"y": 46}) +assert-position: ("#method\.must_use", {"y": 45}) // Check that the bottom-most item on the sidebar menu can be scrolled fully into view. click: ".sidebar-menu-toggle" @@ -65,8 +65,7 @@ define-function: ( "check-colors", [theme, color, background], block { - call-function: ("switch-theme-mobile", {"theme": |theme|}) - reload: + call-function: ("switch-theme", {"theme": |theme|}) // Open the sidebar menu. click: ".sidebar-menu-toggle" @@ -86,13 +85,3 @@ call-function: ("check-colors", { "color": "#c5c5c5", "background": "#14191f", }) -call-function: ("check-colors", { - "theme": "dark", - "color": "#ddd", - "background": "#505050", -}) -call-function: ("check-colors", { - "theme": "light", - "color": "black", - "background": "#F5F5F5", -}) diff --git a/tests/rustdoc-gui/sidebar-resize-close-popover.goml b/tests/rustdoc-gui/sidebar-resize-close-popover.goml index d3fea9b0f400..ac8f7e9c65fa 100644 --- a/tests/rustdoc-gui/sidebar-resize-close-popover.goml +++ b/tests/rustdoc-gui/sidebar-resize-close-popover.goml @@ -1,9 +1,9 @@ // Checks sidebar resizing close the Settings popover +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" assert-property: (".sidebar", {"clientWidth": "199"}) show-text: true -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) // normal resizing drag-and-drop: ((205, 100), (185, 100)) @@ -12,8 +12,7 @@ assert-css: ("#settings", {"display": "none"}) // Now same thing, but for source code go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) assert-property: (".sidebar", {"clientWidth": "49"}) drag-and-drop: ((52, 100), (185, 100)) diff --git a/tests/rustdoc-gui/sidebar-resize-setting.goml b/tests/rustdoc-gui/sidebar-resize-setting.goml index a4572c670f81..132f5f387b29 100644 --- a/tests/rustdoc-gui/sidebar-resize-setting.goml +++ b/tests/rustdoc-gui/sidebar-resize-setting.goml @@ -1,11 +1,11 @@ // Checks sidebar resizing stays synced with the setting +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" assert-property: (".sidebar", {"clientWidth": "199"}) show-text: true // Verify that the "hide" option is unchecked -click: "rustdoc-toolbar .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) assert-css: ("#settings", {"display": "block"}) assert-property: ("#hide-sidebar", {"checked": "false"}) press-key: "Escape" diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index 99810cd78633..d2b667b498bc 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -141,7 +141,7 @@ click: "#sidebar-button" wait-for-css: (".src .sidebar > *", {"visibility": "hidden"}) // We scroll to line 117 to change the scroll position. scroll-to: '//*[@id="117"]' -store-value: (y_offset, "2567") +store-value: (y_offset, "2568") assert-window-property: {"pageYOffset": |y_offset|} // Expanding the sidebar... click: "#sidebar-button" diff --git a/tests/rustdoc-gui/skip-navigation.goml b/tests/rustdoc-gui/skip-navigation.goml new file mode 100644 index 000000000000..50cb2d38b3e0 --- /dev/null +++ b/tests/rustdoc-gui/skip-navigation.goml @@ -0,0 +1,19 @@ +// This test ensures that the "Skip to main content" link works correctly +// for keyboard navigation (WCAG 2.4.1 compliance). +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" + +// The skip link should be hidden initially (positioned off-screen above viewport) +store-position: (".skip-main-content", {"y": y_before}) +store-size: (".skip-main-content", {"height": height_before}) +assert: |y_before| + |height_before| < 0 + +// The skip link should be the first focusable element when pressing Tab +press-key: "Tab" +wait-for: ".skip-main-content:focus" + +// When focused, the link should be visible (top: 0px) +assert-css: (".skip-main-content:focus", {"top": "0px"}) + +// Pressing Enter on the skip link should move focus to main content +press-key: "Enter" +wait-for: "#main-content:focus" diff --git a/tests/rustdoc-gui/source-code-wrapping.goml b/tests/rustdoc-gui/source-code-wrapping.goml index c1fc2835c89a..6dc56672da80 100644 --- a/tests/rustdoc-gui/source-code-wrapping.goml +++ b/tests/rustdoc-gui/source-code-wrapping.goml @@ -1,4 +1,5 @@ // Checks that the interactions with the source code pages are working as expected. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html" show-text: true set-window-size: (1000, 1000) @@ -13,8 +14,7 @@ define-function: ( ) store-size: (".rust code", {"width": width, "height": height}) -click: "main .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) call-function: ("click-code-wrapping", {"expected": "true"}) wait-for-size-false: (".rust code", {"width": |width|, "height": |height|}) store-size: (".rust code", {"width": new_width, "height": new_height}) @@ -28,8 +28,7 @@ assert-size: (".rust code", {"width": |width|, "height": |height|}) // Now let's check in docs code examples. go-to: "file://" + |DOC_PATH| + "/test_docs/trait_bounds/index.html" -click: "main .settings-menu" -wait-for: "#settings" +call-function: ("open-settings-menu", {}) store-property: (".example-wrap .rust code", {"scrollWidth": rust_width, "scrollHeight": rust_height}) store-property: (".example-wrap .language-text code", {"scrollWidth": txt_width, "scrollHeight": txt_height}) diff --git a/tests/rustdoc-gui/src/lib2/implementors/lib.rs b/tests/rustdoc-gui/src/lib2/implementors/lib.rs index 2842ac50dc1e..f08182003927 100644 --- a/tests/rustdoc-gui/src/lib2/implementors/lib.rs +++ b/tests/rustdoc-gui/src/lib2/implementors/lib.rs @@ -1,3 +1,5 @@ +#![feature(negative_impls)] + pub trait Whatever { type Foo; @@ -5,11 +7,14 @@ pub trait Whatever { } pub struct Struct; +pub struct Struct2; impl Whatever for Struct { type Foo = u8; } +impl !Whatever for Struct2 {} + impl http::HttpTrait for Struct {} mod traits { diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs index 400488cbe857..1367b17b37b2 100644 --- a/tests/rustdoc-gui/src/lib2/lib.rs +++ b/tests/rustdoc-gui/src/lib2/lib.rs @@ -1,6 +1,7 @@ // ignore-tidy-linelength #![feature(doc_cfg)] +#![feature(negative_impls)] pub mod another_folder; pub mod another_mod; @@ -60,6 +61,8 @@ impl implementors::Whatever for Foo { type Foo = u32; } +impl !implementors::Whatever for StructToImplOnReexport {} + #[doc(inline)] pub use implementors::TraitToReexport; @@ -365,3 +368,46 @@ impl std::ops::Deref for Derefer { &self.0 } } + +pub mod deprecated { + #[deprecated(since = "1.26.0", note = "deprecated")] + pub struct DeprecatedStruct; + + pub struct NonDeprecatedStruct; + + pub trait NormalTrait { + #[deprecated(since = "1.26.0", note = "deprecated")] + /// doc + const X: usize = 12; + + #[deprecated(since = "1.26.0", note = "deprecated")] + /// doc + fn normal_deprecated_fn(); + } + + #[deprecated(since = "1.26.0", note = "deprecated")] + pub trait DeprecatedTrait { + fn depr_deprecated_fn(); + } + + impl NonDeprecatedStruct { + #[deprecated(since = "1.26.0", note = "deprecated")] + /// doc + pub fn deprecated_fn() {} + + /// doc + pub fn non_deprecated_fn() {} + + #[deprecated(since = "TBD", note = "deprecated")] + /// doc + pub fn future_deprecated_fn() {} + } + + impl NormalTrait for NonDeprecatedStruct { + fn normal_deprecated_fn() {} + } + + impl DeprecatedTrait for NonDeprecatedStruct { + fn depr_deprecated_fn() {} + } +} diff --git a/tests/rustdoc-gui/src/staged_api/lib.rs b/tests/rustdoc-gui/src/staged_api/lib.rs index 9b5ad1c5ff32..7304d2f02ab1 100644 --- a/tests/rustdoc-gui/src/staged_api/lib.rs +++ b/tests/rustdoc-gui/src/staged_api/lib.rs @@ -4,6 +4,10 @@ #![stable(feature = "some_feature", since = "1.3.5")] #![doc(rust_logo)] +pub trait X { + fn vroum(); +} + #[stable(feature = "some_feature", since = "1.3.5")] pub struct Foo {} @@ -13,3 +17,7 @@ impl Foo { #[stable(feature = "some_other_feature", since = "1.3.6")] pub fn yo() {} } + +impl X for Foo { + fn vroum() {} +} diff --git a/tests/rustdoc-gui/theme-change.goml b/tests/rustdoc-gui/theme-change.goml index 3860596e3433..14b32baac57e 100644 --- a/tests/rustdoc-gui/theme-change.goml +++ b/tests/rustdoc-gui/theme-change.goml @@ -7,8 +7,7 @@ store-value: (background_light, "white") store-value: (background_dark, "#353535") store-value: (background_ayu, "#0f1419") -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-ayu" +call-function: ("open-settings-menu", {}) click: "#theme-ayu" // should be the ayu theme so let's check the color. wait-for-css: ("body", { "background-color": |background_ayu| }) @@ -22,10 +21,6 @@ click: "#theme-dark" wait-for-css: ("body", { "background-color": |background_dark| }) assert-local-storage: { "rustdoc-theme": "dark" } -set-local-storage: { - "rustdoc-preferred-light-theme": "light", - "rustdoc-preferred-dark-theme": "light", -} go-to: "file://" + |DOC_PATH| + "/settings.html" wait-for: "#settings" @@ -75,8 +70,7 @@ store-value: (background_dark, "#353535") store-value: (background_ayu, "#0f1419") store-value: (background_custom_theme, "red") -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-ayu" +call-function: ("open-settings-menu", {}) click: "#theme-ayu" // should be the ayu theme so let's check the color. wait-for-css: ("body", { "background-color": |background_ayu| }) diff --git a/tests/rustdoc-gui/theme-defaults.goml b/tests/rustdoc-gui/theme-defaults.goml index 12c17166e874..b7ba64a4adaa 100644 --- a/tests/rustdoc-gui/theme-defaults.goml +++ b/tests/rustdoc-gui/theme-defaults.goml @@ -1,7 +1,7 @@ // Ensure that the theme picker always starts with the actual defaults. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-system-preference" +call-function: ("open-settings-menu", {}) assert: "#theme-system-preference:checked" assert: "#preferred-light-theme-light:checked" assert: "#preferred-dark-theme-dark:checked" @@ -16,8 +16,7 @@ set-local-storage: { "rustdoc-theme": "ayu" } go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -click: "rustdoc-toolbar .settings-menu" -wait-for: "#theme-system-preference" +call-function: ("open-settings-menu", {}) assert: "#theme-system-preference:checked" assert: "#preferred-light-theme-light:checked" assert-false: "#preferred-dark-theme-dark:checked" diff --git a/tests/rustdoc-gui/utils.goml b/tests/rustdoc-gui/utils.goml index e13aef6712f3..53ea91b929fe 100644 --- a/tests/rustdoc-gui/utils.goml +++ b/tests/rustdoc-gui/utils.goml @@ -1,53 +1,117 @@ // This file contains code to be re-used by other tests. + +define-function: ( + "click-settings-button", + [], + block { + store-count: ("rustdoc-topbar", __topbar_count) + store-value: (__topbar_display, "none") + // The `rustdoc-topbar` element is created with JS when the window size is below a given + // size, however if the window size gets bigger again, the element isn't deleted, just + // hidden, so we need to check for both that it exists and is visible. + if: (|__topbar_count| != 0, block { + store-css: ("rustdoc-topbar", {"display": __topbar_display}) + }) + + // Open the settings menu. + if: (|__topbar_display| != "none", block { + // In mobile mode, this is instead the "topbar" the settings button is located into. + click: "rustdoc-topbar .settings-menu" + }) + else: block { + // We're not in mobile mode so clicking on the "normal" sidebar. + click: "rustdoc-toolbar .settings-menu" + } + } +) + +define-function: ( + "open-settings-menu", + [], + block { + store-count: ("#settings", nb_settings_menu) + if: (|nb_settings_menu| != 0, block { + store-css: ("#settings", {"display": settings_display}) + }) + else: block { + store-value: (settings_display, "none") + } + if: (|settings_display| != "block", block { + call-function: ("click-settings-button", {}) + // Wait for the popover to appear... + wait-for-css: ("#settings", {"display": "block"}) + }) + } +) + +define-function: ( + "close-settings-menu", + [], + block { + store-count: ("#settings", nb_settings_menu) + if: (|nb_settings_menu| != 0, block { + store-css: ("#settings", {"display": settings_display}) + }) + else: block { + store-value: (settings_display, "block") + } + if: (|settings_display| == "block", block { + call-function: ("click-settings-button", {}) + // Wait for the popover to disappear... + wait-for-css-false: ("#settings", {"display": "block"}) + }) + } +) + define-function: ( "switch-theme", [theme], block { // Set the theme. - // Open the settings menu. - click: "rustdoc-toolbar .settings-menu" - // Wait for the popover to appear... - wait-for: "#settings" + call-function: ("open-settings-menu", {}) // Change the setting. click: "#theme-"+ |theme| - // Close the popover. - click: "rustdoc-toolbar .settings-menu" + call-function: ("close-settings-menu", {}) // Ensure that the local storage was correctly updated. assert-local-storage: {"rustdoc-theme": |theme|} }, ) define-function: ( - "switch-theme-mobile", - [theme], + "open-search", + [], block { - // Set the theme. - // Open the settings menu. - click: "rustdoc-topbar .settings-menu" - // Wait for the popover to appear... - wait-for: "#settings" - // Change the setting. - click: "#theme-"+ |theme| - // Close the popover. - click: "rustdoc-topbar .settings-menu" - // Ensure that the local storage was correctly updated. - assert-local-storage: {"rustdoc-theme": |theme|} - }, + store-count: (".search-input", __search_input_count) + if: (|__search_input_count| != 0, block { + store-css: ("#alternative-display", {"display": __search_input_display}) + }) + else: block { + // Block requests with doubled `//`. + // Amazon S3 doesn't support them, but other web hosts do, + // and so do file:/// URLs, which means we need to block + // it here if we want to avoid breaking the main docs site. + // https://github.com/rust-lang/rust/issues/145646 + block-network-request: "file://*//*" + store-value: (__search_input_display, "none") + } + + if: (|__search_input_display| == "none", block { + // Open search + click: "#search-button" + wait-for: ".search-input" + }) + } ) define-function: ( "perform-search", [query], block { - // Block requests with doubled `//`. - // Amazon S3 doesn't support them, but other web hosts do, - // and so do file:/// URLs, which means we need to block - // it here if we want to avoid breaking the main docs site. - // https://github.com/rust-lang/rust/issues/145646 - block-network-request: "file://*//*" - // Perform search - click: "#search-button" - wait-for: ".search-input" + call-function: ("open-search", {}) + // We empty the search input in case it wasn't empty. + set-property: (".search-input", {"value": ""}) + focus: ".search-input" + // We write the actual query. write-into: (".search-input", |query|) press-key: 'Enter' // wait for the search to start @@ -56,3 +120,15 @@ define-function: ( wait-for-false: "#search-tabs .count.loading" } ) + +define-function: ( + "switch-line-numbers-setting", + [expected_status], + block { + call-function: ("open-settings-menu", {}) + // We change the line numbers setting. + click: "#line-numbers" + call-function: ("close-settings-menu", {}) + assert-local-storage: {"rustdoc-line-numbers": |expected_status|} + } +) diff --git a/tests/rustdoc/all.rs b/tests/rustdoc-html/all.rs similarity index 100% rename from tests/rustdoc/all.rs rename to tests/rustdoc-html/all.rs diff --git a/tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs b/tests/rustdoc-html/anchors/anchor-id-duplicate-method-name-25001.rs similarity index 100% rename from tests/rustdoc/anchors/anchor-id-duplicate-method-name-25001.rs rename to tests/rustdoc-html/anchors/anchor-id-duplicate-method-name-25001.rs diff --git a/tests/rustdoc/anchors/anchor-id-trait-method-15169.rs b/tests/rustdoc-html/anchors/anchor-id-trait-method-15169.rs similarity index 100% rename from tests/rustdoc/anchors/anchor-id-trait-method-15169.rs rename to tests/rustdoc-html/anchors/anchor-id-trait-method-15169.rs diff --git a/tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs b/tests/rustdoc-html/anchors/anchor-id-trait-tymethod-28478.rs similarity index 100% rename from tests/rustdoc/anchors/anchor-id-trait-tymethod-28478.rs rename to tests/rustdoc-html/anchors/anchor-id-trait-tymethod-28478.rs diff --git a/tests/rustdoc/anchors/anchors.no_const_anchor.html b/tests/rustdoc-html/anchors/anchors.no_const_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_const_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_const_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_const_anchor2.html b/tests/rustdoc-html/anchors/anchors.no_const_anchor2.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_const_anchor2.html rename to tests/rustdoc-html/anchors/anchors.no_const_anchor2.html diff --git a/tests/rustdoc/anchors/anchors.no_method_anchor.html b/tests/rustdoc-html/anchors/anchors.no_method_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_method_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_method_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_trait_method_anchor.html b/tests/rustdoc-html/anchors/anchors.no_trait_method_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_trait_method_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_trait_method_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_tymethod_anchor.html b/tests/rustdoc-html/anchors/anchors.no_tymethod_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_tymethod_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_tymethod_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_type_anchor.html b/tests/rustdoc-html/anchors/anchors.no_type_anchor.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_type_anchor.html rename to tests/rustdoc-html/anchors/anchors.no_type_anchor.html diff --git a/tests/rustdoc/anchors/anchors.no_type_anchor2.html b/tests/rustdoc-html/anchors/anchors.no_type_anchor2.html similarity index 100% rename from tests/rustdoc/anchors/anchors.no_type_anchor2.html rename to tests/rustdoc-html/anchors/anchors.no_type_anchor2.html diff --git a/tests/rustdoc/anchors/anchors.rs b/tests/rustdoc-html/anchors/anchors.rs similarity index 100% rename from tests/rustdoc/anchors/anchors.rs rename to tests/rustdoc-html/anchors/anchors.rs diff --git a/tests/rustdoc/anchors/auxiliary/issue-86620-1.rs b/tests/rustdoc-html/anchors/auxiliary/issue-86620-1.rs similarity index 100% rename from tests/rustdoc/anchors/auxiliary/issue-86620-1.rs rename to tests/rustdoc-html/anchors/auxiliary/issue-86620-1.rs diff --git a/tests/rustdoc/anchors/disambiguate-anchors-32890.rs b/tests/rustdoc-html/anchors/disambiguate-anchors-32890.rs similarity index 100% rename from tests/rustdoc/anchors/disambiguate-anchors-32890.rs rename to tests/rustdoc-html/anchors/disambiguate-anchors-32890.rs diff --git a/tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs b/tests/rustdoc-html/anchors/disambiguate-anchors-header-29449.rs similarity index 100% rename from tests/rustdoc/anchors/disambiguate-anchors-header-29449.rs rename to tests/rustdoc-html/anchors/disambiguate-anchors-header-29449.rs diff --git a/tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs b/tests/rustdoc-html/anchors/method-anchor-in-blanket-impl-86620.rs similarity index 100% rename from tests/rustdoc/anchors/method-anchor-in-blanket-impl-86620.rs rename to tests/rustdoc-html/anchors/method-anchor-in-blanket-impl-86620.rs diff --git a/tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs b/tests/rustdoc-html/anchors/trait-impl-items-links-and-anchors.rs similarity index 100% rename from tests/rustdoc/anchors/trait-impl-items-links-and-anchors.rs rename to tests/rustdoc-html/anchors/trait-impl-items-links-and-anchors.rs diff --git a/tests/rustdoc/anon-fn-params.rs b/tests/rustdoc-html/anon-fn-params.rs similarity index 100% rename from tests/rustdoc/anon-fn-params.rs rename to tests/rustdoc-html/anon-fn-params.rs diff --git a/tests/rustdoc/anonymous-lifetime.rs b/tests/rustdoc-html/anonymous-lifetime.rs similarity index 100% rename from tests/rustdoc/anonymous-lifetime.rs rename to tests/rustdoc-html/anonymous-lifetime.rs diff --git a/tests/rustdoc/array-links.link_box_generic.html b/tests/rustdoc-html/array-links.link_box_generic.html similarity index 100% rename from tests/rustdoc/array-links.link_box_generic.html rename to tests/rustdoc-html/array-links.link_box_generic.html diff --git a/tests/rustdoc/array-links.link_box_u32.html b/tests/rustdoc-html/array-links.link_box_u32.html similarity index 100% rename from tests/rustdoc/array-links.link_box_u32.html rename to tests/rustdoc-html/array-links.link_box_u32.html diff --git a/tests/rustdoc/array-links.link_slice_generic.html b/tests/rustdoc-html/array-links.link_slice_generic.html similarity index 100% rename from tests/rustdoc/array-links.link_slice_generic.html rename to tests/rustdoc-html/array-links.link_slice_generic.html diff --git a/tests/rustdoc/array-links.link_slice_u32.html b/tests/rustdoc-html/array-links.link_slice_u32.html similarity index 100% rename from tests/rustdoc/array-links.link_slice_u32.html rename to tests/rustdoc-html/array-links.link_slice_u32.html diff --git a/tests/rustdoc/array-links.rs b/tests/rustdoc-html/array-links.rs similarity index 100% rename from tests/rustdoc/array-links.rs rename to tests/rustdoc-html/array-links.rs diff --git a/tests/rustdoc/asm-foreign.rs b/tests/rustdoc-html/asm-foreign.rs similarity index 100% rename from tests/rustdoc/asm-foreign.rs rename to tests/rustdoc-html/asm-foreign.rs diff --git a/tests/rustdoc/asm-foreign2.rs b/tests/rustdoc-html/asm-foreign2.rs similarity index 100% rename from tests/rustdoc/asm-foreign2.rs rename to tests/rustdoc-html/asm-foreign2.rs diff --git a/tests/rustdoc/asref-for-and-of-local-82465.rs b/tests/rustdoc-html/asref-for-and-of-local-82465.rs similarity index 100% rename from tests/rustdoc/asref-for-and-of-local-82465.rs rename to tests/rustdoc-html/asref-for-and-of-local-82465.rs diff --git a/tests/rustdoc/assoc/assoc-fns.rs b/tests/rustdoc-html/assoc/assoc-fns.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-fns.rs rename to tests/rustdoc-html/assoc/assoc-fns.rs diff --git a/tests/rustdoc/assoc/assoc-item-cast.rs b/tests/rustdoc-html/assoc/assoc-item-cast.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-item-cast.rs rename to tests/rustdoc-html/assoc/assoc-item-cast.rs diff --git a/tests/rustdoc/assoc/assoc-type-bindings-20646.rs b/tests/rustdoc-html/assoc/assoc-type-bindings-20646.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-type-bindings-20646.rs rename to tests/rustdoc-html/assoc/assoc-type-bindings-20646.rs diff --git a/tests/rustdoc/assoc/assoc-types.rs b/tests/rustdoc-html/assoc/assoc-types.rs similarity index 100% rename from tests/rustdoc/assoc/assoc-types.rs rename to tests/rustdoc-html/assoc/assoc-types.rs diff --git a/tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc-html/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs rename to tests/rustdoc-html/assoc/auxiliary/cross-crate-hidden-assoc-trait-items.rs diff --git a/tests/rustdoc/assoc/auxiliary/issue-20646.rs b/tests/rustdoc-html/assoc/auxiliary/issue-20646.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/issue-20646.rs rename to tests/rustdoc-html/assoc/auxiliary/issue-20646.rs diff --git a/tests/rustdoc/assoc/auxiliary/issue-20727.rs b/tests/rustdoc-html/assoc/auxiliary/issue-20727.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/issue-20727.rs rename to tests/rustdoc-html/assoc/auxiliary/issue-20727.rs diff --git a/tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs b/tests/rustdoc-html/assoc/auxiliary/normalize-assoc-item.rs similarity index 100% rename from tests/rustdoc/assoc/auxiliary/normalize-assoc-item.rs rename to tests/rustdoc-html/assoc/auxiliary/normalize-assoc-item.rs diff --git a/tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs b/tests/rustdoc-html/assoc/cross-crate-hidden-assoc-trait-items.rs similarity index 100% rename from tests/rustdoc/assoc/cross-crate-hidden-assoc-trait-items.rs rename to tests/rustdoc-html/assoc/cross-crate-hidden-assoc-trait-items.rs diff --git a/tests/rustdoc/assoc/doc-assoc-item.rs b/tests/rustdoc-html/assoc/doc-assoc-item.rs similarity index 100% rename from tests/rustdoc/assoc/doc-assoc-item.rs rename to tests/rustdoc-html/assoc/doc-assoc-item.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bindings.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bindings.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bindings.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-deref.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bounds-deref.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-deref.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-index.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bounds-index.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds-index.rs diff --git a/tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs b/tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds.rs similarity index 100% rename from tests/rustdoc/assoc/inline-assoc-type-20727-bounds.rs rename to tests/rustdoc-html/assoc/inline-assoc-type-20727-bounds.rs diff --git a/tests/rustdoc/assoc/normalize-assoc-item.rs b/tests/rustdoc-html/assoc/normalize-assoc-item.rs similarity index 100% rename from tests/rustdoc/assoc/normalize-assoc-item.rs rename to tests/rustdoc-html/assoc/normalize-assoc-item.rs diff --git a/tests/rustdoc/async/async-fn-opaque-item.rs b/tests/rustdoc-html/async/async-fn-opaque-item.rs similarity index 100% rename from tests/rustdoc/async/async-fn-opaque-item.rs rename to tests/rustdoc-html/async/async-fn-opaque-item.rs diff --git a/tests/rustdoc/async/async-fn.rs b/tests/rustdoc-html/async/async-fn.rs similarity index 100% rename from tests/rustdoc/async/async-fn.rs rename to tests/rustdoc-html/async/async-fn.rs diff --git a/tests/rustdoc/async/async-move-doctest.rs b/tests/rustdoc-html/async/async-move-doctest.rs similarity index 100% rename from tests/rustdoc/async/async-move-doctest.rs rename to tests/rustdoc-html/async/async-move-doctest.rs diff --git a/tests/rustdoc/async/async-trait-sig.rs b/tests/rustdoc-html/async/async-trait-sig.rs similarity index 100% rename from tests/rustdoc/async/async-trait-sig.rs rename to tests/rustdoc-html/async/async-trait-sig.rs diff --git a/tests/rustdoc/async/async-trait.rs b/tests/rustdoc-html/async/async-trait.rs similarity index 100% rename from tests/rustdoc/async/async-trait.rs rename to tests/rustdoc-html/async/async-trait.rs diff --git a/tests/rustdoc/async/auxiliary/async-trait-dep.rs b/tests/rustdoc-html/async/auxiliary/async-trait-dep.rs similarity index 100% rename from tests/rustdoc/async/auxiliary/async-trait-dep.rs rename to tests/rustdoc-html/async/auxiliary/async-trait-dep.rs diff --git a/tests/rustdoc/attributes-2021-edition.rs b/tests/rustdoc-html/attributes-2021-edition.rs similarity index 100% rename from tests/rustdoc/attributes-2021-edition.rs rename to tests/rustdoc-html/attributes-2021-edition.rs diff --git a/tests/rustdoc/attributes-inlining-108281.rs b/tests/rustdoc-html/attributes-inlining-108281.rs similarity index 100% rename from tests/rustdoc/attributes-inlining-108281.rs rename to tests/rustdoc-html/attributes-inlining-108281.rs diff --git a/tests/rustdoc/attributes-re-export-2021-edition.rs b/tests/rustdoc-html/attributes-re-export-2021-edition.rs similarity index 100% rename from tests/rustdoc/attributes-re-export-2021-edition.rs rename to tests/rustdoc-html/attributes-re-export-2021-edition.rs diff --git a/tests/rustdoc/attributes-re-export.rs b/tests/rustdoc-html/attributes-re-export.rs similarity index 100% rename from tests/rustdoc/attributes-re-export.rs rename to tests/rustdoc-html/attributes-re-export.rs diff --git a/tests/rustdoc/attributes.rs b/tests/rustdoc-html/attributes.rs similarity index 100% rename from tests/rustdoc/attributes.rs rename to tests/rustdoc-html/attributes.rs diff --git a/tests/rustdoc/auto/auto-impl-for-trait.rs b/tests/rustdoc-html/auto/auto-impl-for-trait.rs similarity index 100% rename from tests/rustdoc/auto/auto-impl-for-trait.rs rename to tests/rustdoc-html/auto/auto-impl-for-trait.rs diff --git a/tests/rustdoc/auto/auto-impl-primitive.rs b/tests/rustdoc-html/auto/auto-impl-primitive.rs similarity index 100% rename from tests/rustdoc/auto/auto-impl-primitive.rs rename to tests/rustdoc-html/auto/auto-impl-primitive.rs diff --git a/tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs b/tests/rustdoc-html/auto/auto-trait-bounds-by-associated-type-50159.rs similarity index 88% rename from tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs rename to tests/rustdoc-html/auto/auto-trait-bounds-by-associated-type-50159.rs index 2803c4da437f..14981783e5f3 100644 --- a/tests/rustdoc/auto/auto-trait-bounds-by-associated-type-50159.rs +++ b/tests/rustdoc-html/auto/auto-trait-bounds-by-associated-type-50159.rs @@ -20,7 +20,8 @@ where //@ has - '//h3[@class="code-header"]' 'impl Send for Switchwhere ::Item: Send' //@ has - '//h3[@class="code-header"]' 'impl Sync for Switchwhere ::Item: Sync' //@ count - '//*[@id="implementations-list"]//*[@class="impl"]' 0 -//@ count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6 +//@ count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 7 +// The number here will need updating when new auto traits are added: ^ pub struct Switch { pub inner: ::Item2, } diff --git a/tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs b/tests/rustdoc-html/auto/auto-trait-bounds-inference-variables-54705.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-bounds-inference-variables-54705.rs rename to tests/rustdoc-html/auto/auto-trait-bounds-inference-variables-54705.rs diff --git a/tests/rustdoc/auto/auto-trait-bounds-where-51236.rs b/tests/rustdoc-html/auto/auto-trait-bounds-where-51236.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-bounds-where-51236.rs rename to tests/rustdoc-html/auto/auto-trait-bounds-where-51236.rs diff --git a/tests/rustdoc/auto/auto-trait-negative-impl-55321.rs b/tests/rustdoc-html/auto/auto-trait-negative-impl-55321.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-negative-impl-55321.rs rename to tests/rustdoc-html/auto/auto-trait-negative-impl-55321.rs diff --git a/tests/rustdoc/auto/auto-trait-not-send.rs b/tests/rustdoc-html/auto/auto-trait-not-send.rs similarity index 100% rename from tests/rustdoc/auto/auto-trait-not-send.rs rename to tests/rustdoc-html/auto/auto-trait-not-send.rs diff --git a/tests/rustdoc/auto/auto-traits.rs b/tests/rustdoc-html/auto/auto-traits.rs similarity index 100% rename from tests/rustdoc/auto/auto-traits.rs rename to tests/rustdoc-html/auto/auto-traits.rs diff --git a/tests/rustdoc/auto/auto_aliases.rs b/tests/rustdoc-html/auto/auto_aliases.rs similarity index 100% rename from tests/rustdoc/auto/auto_aliases.rs rename to tests/rustdoc-html/auto/auto_aliases.rs diff --git a/tests/rustdoc/auto/auxiliary/auto-traits.rs b/tests/rustdoc-html/auto/auxiliary/auto-traits.rs similarity index 100% rename from tests/rustdoc/auto/auxiliary/auto-traits.rs rename to tests/rustdoc-html/auto/auxiliary/auto-traits.rs diff --git a/tests/rustdoc/auxiliary/all-item-types.rs b/tests/rustdoc-html/auxiliary/all-item-types.rs similarity index 100% rename from tests/rustdoc/auxiliary/all-item-types.rs rename to tests/rustdoc-html/auxiliary/all-item-types.rs diff --git a/tests/rustdoc/auxiliary/cross_crate_generic_typedef.rs b/tests/rustdoc-html/auxiliary/cross_crate_generic_typedef.rs similarity index 100% rename from tests/rustdoc/auxiliary/cross_crate_generic_typedef.rs rename to tests/rustdoc-html/auxiliary/cross_crate_generic_typedef.rs diff --git a/tests/rustdoc/auxiliary/elided-lifetime.rs b/tests/rustdoc-html/auxiliary/elided-lifetime.rs similarity index 100% rename from tests/rustdoc/auxiliary/elided-lifetime.rs rename to tests/rustdoc-html/auxiliary/elided-lifetime.rs diff --git a/tests/rustdoc/auxiliary/empty.rs b/tests/rustdoc-html/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/auxiliary/empty.rs rename to tests/rustdoc-html/auxiliary/empty.rs diff --git a/tests/rustdoc/auxiliary/enum-primitive.rs b/tests/rustdoc-html/auxiliary/enum-primitive.rs similarity index 100% rename from tests/rustdoc/auxiliary/enum-primitive.rs rename to tests/rustdoc-html/auxiliary/enum-primitive.rs diff --git a/tests/rustdoc/auxiliary/ext-anon-fn-params.rs b/tests/rustdoc-html/auxiliary/ext-anon-fn-params.rs similarity index 100% rename from tests/rustdoc/auxiliary/ext-anon-fn-params.rs rename to tests/rustdoc-html/auxiliary/ext-anon-fn-params.rs diff --git a/tests/rustdoc/auxiliary/ext-repr.rs b/tests/rustdoc-html/auxiliary/ext-repr.rs similarity index 100% rename from tests/rustdoc/auxiliary/ext-repr.rs rename to tests/rustdoc-html/auxiliary/ext-repr.rs diff --git a/tests/rustdoc/auxiliary/ext-trait-aliases.rs b/tests/rustdoc-html/auxiliary/ext-trait-aliases.rs similarity index 100% rename from tests/rustdoc/auxiliary/ext-trait-aliases.rs rename to tests/rustdoc-html/auxiliary/ext-trait-aliases.rs diff --git a/tests/rustdoc/auxiliary/inline-default-methods.rs b/tests/rustdoc-html/auxiliary/inline-default-methods.rs similarity index 100% rename from tests/rustdoc/auxiliary/inline-default-methods.rs rename to tests/rustdoc-html/auxiliary/inline-default-methods.rs diff --git a/tests/rustdoc/auxiliary/issue-106421-force-unstable.rs b/tests/rustdoc-html/auxiliary/issue-106421-force-unstable.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-106421-force-unstable.rs rename to tests/rustdoc-html/auxiliary/issue-106421-force-unstable.rs diff --git a/tests/rustdoc/auxiliary/issue-13698.rs b/tests/rustdoc-html/auxiliary/issue-13698.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-13698.rs rename to tests/rustdoc-html/auxiliary/issue-13698.rs diff --git a/tests/rustdoc/auxiliary/issue-19190-3.rs b/tests/rustdoc-html/auxiliary/issue-19190-3.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-19190-3.rs rename to tests/rustdoc-html/auxiliary/issue-19190-3.rs diff --git a/tests/rustdoc/auxiliary/issue-61592.rs b/tests/rustdoc-html/auxiliary/issue-61592.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-61592.rs rename to tests/rustdoc-html/auxiliary/issue-61592.rs diff --git a/tests/rustdoc/auxiliary/issue-99221-aux.rs b/tests/rustdoc-html/auxiliary/issue-99221-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-99221-aux.rs rename to tests/rustdoc-html/auxiliary/issue-99221-aux.rs diff --git a/tests/rustdoc/auxiliary/issue-99734-aux.rs b/tests/rustdoc-html/auxiliary/issue-99734-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-99734-aux.rs rename to tests/rustdoc-html/auxiliary/issue-99734-aux.rs diff --git a/tests/rustdoc/auxiliary/jump-to-def-res-err-handling-aux.rs b/tests/rustdoc-html/auxiliary/jump-to-def-res-err-handling-aux.rs similarity index 100% rename from tests/rustdoc/auxiliary/jump-to-def-res-err-handling-aux.rs rename to tests/rustdoc-html/auxiliary/jump-to-def-res-err-handling-aux.rs diff --git a/tests/rustdoc/auxiliary/masked.rs b/tests/rustdoc-html/auxiliary/masked.rs similarity index 100% rename from tests/rustdoc/auxiliary/masked.rs rename to tests/rustdoc-html/auxiliary/masked.rs diff --git a/tests/rustdoc/auxiliary/mod-stackoverflow.rs b/tests/rustdoc-html/auxiliary/mod-stackoverflow.rs similarity index 100% rename from tests/rustdoc/auxiliary/mod-stackoverflow.rs rename to tests/rustdoc-html/auxiliary/mod-stackoverflow.rs diff --git a/tests/rustdoc/auxiliary/reexp-stripped.rs b/tests/rustdoc-html/auxiliary/reexp-stripped.rs similarity index 100% rename from tests/rustdoc/auxiliary/reexp-stripped.rs rename to tests/rustdoc-html/auxiliary/reexp-stripped.rs diff --git a/tests/rustdoc-html/auxiliary/remapped-paths.rs b/tests/rustdoc-html/auxiliary/remapped-paths.rs new file mode 100644 index 000000000000..f31d2d316f3a --- /dev/null +++ b/tests/rustdoc-html/auxiliary/remapped-paths.rs @@ -0,0 +1,11 @@ +//@ compile-flags:-Zunstable-options --remap-path-prefix={{src-base}}= + +pub struct MyStruct { + field: u32, +} + +impl MyStruct { + pub fn new() -> MyStruct { + MyStruct { field: 3 } + } +} diff --git a/tests/rustdoc/auxiliary/rustdoc-ffi.rs b/tests/rustdoc-html/auxiliary/rustdoc-ffi.rs similarity index 100% rename from tests/rustdoc/auxiliary/rustdoc-ffi.rs rename to tests/rustdoc-html/auxiliary/rustdoc-ffi.rs diff --git a/tests/rustdoc/auxiliary/trait-visibility.rs b/tests/rustdoc-html/auxiliary/trait-visibility.rs similarity index 100% rename from tests/rustdoc/auxiliary/trait-visibility.rs rename to tests/rustdoc-html/auxiliary/trait-visibility.rs diff --git a/tests/rustdoc/auxiliary/unit-return.rs b/tests/rustdoc-html/auxiliary/unit-return.rs similarity index 100% rename from tests/rustdoc/auxiliary/unit-return.rs rename to tests/rustdoc-html/auxiliary/unit-return.rs diff --git a/tests/rustdoc/auxiliary/unsafe-binder-dep.rs b/tests/rustdoc-html/auxiliary/unsafe-binder-dep.rs similarity index 100% rename from tests/rustdoc/auxiliary/unsafe-binder-dep.rs rename to tests/rustdoc-html/auxiliary/unsafe-binder-dep.rs diff --git a/tests/rustdoc/auxiliary/unstable-trait.rs b/tests/rustdoc-html/auxiliary/unstable-trait.rs similarity index 100% rename from tests/rustdoc/auxiliary/unstable-trait.rs rename to tests/rustdoc-html/auxiliary/unstable-trait.rs diff --git a/tests/rustdoc/bad-codeblock-syntax.rs b/tests/rustdoc-html/bad-codeblock-syntax.rs similarity index 100% rename from tests/rustdoc/bad-codeblock-syntax.rs rename to tests/rustdoc-html/bad-codeblock-syntax.rs diff --git a/tests/rustdoc/blank-line-in-doc-block-47197.rs b/tests/rustdoc-html/blank-line-in-doc-block-47197.rs similarity index 100% rename from tests/rustdoc/blank-line-in-doc-block-47197.rs rename to tests/rustdoc-html/blank-line-in-doc-block-47197.rs diff --git a/tests/rustdoc/bold-tag-101743.rs b/tests/rustdoc-html/bold-tag-101743.rs similarity index 100% rename from tests/rustdoc/bold-tag-101743.rs rename to tests/rustdoc-html/bold-tag-101743.rs diff --git a/tests/rustdoc/bounds.rs b/tests/rustdoc-html/bounds.rs similarity index 100% rename from tests/rustdoc/bounds.rs rename to tests/rustdoc-html/bounds.rs diff --git a/tests/rustdoc/cap-lints.rs b/tests/rustdoc-html/cap-lints.rs similarity index 100% rename from tests/rustdoc/cap-lints.rs rename to tests/rustdoc-html/cap-lints.rs diff --git a/tests/rustdoc/cfg-bool.rs b/tests/rustdoc-html/cfg-bool.rs similarity index 100% rename from tests/rustdoc/cfg-bool.rs rename to tests/rustdoc-html/cfg-bool.rs diff --git a/tests/rustdoc/cfg-doctest.rs b/tests/rustdoc-html/cfg-doctest.rs similarity index 100% rename from tests/rustdoc/cfg-doctest.rs rename to tests/rustdoc-html/cfg-doctest.rs diff --git a/tests/rustdoc/check-styled-link.rs b/tests/rustdoc-html/check-styled-link.rs similarity index 100% rename from tests/rustdoc/check-styled-link.rs rename to tests/rustdoc-html/check-styled-link.rs diff --git a/tests/rustdoc/check.rs b/tests/rustdoc-html/check.rs similarity index 100% rename from tests/rustdoc/check.rs rename to tests/rustdoc-html/check.rs diff --git a/tests/rustdoc/codeblock-title.rs b/tests/rustdoc-html/codeblock-title.rs similarity index 100% rename from tests/rustdoc/codeblock-title.rs rename to tests/rustdoc-html/codeblock-title.rs diff --git a/tests/rustdoc/comment-in-doctest.rs b/tests/rustdoc-html/comment-in-doctest.rs similarity index 100% rename from tests/rustdoc/comment-in-doctest.rs rename to tests/rustdoc-html/comment-in-doctest.rs diff --git a/tests/rustdoc/const-fn-76501.rs b/tests/rustdoc-html/const-fn-76501.rs similarity index 100% rename from tests/rustdoc/const-fn-76501.rs rename to tests/rustdoc-html/const-fn-76501.rs diff --git a/tests/rustdoc/const-fn-effects.rs b/tests/rustdoc-html/const-fn-effects.rs similarity index 100% rename from tests/rustdoc/const-fn-effects.rs rename to tests/rustdoc-html/const-fn-effects.rs diff --git a/tests/rustdoc/const-fn.rs b/tests/rustdoc-html/const-fn.rs similarity index 100% rename from tests/rustdoc/const-fn.rs rename to tests/rustdoc-html/const-fn.rs diff --git a/tests/rustdoc/const-generics/add-impl.rs b/tests/rustdoc-html/const-generics/add-impl.rs similarity index 100% rename from tests/rustdoc/const-generics/add-impl.rs rename to tests/rustdoc-html/const-generics/add-impl.rs diff --git a/tests/rustdoc/const-generics/auxiliary/extern_crate.rs b/tests/rustdoc-html/const-generics/auxiliary/extern_crate.rs similarity index 100% rename from tests/rustdoc/const-generics/auxiliary/extern_crate.rs rename to tests/rustdoc-html/const-generics/auxiliary/extern_crate.rs diff --git a/tests/rustdoc/const-generics/const-generic-defaults.rs b/tests/rustdoc-html/const-generics/const-generic-defaults.rs similarity index 100% rename from tests/rustdoc/const-generics/const-generic-defaults.rs rename to tests/rustdoc-html/const-generics/const-generic-defaults.rs diff --git a/tests/rustdoc/const-generics/const-generic-slice.rs b/tests/rustdoc-html/const-generics/const-generic-slice.rs similarity index 100% rename from tests/rustdoc/const-generics/const-generic-slice.rs rename to tests/rustdoc-html/const-generics/const-generic-slice.rs diff --git a/tests/rustdoc/const-generics/const-generics-docs.rs b/tests/rustdoc-html/const-generics/const-generics-docs.rs similarity index 100% rename from tests/rustdoc/const-generics/const-generics-docs.rs rename to tests/rustdoc-html/const-generics/const-generics-docs.rs diff --git a/tests/rustdoc/const-generics/const-impl.rs b/tests/rustdoc-html/const-generics/const-impl.rs similarity index 100% rename from tests/rustdoc/const-generics/const-impl.rs rename to tests/rustdoc-html/const-generics/const-impl.rs diff --git a/tests/rustdoc/const-generics/const-param-type-references-generics.rs b/tests/rustdoc-html/const-generics/const-param-type-references-generics.rs similarity index 100% rename from tests/rustdoc/const-generics/const-param-type-references-generics.rs rename to tests/rustdoc-html/const-generics/const-param-type-references-generics.rs diff --git a/tests/rustdoc/const-generics/generic_const_exprs.rs b/tests/rustdoc-html/const-generics/generic_const_exprs.rs similarity index 100% rename from tests/rustdoc/const-generics/generic_const_exprs.rs rename to tests/rustdoc-html/const-generics/generic_const_exprs.rs diff --git a/tests/rustdoc/const-generics/lazy_normalization_consts/const-equate-pred.rs b/tests/rustdoc-html/const-generics/lazy_normalization_consts/const-equate-pred.rs similarity index 100% rename from tests/rustdoc/const-generics/lazy_normalization_consts/const-equate-pred.rs rename to tests/rustdoc-html/const-generics/lazy_normalization_consts/const-equate-pred.rs diff --git a/tests/rustdoc/const-generics/type-alias.rs b/tests/rustdoc-html/const-generics/type-alias.rs similarity index 100% rename from tests/rustdoc/const-generics/type-alias.rs rename to tests/rustdoc-html/const-generics/type-alias.rs diff --git a/tests/rustdoc/const-intrinsic.rs b/tests/rustdoc-html/const-intrinsic.rs similarity index 100% rename from tests/rustdoc/const-intrinsic.rs rename to tests/rustdoc-html/const-intrinsic.rs diff --git a/tests/rustdoc/constant/assoc-const-has-projection-ty.rs b/tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs similarity index 100% rename from tests/rustdoc/constant/assoc-const-has-projection-ty.rs rename to tests/rustdoc-html/constant/assoc-const-has-projection-ty.rs diff --git a/tests/rustdoc/constant/assoc-consts-underscore.rs b/tests/rustdoc-html/constant/assoc-consts-underscore.rs similarity index 100% rename from tests/rustdoc/constant/assoc-consts-underscore.rs rename to tests/rustdoc-html/constant/assoc-consts-underscore.rs diff --git a/tests/rustdoc/constant/assoc-consts-version.rs b/tests/rustdoc-html/constant/assoc-consts-version.rs similarity index 100% rename from tests/rustdoc/constant/assoc-consts-version.rs rename to tests/rustdoc-html/constant/assoc-consts-version.rs diff --git a/tests/rustdoc/constant/assoc-consts.rs b/tests/rustdoc-html/constant/assoc-consts.rs similarity index 100% rename from tests/rustdoc/constant/assoc-consts.rs rename to tests/rustdoc-html/constant/assoc-consts.rs diff --git a/tests/rustdoc/constant/associated-consts.rs b/tests/rustdoc-html/constant/associated-consts.rs similarity index 100% rename from tests/rustdoc/constant/associated-consts.rs rename to tests/rustdoc-html/constant/associated-consts.rs diff --git a/tests/rustdoc/constant/const-display.rs b/tests/rustdoc-html/constant/const-display.rs similarity index 100% rename from tests/rustdoc/constant/const-display.rs rename to tests/rustdoc-html/constant/const-display.rs diff --git a/tests/rustdoc/constant/const-doc.rs b/tests/rustdoc-html/constant/const-doc.rs similarity index 100% rename from tests/rustdoc/constant/const-doc.rs rename to tests/rustdoc-html/constant/const-doc.rs diff --git a/tests/rustdoc/constant/const-effect-param.rs b/tests/rustdoc-html/constant/const-effect-param.rs similarity index 100% rename from tests/rustdoc/constant/const-effect-param.rs rename to tests/rustdoc-html/constant/const-effect-param.rs diff --git a/tests/rustdoc/constant/const-trait-and-impl-methods.rs b/tests/rustdoc-html/constant/const-trait-and-impl-methods.rs similarity index 100% rename from tests/rustdoc/constant/const-trait-and-impl-methods.rs rename to tests/rustdoc-html/constant/const-trait-and-impl-methods.rs diff --git a/tests/rustdoc/constant/const-underscore.rs b/tests/rustdoc-html/constant/const-underscore.rs similarity index 100% rename from tests/rustdoc/constant/const-underscore.rs rename to tests/rustdoc-html/constant/const-underscore.rs diff --git a/tests/rustdoc/constant/const-value-display.rs b/tests/rustdoc-html/constant/const-value-display.rs similarity index 100% rename from tests/rustdoc/constant/const-value-display.rs rename to tests/rustdoc-html/constant/const-value-display.rs diff --git a/tests/rustdoc/constant/const.rs b/tests/rustdoc-html/constant/const.rs similarity index 100% rename from tests/rustdoc/constant/const.rs rename to tests/rustdoc-html/constant/const.rs diff --git a/tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs b/tests/rustdoc-html/constant/document-item-with-associated-const-in-where-clause.rs similarity index 100% rename from tests/rustdoc/constant/document-item-with-associated-const-in-where-clause.rs rename to tests/rustdoc-html/constant/document-item-with-associated-const-in-where-clause.rs diff --git a/tests/rustdoc/constant/generic-const-items.rs b/tests/rustdoc-html/constant/generic-const-items.rs similarity index 100% rename from tests/rustdoc/constant/generic-const-items.rs rename to tests/rustdoc-html/constant/generic-const-items.rs diff --git a/tests/rustdoc/constant/generic_const_exprs.rs b/tests/rustdoc-html/constant/generic_const_exprs.rs similarity index 100% rename from tests/rustdoc/constant/generic_const_exprs.rs rename to tests/rustdoc-html/constant/generic_const_exprs.rs diff --git a/tests/rustdoc/constant/glob-shadowing-const.rs b/tests/rustdoc-html/constant/glob-shadowing-const.rs similarity index 100% rename from tests/rustdoc/constant/glob-shadowing-const.rs rename to tests/rustdoc-html/constant/glob-shadowing-const.rs diff --git a/tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc-html/constant/hide-complex-unevaluated-const-arguments.rs similarity index 100% rename from tests/rustdoc/constant/hide-complex-unevaluated-const-arguments.rs rename to tests/rustdoc-html/constant/hide-complex-unevaluated-const-arguments.rs diff --git a/tests/rustdoc/constant/hide-complex-unevaluated-consts.rs b/tests/rustdoc-html/constant/hide-complex-unevaluated-consts.rs similarity index 100% rename from tests/rustdoc/constant/hide-complex-unevaluated-consts.rs rename to tests/rustdoc-html/constant/hide-complex-unevaluated-consts.rs diff --git a/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs b/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs new file mode 100644 index 000000000000..bdb82b91ec27 --- /dev/null +++ b/tests/rustdoc-html/constant/ice-associated-const-equality-105952.rs @@ -0,0 +1,19 @@ +//! Regression test for + +#![crate_name = "foo"] +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +pub enum ParseMode { + Raw, +} +pub trait Parse { + type const PARSE_MODE: ParseMode; +} +pub trait RenderRaw {} + +//@ hasraw foo/trait.RenderRaw.html 'impl' +//@ hasraw foo/trait.RenderRaw.html 'ParseMode::Raw' +impl> RenderRaw for T {} diff --git a/tests/rustdoc/constant/legacy-const-generic.rs b/tests/rustdoc-html/constant/legacy-const-generic.rs similarity index 100% rename from tests/rustdoc/constant/legacy-const-generic.rs rename to tests/rustdoc-html/constant/legacy-const-generic.rs diff --git a/tests/rustdoc/constant/link-assoc-const.rs b/tests/rustdoc-html/constant/link-assoc-const.rs similarity index 100% rename from tests/rustdoc/constant/link-assoc-const.rs rename to tests/rustdoc-html/constant/link-assoc-const.rs diff --git a/tests/rustdoc/constant/redirect-const.rs b/tests/rustdoc-html/constant/redirect-const.rs similarity index 100% rename from tests/rustdoc/constant/redirect-const.rs rename to tests/rustdoc-html/constant/redirect-const.rs diff --git a/tests/rustdoc/constant/rfc-2632-const-trait-impl.rs b/tests/rustdoc-html/constant/rfc-2632-const-trait-impl.rs similarity index 100% rename from tests/rustdoc/constant/rfc-2632-const-trait-impl.rs rename to tests/rustdoc-html/constant/rfc-2632-const-trait-impl.rs diff --git a/tests/rustdoc/constant/show-const-contents.rs b/tests/rustdoc-html/constant/show-const-contents.rs similarity index 100% rename from tests/rustdoc/constant/show-const-contents.rs rename to tests/rustdoc-html/constant/show-const-contents.rs diff --git a/tests/rustdoc/constructor-imports.rs b/tests/rustdoc-html/constructor-imports.rs similarity index 100% rename from tests/rustdoc/constructor-imports.rs rename to tests/rustdoc-html/constructor-imports.rs diff --git a/tests/rustdoc/crate-doc-hidden-109695.rs b/tests/rustdoc-html/crate-doc-hidden-109695.rs similarity index 100% rename from tests/rustdoc/crate-doc-hidden-109695.rs rename to tests/rustdoc-html/crate-doc-hidden-109695.rs diff --git a/tests/rustdoc/crate-version-escape.rs b/tests/rustdoc-html/crate-version-escape.rs similarity index 100% rename from tests/rustdoc/crate-version-escape.rs rename to tests/rustdoc-html/crate-version-escape.rs diff --git a/tests/rustdoc/crate-version-extra.rs b/tests/rustdoc-html/crate-version-extra.rs similarity index 100% rename from tests/rustdoc/crate-version-extra.rs rename to tests/rustdoc-html/crate-version-extra.rs diff --git a/tests/rustdoc/crate-version.rs b/tests/rustdoc-html/crate-version.rs similarity index 100% rename from tests/rustdoc/crate-version.rs rename to tests/rustdoc-html/crate-version.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive-no-index/s.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive-no-index/s.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-transitive/s.rs b/tests/rustdoc-html/cross-crate-info/cargo-transitive/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-transitive/s.rs rename to tests/rustdoc-html/cross-crate-info/cargo-transitive/s.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two-no-index/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/cargo-two-no-index/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two-no-index/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two-no-index/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs b/tests/rustdoc-html/cross-crate-info/cargo-two-no-index/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two-no-index/e.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two-no-index/e.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/cargo-two/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/cargo-two/e.rs b/tests/rustdoc-html/cross-crate-info/cargo-two/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/cargo-two/e.rs rename to tests/rustdoc-html/cross-crate-info/cargo-two/e.rs diff --git a/tests/rustdoc/cross-crate-info/index-on-last/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/index-on-last/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/index-on-last/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/index-on-last/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/index-on-last/e.rs b/tests/rustdoc-html/cross-crate-info/index-on-last/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/index-on-last/e.rs rename to tests/rustdoc-html/cross-crate-info/index-on-last/e.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/r.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/r.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/r.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/r.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/s.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/s.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/s.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/kitchen-sink/i.rs b/tests/rustdoc-html/cross-crate-info/kitchen-sink/i.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/kitchen-sink/i.rs rename to tests/rustdoc-html/cross-crate-info/kitchen-sink/i.rs diff --git a/tests/rustdoc/cross-crate-info/single-crate-baseline/q.rs b/tests/rustdoc-html/cross-crate-info/single-crate-baseline/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/single-crate-baseline/q.rs rename to tests/rustdoc-html/cross-crate-info/single-crate-baseline/q.rs diff --git a/tests/rustdoc/cross-crate-info/single-crate-no-index/q.rs b/tests/rustdoc-html/cross-crate-info/single-crate-no-index/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/single-crate-no-index/q.rs rename to tests/rustdoc-html/cross-crate-info/single-crate-no-index/q.rs diff --git a/tests/rustdoc/cross-crate-info/transitive/auxiliary/q.rs b/tests/rustdoc-html/cross-crate-info/transitive/auxiliary/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/transitive/auxiliary/q.rs rename to tests/rustdoc-html/cross-crate-info/transitive/auxiliary/q.rs diff --git a/tests/rustdoc/cross-crate-info/transitive/auxiliary/t.rs b/tests/rustdoc-html/cross-crate-info/transitive/auxiliary/t.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/transitive/auxiliary/t.rs rename to tests/rustdoc-html/cross-crate-info/transitive/auxiliary/t.rs diff --git a/tests/rustdoc/cross-crate-info/transitive/s.rs b/tests/rustdoc-html/cross-crate-info/transitive/s.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/transitive/s.rs rename to tests/rustdoc-html/cross-crate-info/transitive/s.rs diff --git a/tests/rustdoc/cross-crate-info/two/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/two/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/two/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/two/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/two/e.rs b/tests/rustdoc-html/cross-crate-info/two/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/two/e.rs rename to tests/rustdoc-html/cross-crate-info/two/e.rs diff --git a/tests/rustdoc/cross-crate-info/working-dir-examples/q.rs b/tests/rustdoc-html/cross-crate-info/working-dir-examples/q.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/working-dir-examples/q.rs rename to tests/rustdoc-html/cross-crate-info/working-dir-examples/q.rs diff --git a/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs b/tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs rename to tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/auxiliary/f.rs diff --git a/tests/rustdoc/cross-crate-info/write-docs-somewhere-else/e.rs b/tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/e.rs similarity index 100% rename from tests/rustdoc/cross-crate-info/write-docs-somewhere-else/e.rs rename to tests/rustdoc-html/cross-crate-info/write-docs-somewhere-else/e.rs diff --git a/tests/rustdoc/cross-crate-links.rs b/tests/rustdoc-html/cross-crate-links.rs similarity index 100% rename from tests/rustdoc/cross-crate-links.rs rename to tests/rustdoc-html/cross-crate-links.rs diff --git a/tests/rustdoc/custom_code_classes.rs b/tests/rustdoc-html/custom_code_classes.rs similarity index 100% rename from tests/rustdoc/custom_code_classes.rs rename to tests/rustdoc-html/custom_code_classes.rs diff --git a/tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html b/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html similarity index 100% rename from tests/rustdoc/decl-line-wrapping-empty-arg-list.decl.html rename to tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html diff --git a/tests/rustdoc/decl-line-wrapping-empty-arg-list.rs b/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs similarity index 100% rename from tests/rustdoc/decl-line-wrapping-empty-arg-list.rs rename to tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs diff --git a/tests/rustdoc/decl-trailing-whitespace.declaration.html b/tests/rustdoc-html/decl-trailing-whitespace.declaration.html similarity index 100% rename from tests/rustdoc/decl-trailing-whitespace.declaration.html rename to tests/rustdoc-html/decl-trailing-whitespace.declaration.html diff --git a/tests/rustdoc/decl-trailing-whitespace.rs b/tests/rustdoc-html/decl-trailing-whitespace.rs similarity index 100% rename from tests/rustdoc/decl-trailing-whitespace.rs rename to tests/rustdoc-html/decl-trailing-whitespace.rs diff --git a/tests/rustdoc/deep-structures.rs b/tests/rustdoc-html/deep-structures.rs similarity index 100% rename from tests/rustdoc/deep-structures.rs rename to tests/rustdoc-html/deep-structures.rs diff --git a/tests/rustdoc/default-theme.rs b/tests/rustdoc-html/default-theme.rs similarity index 100% rename from tests/rustdoc/default-theme.rs rename to tests/rustdoc-html/default-theme.rs diff --git a/tests/rustdoc/default-trait-method-link.rs b/tests/rustdoc-html/default-trait-method-link.rs similarity index 100% rename from tests/rustdoc/default-trait-method-link.rs rename to tests/rustdoc-html/default-trait-method-link.rs diff --git a/tests/rustdoc/default-trait-method.rs b/tests/rustdoc-html/default-trait-method.rs similarity index 100% rename from tests/rustdoc/default-trait-method.rs rename to tests/rustdoc-html/default-trait-method.rs diff --git a/tests/rustdoc/demo-allocator-54478.rs b/tests/rustdoc-html/demo-allocator-54478.rs similarity index 100% rename from tests/rustdoc/demo-allocator-54478.rs rename to tests/rustdoc-html/demo-allocator-54478.rs diff --git a/tests/rustdoc/deprecated-future-staged-api.rs b/tests/rustdoc-html/deprecated-future-staged-api.rs similarity index 100% rename from tests/rustdoc/deprecated-future-staged-api.rs rename to tests/rustdoc-html/deprecated-future-staged-api.rs diff --git a/tests/rustdoc/deprecated-future.rs b/tests/rustdoc-html/deprecated-future.rs similarity index 100% rename from tests/rustdoc/deprecated-future.rs rename to tests/rustdoc-html/deprecated-future.rs diff --git a/tests/rustdoc/deprecated.rs b/tests/rustdoc-html/deprecated.rs similarity index 100% rename from tests/rustdoc/deprecated.rs rename to tests/rustdoc-html/deprecated.rs diff --git a/tests/rustdoc/deref-methods-19190-foreign-type.rs b/tests/rustdoc-html/deref-methods-19190-foreign-type.rs similarity index 100% rename from tests/rustdoc/deref-methods-19190-foreign-type.rs rename to tests/rustdoc-html/deref-methods-19190-foreign-type.rs diff --git a/tests/rustdoc/deref-methods-19190-inline.rs b/tests/rustdoc-html/deref-methods-19190-inline.rs similarity index 100% rename from tests/rustdoc/deref-methods-19190-inline.rs rename to tests/rustdoc-html/deref-methods-19190-inline.rs diff --git a/tests/rustdoc/deref-methods-19190.rs b/tests/rustdoc-html/deref-methods-19190.rs similarity index 100% rename from tests/rustdoc/deref-methods-19190.rs rename to tests/rustdoc-html/deref-methods-19190.rs diff --git a/tests/rustdoc/deref-mut-35169-2.rs b/tests/rustdoc-html/deref-mut-35169-2.rs similarity index 100% rename from tests/rustdoc/deref-mut-35169-2.rs rename to tests/rustdoc-html/deref-mut-35169-2.rs diff --git a/tests/rustdoc/deref-mut-35169.rs b/tests/rustdoc-html/deref-mut-35169.rs similarity index 100% rename from tests/rustdoc/deref-mut-35169.rs rename to tests/rustdoc-html/deref-mut-35169.rs diff --git a/tests/rustdoc/deref/deref-const-fn.rs b/tests/rustdoc-html/deref/deref-const-fn.rs similarity index 100% rename from tests/rustdoc/deref/deref-const-fn.rs rename to tests/rustdoc-html/deref/deref-const-fn.rs diff --git a/tests/rustdoc/deref/deref-methods-24686-target.rs b/tests/rustdoc-html/deref/deref-methods-24686-target.rs similarity index 100% rename from tests/rustdoc/deref/deref-methods-24686-target.rs rename to tests/rustdoc-html/deref/deref-methods-24686-target.rs diff --git a/tests/rustdoc/deref/deref-multiple-impl-blocks.rs b/tests/rustdoc-html/deref/deref-multiple-impl-blocks.rs similarity index 100% rename from tests/rustdoc/deref/deref-multiple-impl-blocks.rs rename to tests/rustdoc-html/deref/deref-multiple-impl-blocks.rs diff --git a/tests/rustdoc/deref/deref-mut-methods.rs b/tests/rustdoc-html/deref/deref-mut-methods.rs similarity index 100% rename from tests/rustdoc/deref/deref-mut-methods.rs rename to tests/rustdoc-html/deref/deref-mut-methods.rs diff --git a/tests/rustdoc/deref/deref-recursive-pathbuf.rs b/tests/rustdoc-html/deref/deref-recursive-pathbuf.rs similarity index 100% rename from tests/rustdoc/deref/deref-recursive-pathbuf.rs rename to tests/rustdoc-html/deref/deref-recursive-pathbuf.rs diff --git a/tests/rustdoc/deref/deref-recursive.rs b/tests/rustdoc-html/deref/deref-recursive.rs similarity index 100% rename from tests/rustdoc/deref/deref-recursive.rs rename to tests/rustdoc-html/deref/deref-recursive.rs diff --git a/tests/rustdoc/deref/deref-slice-core.rs b/tests/rustdoc-html/deref/deref-slice-core.rs similarity index 100% rename from tests/rustdoc/deref/deref-slice-core.rs rename to tests/rustdoc-html/deref/deref-slice-core.rs diff --git a/tests/rustdoc/deref/deref-to-primitive.rs b/tests/rustdoc-html/deref/deref-to-primitive.rs similarity index 100% rename from tests/rustdoc/deref/deref-to-primitive.rs rename to tests/rustdoc-html/deref/deref-to-primitive.rs diff --git a/tests/rustdoc/deref/deref-typedef.rs b/tests/rustdoc-html/deref/deref-typedef.rs similarity index 100% rename from tests/rustdoc/deref/deref-typedef.rs rename to tests/rustdoc-html/deref/deref-typedef.rs diff --git a/tests/rustdoc/deref/escape-deref-methods.rs b/tests/rustdoc-html/deref/escape-deref-methods.rs similarity index 100% rename from tests/rustdoc/deref/escape-deref-methods.rs rename to tests/rustdoc-html/deref/escape-deref-methods.rs diff --git a/tests/rustdoc/deref/recursive-deref-sidebar.rs b/tests/rustdoc-html/deref/recursive-deref-sidebar.rs similarity index 100% rename from tests/rustdoc/deref/recursive-deref-sidebar.rs rename to tests/rustdoc-html/deref/recursive-deref-sidebar.rs diff --git a/tests/rustdoc/deref/recursive-deref.rs b/tests/rustdoc-html/deref/recursive-deref.rs similarity index 100% rename from tests/rustdoc/deref/recursive-deref.rs rename to tests/rustdoc-html/deref/recursive-deref.rs diff --git a/tests/rustdoc/deref/sidebar-links-deref-100679.rs b/tests/rustdoc-html/deref/sidebar-links-deref-100679.rs similarity index 100% rename from tests/rustdoc/deref/sidebar-links-deref-100679.rs rename to tests/rustdoc-html/deref/sidebar-links-deref-100679.rs diff --git a/tests/rustdoc/description.rs b/tests/rustdoc-html/description.rs similarity index 100% rename from tests/rustdoc/description.rs rename to tests/rustdoc-html/description.rs diff --git a/tests/rustdoc/description_default.rs b/tests/rustdoc-html/description_default.rs similarity index 100% rename from tests/rustdoc/description_default.rs rename to tests/rustdoc-html/description_default.rs diff --git a/tests/rustdoc-html/display-hidden-items.rs b/tests/rustdoc-html/display-hidden-items.rs new file mode 100644 index 000000000000..6b548e394560 --- /dev/null +++ b/tests/rustdoc-html/display-hidden-items.rs @@ -0,0 +1,84 @@ +// Test to ensure that the `--document-hidden-items` option is working as expected. +//@ compile-flags: -Z unstable-options --document-hidden-items +// ignore-tidy-linelength + +#![crate_name = "foo"] + +//@ has 'foo/index.html' + +//@ matches - '//dt[code]' 'pub extern crate .*hidden_core;.*👻' +//@ has - '//dt/code' 'pub extern crate core as hidden_core;' +#[doc(hidden)] +pub extern crate core as hidden_core; + +//@ has - '//*[@id="reexport.hidden_reexport"]/span[@title="Hidden item"]' '👻' +//@ has - '//*[@id="reexport.hidden_reexport"]/code' 'pub use hidden::inside_hidden as hidden_reexport;' +#[doc(hidden)] +pub use hidden::inside_hidden as hidden_reexport; + +//@ has - '//dt/a[@class="trait"]' 'TraitHidden' +//@ has 'foo/trait.TraitHidden.html' +//@ has 'foo/trait.TraitHidden.html' '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has 'foo/trait.TraitHidden.html' '//*[@class="rust item-decl"]/code' 'pub trait TraitHidden' +#[doc(hidden)] +pub trait TraitHidden {} + +//@ has 'foo/index.html' '//dt/a[@class="trait"]' 'Trait' +pub trait Trait { + //@ has 'foo/trait.Trait.html' + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' + #[doc(hidden)] + const BAR: u32 = 0; + + //@ has - '//*[@id="method.foo"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' + //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' + #[doc(hidden)] + fn foo() {} +} + +//@ has 'foo/index.html' '//dt/a[@class="struct"]' 'Struct' +//@ has 'foo/struct.Struct.html' +pub struct Struct { + //@ has - '//*[@id="structfield.a"]/code' 'a: u32' + #[doc(hidden)] + pub a: u32, +} + +impl Struct { + //@ has - '//*[@id="method.new"]/*[@class="code-header"]' 'pub fn new() -> Self' + #[doc(hidden)] + pub fn new() -> Self { Self { a: 0 } } +} + +impl Trait for Struct { + //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' + //@ has - '//*[@id="method.foo"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' +} +//@ has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' +impl TraitHidden for Struct {} + +//@ has 'foo/index.html' '//dt/a[@class="enum"]' 'HiddenEnum' +//@ has 'foo/enum.HiddenEnum.html' +//@ has 'foo/enum.HiddenEnum.html' '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[doc(hidden)]' +//@ has 'foo/enum.HiddenEnum.html' '//*[@class="rust item-decl"]/code' 'pub enum HiddenEnum' +#[doc(hidden)] +pub enum HiddenEnum { + A, +} + +//@ has 'foo/index.html' '//dt/a[@class="enum"]' 'Enum' +pub enum Enum { + //@ has 'foo/enum.Enum.html' '//*[@id="variant.A"]/*[@class="code-header"]/*[@class="code-attribute"]' '#[doc(hidden)]' + //@ has 'foo/enum.Enum.html' '//*[@id="variant.A"]/*[@class="code-header"]' 'A' + #[doc(hidden)] + A, +} + +//@ has 'foo/index.html' '//dt/a[@class="mod"]' 'hidden' +#[doc(hidden)] +pub mod hidden { + //@ has 'foo/hidden/index.html' + //@ has - '//dt/a[@class="fn"]' 'inside_hidden' + //@ has 'foo/hidden/fn.inside_hidden.html' + pub fn inside_hidden() {} +} diff --git a/tests/rustdoc/doc-attr-comment-mix-42760.rs b/tests/rustdoc-html/doc-attr-comment-mix-42760.rs similarity index 100% rename from tests/rustdoc/doc-attr-comment-mix-42760.rs rename to tests/rustdoc-html/doc-attr-comment-mix-42760.rs diff --git a/tests/rustdoc/doc-attribute.rs b/tests/rustdoc-html/doc-attribute.rs similarity index 100% rename from tests/rustdoc/doc-attribute.rs rename to tests/rustdoc-html/doc-attribute.rs diff --git a/tests/rustdoc/doc-auto-cfg-public-in-private.rs b/tests/rustdoc-html/doc-auto-cfg-public-in-private.rs similarity index 100% rename from tests/rustdoc/doc-auto-cfg-public-in-private.rs rename to tests/rustdoc-html/doc-auto-cfg-public-in-private.rs diff --git a/tests/rustdoc/doc-auto-cfg.rs b/tests/rustdoc-html/doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/doc-auto-cfg.rs rename to tests/rustdoc-html/doc-auto-cfg.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-hide.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-hide.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-hide.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-hide.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-implicit-gate.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-implicit-gate.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-implicit.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-implicit.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-implicit.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-inherit-from-module-79201.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-inherit-from-module-79201.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-inherit-from-module-79201.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-simplification.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-simplification.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-simplification.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-simplification.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-target-feature.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-target-feature.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-target-feature.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg-traits.rs b/tests/rustdoc-html/doc-cfg/doc-cfg-traits.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg-traits.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg-traits.rs diff --git a/tests/rustdoc/doc-cfg/doc-cfg.rs b/tests/rustdoc-html/doc-cfg/doc-cfg.rs similarity index 100% rename from tests/rustdoc/doc-cfg/doc-cfg.rs rename to tests/rustdoc-html/doc-cfg/doc-cfg.rs diff --git a/tests/rustdoc/doc-cfg/duplicate-cfg.rs b/tests/rustdoc-html/doc-cfg/duplicate-cfg.rs similarity index 100% rename from tests/rustdoc/doc-cfg/duplicate-cfg.rs rename to tests/rustdoc-html/doc-cfg/duplicate-cfg.rs diff --git a/tests/rustdoc/doc-hidden-crate.rs b/tests/rustdoc-html/doc-hidden-crate.rs similarity index 100% rename from tests/rustdoc/doc-hidden-crate.rs rename to tests/rustdoc-html/doc-hidden-crate.rs diff --git a/tests/rustdoc/doc-hidden-method-13698.rs b/tests/rustdoc-html/doc-hidden-method-13698.rs similarity index 100% rename from tests/rustdoc/doc-hidden-method-13698.rs rename to tests/rustdoc-html/doc-hidden-method-13698.rs diff --git a/tests/rustdoc-html/doc-on-keyword.rs b/tests/rustdoc-html/doc-on-keyword.rs new file mode 100644 index 000000000000..0c62eda60a6b --- /dev/null +++ b/tests/rustdoc-html/doc-on-keyword.rs @@ -0,0 +1,13 @@ +// While working on , the +// intra doc links on keyword/attribute items were not processed. + +#![feature(rustdoc_internals)] +#![crate_name = "foo"] + +//@ has 'foo/keyword.trait.html' +//@ has - '//a[@href="{{channel}}/core/marker/trait.Send.html"]' 'Send' +//@ has - '//a[@href="{{channel}}/core/marker/trait.Sync.html"]' 'Sync' +#[doc(keyword = "trait")] +// +/// [`Send`] and [Sync] +mod bar {} diff --git a/tests/rustdoc/doc-test-attr-18199.rs b/tests/rustdoc-html/doc-test-attr-18199.rs similarity index 100% rename from tests/rustdoc/doc-test-attr-18199.rs rename to tests/rustdoc-html/doc-test-attr-18199.rs diff --git a/tests/rustdoc/doc_auto_cfg.rs b/tests/rustdoc-html/doc_auto_cfg.rs similarity index 100% rename from tests/rustdoc/doc_auto_cfg.rs rename to tests/rustdoc-html/doc_auto_cfg.rs diff --git a/tests/rustdoc/doc_auto_cfg_reexports.rs b/tests/rustdoc-html/doc_auto_cfg_reexports.rs similarity index 100% rename from tests/rustdoc/doc_auto_cfg_reexports.rs rename to tests/rustdoc-html/doc_auto_cfg_reexports.rs diff --git a/tests/rustdoc/doctest/auxiliary/doctest-runtool.rs b/tests/rustdoc-html/doctest/auxiliary/doctest-runtool.rs similarity index 100% rename from tests/rustdoc/doctest/auxiliary/doctest-runtool.rs rename to tests/rustdoc-html/doctest/auxiliary/doctest-runtool.rs diff --git a/tests/rustdoc/doctest/auxiliary/empty.rs b/tests/rustdoc-html/doctest/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/doctest/auxiliary/empty.rs rename to tests/rustdoc-html/doctest/auxiliary/empty.rs diff --git a/tests/rustdoc/doctest/doctest-cfg-feature-30252.rs b/tests/rustdoc-html/doctest/doctest-cfg-feature-30252.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-cfg-feature-30252.rs rename to tests/rustdoc-html/doctest/doctest-cfg-feature-30252.rs diff --git a/tests/rustdoc/doctest/doctest-crate-attributes-38129.rs b/tests/rustdoc-html/doctest/doctest-crate-attributes-38129.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-crate-attributes-38129.rs rename to tests/rustdoc-html/doctest/doctest-crate-attributes-38129.rs diff --git a/tests/rustdoc/doctest/doctest-escape-boring-41783.codeblock.html b/tests/rustdoc-html/doctest/doctest-escape-boring-41783.codeblock.html similarity index 100% rename from tests/rustdoc/doctest/doctest-escape-boring-41783.codeblock.html rename to tests/rustdoc-html/doctest/doctest-escape-boring-41783.codeblock.html diff --git a/tests/rustdoc/doctest/doctest-escape-boring-41783.rs b/tests/rustdoc-html/doctest/doctest-escape-boring-41783.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-escape-boring-41783.rs rename to tests/rustdoc-html/doctest/doctest-escape-boring-41783.rs diff --git a/tests/rustdoc/doctest/doctest-hide-empty-line-23106.rs b/tests/rustdoc-html/doctest/doctest-hide-empty-line-23106.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-hide-empty-line-23106.rs rename to tests/rustdoc-html/doctest/doctest-hide-empty-line-23106.rs diff --git a/tests/rustdoc/doctest/doctest-ignore-32556.rs b/tests/rustdoc-html/doctest/doctest-ignore-32556.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-ignore-32556.rs rename to tests/rustdoc-html/doctest/doctest-ignore-32556.rs diff --git a/tests/rustdoc/doctest/doctest-include-43153.rs b/tests/rustdoc-html/doctest/doctest-include-43153.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-include-43153.rs rename to tests/rustdoc-html/doctest/doctest-include-43153.rs diff --git a/tests/rustdoc/doctest/doctest-macro-38219.rs b/tests/rustdoc-html/doctest/doctest-macro-38219.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-macro-38219.rs rename to tests/rustdoc-html/doctest/doctest-macro-38219.rs diff --git a/tests/rustdoc/doctest/doctest-manual-crate-name.rs b/tests/rustdoc-html/doctest/doctest-manual-crate-name.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-manual-crate-name.rs rename to tests/rustdoc-html/doctest/doctest-manual-crate-name.rs diff --git a/tests/rustdoc/doctest/doctest-markdown-inline-parse-23744.rs b/tests/rustdoc-html/doctest/doctest-markdown-inline-parse-23744.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-markdown-inline-parse-23744.rs rename to tests/rustdoc-html/doctest/doctest-markdown-inline-parse-23744.rs diff --git a/tests/rustdoc/doctest/doctest-markdown-trailing-docblock-48377.rs b/tests/rustdoc-html/doctest/doctest-markdown-trailing-docblock-48377.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-markdown-trailing-docblock-48377.rs rename to tests/rustdoc-html/doctest/doctest-markdown-trailing-docblock-48377.rs diff --git a/tests/rustdoc/doctest/doctest-multi-line-string-literal-25944.rs b/tests/rustdoc-html/doctest/doctest-multi-line-string-literal-25944.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-multi-line-string-literal-25944.rs rename to tests/rustdoc-html/doctest/doctest-multi-line-string-literal-25944.rs diff --git a/tests/rustdoc/doctest/doctest-runtool.rs b/tests/rustdoc-html/doctest/doctest-runtool.rs similarity index 100% rename from tests/rustdoc/doctest/doctest-runtool.rs rename to tests/rustdoc-html/doctest/doctest-runtool.rs diff --git a/tests/rustdoc/doctest/ignore-sometimes.rs b/tests/rustdoc-html/doctest/ignore-sometimes.rs similarity index 100% rename from tests/rustdoc/doctest/ignore-sometimes.rs rename to tests/rustdoc-html/doctest/ignore-sometimes.rs diff --git a/tests/rustdoc/document-hidden-items-15347.rs b/tests/rustdoc-html/document-hidden-items-15347.rs similarity index 100% rename from tests/rustdoc/document-hidden-items-15347.rs rename to tests/rustdoc-html/document-hidden-items-15347.rs diff --git a/tests/rustdoc/double-hyphen-to-dash.rs b/tests/rustdoc-html/double-hyphen-to-dash.rs similarity index 100% rename from tests/rustdoc/double-hyphen-to-dash.rs rename to tests/rustdoc-html/double-hyphen-to-dash.rs diff --git a/tests/rustdoc/double-quote-escape.rs b/tests/rustdoc-html/double-quote-escape.rs similarity index 100% rename from tests/rustdoc/double-quote-escape.rs rename to tests/rustdoc-html/double-quote-escape.rs diff --git a/tests/rustdoc/duplicate-flags.rs b/tests/rustdoc-html/duplicate-flags.rs similarity index 100% rename from tests/rustdoc/duplicate-flags.rs rename to tests/rustdoc-html/duplicate-flags.rs diff --git a/tests/rustdoc/duplicate_impls/impls.rs b/tests/rustdoc-html/duplicate_impls/impls.rs similarity index 100% rename from tests/rustdoc/duplicate_impls/impls.rs rename to tests/rustdoc-html/duplicate_impls/impls.rs diff --git a/tests/rustdoc/duplicate_impls/sidebar-links-duplicate-impls-33054.rs b/tests/rustdoc-html/duplicate_impls/sidebar-links-duplicate-impls-33054.rs similarity index 100% rename from tests/rustdoc/duplicate_impls/sidebar-links-duplicate-impls-33054.rs rename to tests/rustdoc-html/duplicate_impls/sidebar-links-duplicate-impls-33054.rs diff --git a/tests/rustdoc/dyn-compatibility.rs b/tests/rustdoc-html/dyn-compatibility.rs similarity index 100% rename from tests/rustdoc/dyn-compatibility.rs rename to tests/rustdoc-html/dyn-compatibility.rs diff --git a/tests/rustdoc/early-unindent.rs b/tests/rustdoc-html/early-unindent.rs similarity index 100% rename from tests/rustdoc/early-unindent.rs rename to tests/rustdoc-html/early-unindent.rs diff --git a/tests/rustdoc/edition-doctest.rs b/tests/rustdoc-html/edition-doctest.rs similarity index 100% rename from tests/rustdoc/edition-doctest.rs rename to tests/rustdoc-html/edition-doctest.rs diff --git a/tests/rustdoc/edition-flag.rs b/tests/rustdoc-html/edition-flag.rs similarity index 100% rename from tests/rustdoc/edition-flag.rs rename to tests/rustdoc-html/edition-flag.rs diff --git a/tests/rustdoc/elided-lifetime.rs b/tests/rustdoc-html/elided-lifetime.rs similarity index 100% rename from tests/rustdoc/elided-lifetime.rs rename to tests/rustdoc-html/elided-lifetime.rs diff --git a/tests/rustdoc/empty-doc-comment.rs b/tests/rustdoc-html/empty-doc-comment.rs similarity index 100% rename from tests/rustdoc/empty-doc-comment.rs rename to tests/rustdoc-html/empty-doc-comment.rs diff --git a/tests/rustdoc/empty-mod-public.rs b/tests/rustdoc-html/empty-mod-public.rs similarity index 100% rename from tests/rustdoc/empty-mod-public.rs rename to tests/rustdoc-html/empty-mod-public.rs diff --git a/tests/rustdoc-html/empty-section.rs b/tests/rustdoc-html/empty-section.rs new file mode 100644 index 000000000000..1e6e725a5a7b --- /dev/null +++ b/tests/rustdoc-html/empty-section.rs @@ -0,0 +1,15 @@ +#![crate_name = "foo"] +#![feature(negative_impls, freeze_impls, freeze, unsafe_unpin)] + +pub struct Foo; + +//@ has foo/struct.Foo.html +//@ !hasraw - 'Auto Trait Implementations' +// Manually un-implement all auto traits for Foo: +impl !Send for Foo {} +impl !Sync for Foo {} +impl !std::marker::Freeze for Foo {} +impl !std::marker::UnsafeUnpin for Foo {} +impl !std::marker::Unpin for Foo {} +impl !std::panic::RefUnwindSafe for Foo {} +impl !std::panic::UnwindSafe for Foo {} diff --git a/tests/rustdoc/empty-tuple-struct-118180.rs b/tests/rustdoc-html/empty-tuple-struct-118180.rs similarity index 100% rename from tests/rustdoc/empty-tuple-struct-118180.rs rename to tests/rustdoc-html/empty-tuple-struct-118180.rs diff --git a/tests/rustdoc/ensure-src-link.rs b/tests/rustdoc-html/ensure-src-link.rs similarity index 100% rename from tests/rustdoc/ensure-src-link.rs rename to tests/rustdoc-html/ensure-src-link.rs diff --git a/tests/rustdoc/enum/auxiliary/enum-variant.rs b/tests/rustdoc-html/enum/auxiliary/enum-variant.rs similarity index 100% rename from tests/rustdoc/enum/auxiliary/enum-variant.rs rename to tests/rustdoc-html/enum/auxiliary/enum-variant.rs diff --git a/tests/rustdoc/enum/auxiliary/variant-struct.rs b/tests/rustdoc-html/enum/auxiliary/variant-struct.rs similarity index 100% rename from tests/rustdoc/enum/auxiliary/variant-struct.rs rename to tests/rustdoc-html/enum/auxiliary/variant-struct.rs diff --git a/tests/rustdoc/enum/enum-headings.rs b/tests/rustdoc-html/enum/enum-headings.rs similarity index 100% rename from tests/rustdoc/enum/enum-headings.rs rename to tests/rustdoc-html/enum/enum-headings.rs diff --git a/tests/rustdoc/enum/enum-non-exhaustive-108925.rs b/tests/rustdoc-html/enum/enum-non-exhaustive-108925.rs similarity index 100% rename from tests/rustdoc/enum/enum-non-exhaustive-108925.rs rename to tests/rustdoc-html/enum/enum-non-exhaustive-108925.rs diff --git a/tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs b/tests/rustdoc-html/enum/enum-variant-doc-hidden-field-88600.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-doc-hidden-field-88600.rs rename to tests/rustdoc-html/enum/enum-variant-doc-hidden-field-88600.rs diff --git a/tests/rustdoc/enum/enum-variant-fields-heading.rs b/tests/rustdoc-html/enum/enum-variant-fields-heading.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-fields-heading.rs rename to tests/rustdoc-html/enum/enum-variant-fields-heading.rs diff --git a/tests/rustdoc/enum/enum-variant-fields-heading.variants.html b/tests/rustdoc-html/enum/enum-variant-fields-heading.variants.html similarity index 100% rename from tests/rustdoc/enum/enum-variant-fields-heading.variants.html rename to tests/rustdoc-html/enum/enum-variant-fields-heading.variants.html diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.rs b/tests/rustdoc-html/enum/enum-variant-non_exhaustive.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-non_exhaustive.rs rename to tests/rustdoc-html/enum/enum-variant-non_exhaustive.rs diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html b/tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-alias-code.html similarity index 100% rename from tests/rustdoc/enum/enum-variant-non_exhaustive.type-alias-code.html rename to tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-alias-code.html diff --git a/tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html b/tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-code.html similarity index 100% rename from tests/rustdoc/enum/enum-variant-non_exhaustive.type-code.html rename to tests/rustdoc-html/enum/enum-variant-non_exhaustive.type-code.html diff --git a/tests/rustdoc/enum/enum-variant-value.rs b/tests/rustdoc-html/enum/enum-variant-value.rs similarity index 100% rename from tests/rustdoc/enum/enum-variant-value.rs rename to tests/rustdoc-html/enum/enum-variant-value.rs diff --git a/tests/rustdoc/enum/render-enum-variant-structlike-32395.rs b/tests/rustdoc-html/enum/render-enum-variant-structlike-32395.rs similarity index 100% rename from tests/rustdoc/enum/render-enum-variant-structlike-32395.rs rename to tests/rustdoc-html/enum/render-enum-variant-structlike-32395.rs diff --git a/tests/rustdoc/enum/strip-enum-variant.no-not-shown.html b/tests/rustdoc-html/enum/strip-enum-variant.no-not-shown.html similarity index 100% rename from tests/rustdoc/enum/strip-enum-variant.no-not-shown.html rename to tests/rustdoc-html/enum/strip-enum-variant.no-not-shown.html diff --git a/tests/rustdoc/enum/strip-enum-variant.rs b/tests/rustdoc-html/enum/strip-enum-variant.rs similarity index 100% rename from tests/rustdoc/enum/strip-enum-variant.rs rename to tests/rustdoc-html/enum/strip-enum-variant.rs diff --git a/tests/rustdoc/extern/auxiliary/empty.rs b/tests/rustdoc-html/extern/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/empty.rs rename to tests/rustdoc-html/extern/auxiliary/empty.rs diff --git a/tests/rustdoc-html/extern/auxiliary/extern-links.rs b/tests/rustdoc-html/extern/auxiliary/extern-links.rs new file mode 100644 index 000000000000..4a835673a596 --- /dev/null +++ b/tests/rustdoc-html/extern/auxiliary/extern-links.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/rustdoc/extern/auxiliary/external-cross-doc.md b/tests/rustdoc-html/extern/auxiliary/external-cross-doc.md similarity index 100% rename from tests/rustdoc/extern/auxiliary/external-cross-doc.md rename to tests/rustdoc-html/extern/auxiliary/external-cross-doc.md diff --git a/tests/rustdoc/extern/auxiliary/external-cross.rs b/tests/rustdoc-html/extern/auxiliary/external-cross.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/external-cross.rs rename to tests/rustdoc-html/extern/auxiliary/external-cross.rs diff --git a/tests/rustdoc/extern/auxiliary/external-doc.md b/tests/rustdoc-html/extern/auxiliary/external-doc.md similarity index 100% rename from tests/rustdoc/extern/auxiliary/external-doc.md rename to tests/rustdoc-html/extern/auxiliary/external-doc.md diff --git a/tests/rustdoc/extern/auxiliary/html_root.rs b/tests/rustdoc-html/extern/auxiliary/html_root.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/html_root.rs rename to tests/rustdoc-html/extern/auxiliary/html_root.rs diff --git a/tests/rustdoc/extern/auxiliary/issue-30109-1.rs b/tests/rustdoc-html/extern/auxiliary/issue-30109-1.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/issue-30109-1.rs rename to tests/rustdoc-html/extern/auxiliary/issue-30109-1.rs diff --git a/tests/rustdoc/extern/auxiliary/no_html_root.rs b/tests/rustdoc-html/extern/auxiliary/no_html_root.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/no_html_root.rs rename to tests/rustdoc-html/extern/auxiliary/no_html_root.rs diff --git a/tests/rustdoc/extern/auxiliary/panic-item.rs b/tests/rustdoc-html/extern/auxiliary/panic-item.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/panic-item.rs rename to tests/rustdoc-html/extern/auxiliary/panic-item.rs diff --git a/tests/rustdoc/extern/auxiliary/pub-extern-crate.rs b/tests/rustdoc-html/extern/auxiliary/pub-extern-crate.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/pub-extern-crate.rs rename to tests/rustdoc-html/extern/auxiliary/pub-extern-crate.rs diff --git a/tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs b/tests/rustdoc-html/extern/auxiliary/rustdoc-extern-default-method.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/rustdoc-extern-default-method.rs rename to tests/rustdoc-html/extern/auxiliary/rustdoc-extern-default-method.rs diff --git a/tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs b/tests/rustdoc-html/extern/auxiliary/rustdoc-extern-method.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/rustdoc-extern-method.rs rename to tests/rustdoc-html/extern/auxiliary/rustdoc-extern-method.rs diff --git a/tests/rustdoc/extern/auxiliary/variant-struct.rs b/tests/rustdoc-html/extern/auxiliary/variant-struct.rs similarity index 100% rename from tests/rustdoc/extern/auxiliary/variant-struct.rs rename to tests/rustdoc-html/extern/auxiliary/variant-struct.rs diff --git a/tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs b/tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs new file mode 100644 index 000000000000..41f80cc6ab75 --- /dev/null +++ b/tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs @@ -0,0 +1,19 @@ +//@ aux-build:pub-extern-crate.rs + +// Regression test for issue . +// When a module has both `pub extern crate` and `pub use` items, +// they should both appear under a single "Re-exports" section, +// not two separate sections. + +//@ has duplicate_reexports_section_150211/index.html +// Verify there's exactly one Re-exports section header +//@ count - '//h2[@id="reexports"]' 1 +//@ has - '//h2[@id="reexports"]' 'Re-exports' +// Verify both the extern crate and the use item are present +//@ has - '//code' 'pub extern crate inner;' +//@ has - '//code' 'pub use inner::SomeStruct;' + +pub extern crate inner; + +#[doc(no_inline)] +pub use inner::SomeStruct; diff --git a/tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html b/tests/rustdoc-html/extern/extern-default-method.no_href_on_anchor.html similarity index 100% rename from tests/rustdoc/extern/extern-default-method.no_href_on_anchor.html rename to tests/rustdoc-html/extern/extern-default-method.no_href_on_anchor.html diff --git a/tests/rustdoc/extern/extern-default-method.rs b/tests/rustdoc-html/extern/extern-default-method.rs similarity index 100% rename from tests/rustdoc/extern/extern-default-method.rs rename to tests/rustdoc-html/extern/extern-default-method.rs diff --git a/tests/rustdoc/extern/extern-fn-22038.rs b/tests/rustdoc-html/extern/extern-fn-22038.rs similarity index 100% rename from tests/rustdoc/extern/extern-fn-22038.rs rename to tests/rustdoc-html/extern/extern-fn-22038.rs diff --git a/tests/rustdoc/extern/extern-html-alias.rs b/tests/rustdoc-html/extern/extern-html-alias.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-alias.rs rename to tests/rustdoc-html/extern/extern-html-alias.rs diff --git a/tests/rustdoc/extern/extern-html-fallback.rs b/tests/rustdoc-html/extern/extern-html-fallback.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-fallback.rs rename to tests/rustdoc-html/extern/extern-html-fallback.rs diff --git a/tests/rustdoc/extern/extern-html-root-url-precedence.rs b/tests/rustdoc-html/extern/extern-html-root-url-precedence.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-root-url-precedence.rs rename to tests/rustdoc-html/extern/extern-html-root-url-precedence.rs diff --git a/tests/rustdoc/extern/extern-html-root-url.rs b/tests/rustdoc-html/extern/extern-html-root-url.rs similarity index 100% rename from tests/rustdoc/extern/extern-html-root-url.rs rename to tests/rustdoc-html/extern/extern-html-root-url.rs diff --git a/tests/rustdoc/extern/extern-links.rs b/tests/rustdoc-html/extern/extern-links.rs similarity index 100% rename from tests/rustdoc/extern/extern-links.rs rename to tests/rustdoc-html/extern/extern-links.rs diff --git a/tests/rustdoc/extern/extern-method.rs b/tests/rustdoc-html/extern/extern-method.rs similarity index 100% rename from tests/rustdoc/extern/extern-method.rs rename to tests/rustdoc-html/extern/extern-method.rs diff --git a/tests/rustdoc/extern/external-cross.rs b/tests/rustdoc-html/extern/external-cross.rs similarity index 100% rename from tests/rustdoc/extern/external-cross.rs rename to tests/rustdoc-html/extern/external-cross.rs diff --git a/tests/rustdoc/extern/external-doc.rs b/tests/rustdoc-html/extern/external-doc.rs similarity index 100% rename from tests/rustdoc/extern/external-doc.rs rename to tests/rustdoc-html/extern/external-doc.rs diff --git a/tests/rustdoc/extern/hidden-extern-34025.rs b/tests/rustdoc-html/extern/hidden-extern-34025.rs similarity index 100% rename from tests/rustdoc/extern/hidden-extern-34025.rs rename to tests/rustdoc-html/extern/hidden-extern-34025.rs diff --git a/tests/rustdoc/extern/link-extern-crate-33178.rs b/tests/rustdoc-html/extern/link-extern-crate-33178.rs similarity index 100% rename from tests/rustdoc/extern/link-extern-crate-33178.rs rename to tests/rustdoc-html/extern/link-extern-crate-33178.rs diff --git a/tests/rustdoc/extern/link-extern-crate-item-30109.rs b/tests/rustdoc-html/extern/link-extern-crate-item-30109.rs similarity index 100% rename from tests/rustdoc/extern/link-extern-crate-item-30109.rs rename to tests/rustdoc-html/extern/link-extern-crate-item-30109.rs diff --git a/tests/rustdoc/extern/link-extern-crate-title-33178.rs b/tests/rustdoc-html/extern/link-extern-crate-title-33178.rs similarity index 100% rename from tests/rustdoc/extern/link-extern-crate-title-33178.rs rename to tests/rustdoc-html/extern/link-extern-crate-title-33178.rs diff --git a/tests/rustdoc-html/extern/pub-extern-crate-150176.rs b/tests/rustdoc-html/extern/pub-extern-crate-150176.rs new file mode 100644 index 000000000000..e557b1607182 --- /dev/null +++ b/tests/rustdoc-html/extern/pub-extern-crate-150176.rs @@ -0,0 +1,9 @@ +//@ aux-build:pub-extern-crate.rs + +// A refactor had left us missing the closing tags, +// ensure that they are present. +// https://github.com/rust-lang/rust/issues/150176 + +//@ has pub_extern_crate_150176/index.html +//@ hasraw - '

pub extern crate inner;
' +pub extern crate inner; diff --git a/tests/rustdoc/extern/pub-extern-crate.rs b/tests/rustdoc-html/extern/pub-extern-crate.rs similarity index 100% rename from tests/rustdoc/extern/pub-extern-crate.rs rename to tests/rustdoc-html/extern/pub-extern-crate.rs diff --git a/tests/rustdoc/extern/unsafe-extern-blocks.rs b/tests/rustdoc-html/extern/unsafe-extern-blocks.rs similarity index 100% rename from tests/rustdoc/extern/unsafe-extern-blocks.rs rename to tests/rustdoc-html/extern/unsafe-extern-blocks.rs diff --git a/tests/rustdoc/extern/unused-extern-crate.rs b/tests/rustdoc-html/extern/unused-extern-crate.rs similarity index 100% rename from tests/rustdoc/extern/unused-extern-crate.rs rename to tests/rustdoc-html/extern/unused-extern-crate.rs diff --git a/tests/rustdoc/extremely_long_typename.extremely_long_typename.html b/tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html similarity index 100% rename from tests/rustdoc/extremely_long_typename.extremely_long_typename.html rename to tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html diff --git a/tests/rustdoc/extremely_long_typename.rs b/tests/rustdoc-html/extremely_long_typename.rs similarity index 100% rename from tests/rustdoc/extremely_long_typename.rs rename to tests/rustdoc-html/extremely_long_typename.rs diff --git a/tests/rustdoc/feature-gate-doc_auto_cfg.rs b/tests/rustdoc-html/feature-gate-doc_auto_cfg.rs similarity index 100% rename from tests/rustdoc/feature-gate-doc_auto_cfg.rs rename to tests/rustdoc-html/feature-gate-doc_auto_cfg.rs diff --git a/tests/rustdoc/ffi.rs b/tests/rustdoc-html/ffi.rs similarity index 100% rename from tests/rustdoc/ffi.rs rename to tests/rustdoc-html/ffi.rs diff --git a/tests/rustdoc/file-creation-111249.rs b/tests/rustdoc-html/file-creation-111249.rs similarity index 100% rename from tests/rustdoc/file-creation-111249.rs rename to tests/rustdoc-html/file-creation-111249.rs diff --git a/tests/rustdoc/files-creation-hidden.rs b/tests/rustdoc-html/files-creation-hidden.rs similarity index 100% rename from tests/rustdoc/files-creation-hidden.rs rename to tests/rustdoc-html/files-creation-hidden.rs diff --git a/tests/rustdoc-html/final-trait-method.rs b/tests/rustdoc-html/final-trait-method.rs new file mode 100644 index 000000000000..016578a8b0e7 --- /dev/null +++ b/tests/rustdoc-html/final-trait-method.rs @@ -0,0 +1,22 @@ +#![feature(final_associated_functions)] + +//@ has final_trait_method/trait.Item.html +pub trait Item { + //@ has - '//*[@id="method.foo"]' 'final fn foo()' + //@ !has - '//*[@id="method.foo"]' 'default fn foo()' + final fn foo() {} + + //@ has - '//*[@id="method.bar"]' 'fn bar()' + //@ !has - '//*[@id="method.bar"]' 'default fn bar()' + //@ !has - '//*[@id="method.bar"]' 'final fn bar()' + fn bar() {} +} + +//@ has final_trait_method/struct.Foo.html +pub struct Foo; +impl Item for Foo { + //@ has - '//*[@id="method.bar"]' 'fn bar()' + //@ !has - '//*[@id="method.bar"]' 'final fn bar()' + //@ !has - '//*[@id="method.bar"]' 'default fn bar()' + fn bar() {} +} diff --git a/tests/rustdoc/fn-bound.rs b/tests/rustdoc-html/fn-bound.rs similarity index 100% rename from tests/rustdoc/fn-bound.rs rename to tests/rustdoc-html/fn-bound.rs diff --git a/tests/rustdoc/fn-pointer-arg-name.rs b/tests/rustdoc-html/fn-pointer-arg-name.rs similarity index 100% rename from tests/rustdoc/fn-pointer-arg-name.rs rename to tests/rustdoc-html/fn-pointer-arg-name.rs diff --git a/tests/rustdoc/fn-sidebar.rs b/tests/rustdoc-html/fn-sidebar.rs similarity index 100% rename from tests/rustdoc/fn-sidebar.rs rename to tests/rustdoc-html/fn-sidebar.rs diff --git a/tests/rustdoc/fn-type.rs b/tests/rustdoc-html/fn-type.rs similarity index 100% rename from tests/rustdoc/fn-type.rs rename to tests/rustdoc-html/fn-type.rs diff --git a/tests/rustdoc/footnote-definition-without-blank-line-100638.rs b/tests/rustdoc-html/footnote-definition-without-blank-line-100638.rs similarity index 100% rename from tests/rustdoc/footnote-definition-without-blank-line-100638.rs rename to tests/rustdoc-html/footnote-definition-without-blank-line-100638.rs diff --git a/tests/rustdoc/footnote-ids.rs b/tests/rustdoc-html/footnote-ids.rs similarity index 100% rename from tests/rustdoc/footnote-ids.rs rename to tests/rustdoc-html/footnote-ids.rs diff --git a/tests/rustdoc/footnote-in-summary.rs b/tests/rustdoc-html/footnote-in-summary.rs similarity index 100% rename from tests/rustdoc/footnote-in-summary.rs rename to tests/rustdoc-html/footnote-in-summary.rs diff --git a/tests/rustdoc/footnote-reference-ids.rs b/tests/rustdoc-html/footnote-reference-ids.rs similarity index 100% rename from tests/rustdoc/footnote-reference-ids.rs rename to tests/rustdoc-html/footnote-reference-ids.rs diff --git a/tests/rustdoc/footnote-reference-in-footnote-def.rs b/tests/rustdoc-html/footnote-reference-in-footnote-def.rs similarity index 100% rename from tests/rustdoc/footnote-reference-in-footnote-def.rs rename to tests/rustdoc-html/footnote-reference-in-footnote-def.rs diff --git a/tests/rustdoc/force-target-feature.rs b/tests/rustdoc-html/force-target-feature.rs similarity index 100% rename from tests/rustdoc/force-target-feature.rs rename to tests/rustdoc-html/force-target-feature.rs diff --git a/tests/rustdoc/force-unstable-if-unmarked-106421-not-internal.rs b/tests/rustdoc-html/force-unstable-if-unmarked-106421-not-internal.rs similarity index 100% rename from tests/rustdoc/force-unstable-if-unmarked-106421-not-internal.rs rename to tests/rustdoc-html/force-unstable-if-unmarked-106421-not-internal.rs diff --git a/tests/rustdoc/force-unstable-if-unmarked-106421.rs b/tests/rustdoc-html/force-unstable-if-unmarked-106421.rs similarity index 100% rename from tests/rustdoc/force-unstable-if-unmarked-106421.rs rename to tests/rustdoc-html/force-unstable-if-unmarked-106421.rs diff --git a/tests/rustdoc/foreigntype.rs b/tests/rustdoc-html/foreigntype.rs similarity index 100% rename from tests/rustdoc/foreigntype.rs rename to tests/rustdoc-html/foreigntype.rs diff --git a/tests/rustdoc/generic-associated-types/gat-elided-lifetime-94683.rs b/tests/rustdoc-html/generic-associated-types/gat-elided-lifetime-94683.rs similarity index 100% rename from tests/rustdoc/generic-associated-types/gat-elided-lifetime-94683.rs rename to tests/rustdoc-html/generic-associated-types/gat-elided-lifetime-94683.rs diff --git a/tests/rustdoc/generic-associated-types/gat-linkification-109488.rs b/tests/rustdoc-html/generic-associated-types/gat-linkification-109488.rs similarity index 100% rename from tests/rustdoc/generic-associated-types/gat-linkification-109488.rs rename to tests/rustdoc-html/generic-associated-types/gat-linkification-109488.rs diff --git a/tests/rustdoc/generic-associated-types/gats.rs b/tests/rustdoc-html/generic-associated-types/gats.rs similarity index 100% rename from tests/rustdoc/generic-associated-types/gats.rs rename to tests/rustdoc-html/generic-associated-types/gats.rs diff --git a/tests/rustdoc/glob-shadowing.rs b/tests/rustdoc-html/glob-shadowing.rs similarity index 86% rename from tests/rustdoc/glob-shadowing.rs rename to tests/rustdoc-html/glob-shadowing.rs index d9e9ead3f9a9..c1eeb7e663e7 100644 --- a/tests/rustdoc/glob-shadowing.rs +++ b/tests/rustdoc-html/glob-shadowing.rs @@ -1,9 +1,9 @@ //@ has 'glob_shadowing/index.html' -//@ count - '//dt' 6 -//@ !has - '//dd' 'sub1::describe' +//@ count - '//dt' 7 +//@ !has - '//dd' 'sub1::describe1' //@ has - '//dd' 'sub2::describe' -//@ !has - '//dd' 'sub1::describe2' +//@ has - '//dd' 'sub1::describe2' //@ !has - '//dd' 'sub1::prelude' //@ has - '//dd' 'mod::prelude' @@ -18,7 +18,7 @@ mod sub1 { // this should be shadowed by sub2::describe - /// sub1::describe + /// sub1::describe1 pub fn describe() -> &'static str { "sub1::describe" } @@ -33,7 +33,9 @@ mod sub1 { pub struct Foo; // this should be shadowed, - // because both sub1::describe2 and sub3::describe2 are from glob reexport + // because both sub1::describe2 and sub3::describe2 are from glob reexport, + // but it is still usable from other crates under the `ambiguous_glob_imports` lint, + // so it is reachable and documented /// sub1::describe2 pub fn describe2() -> &'static str { "sub1::describe2" diff --git a/tests/rustdoc/heading-levels-89309.rs b/tests/rustdoc-html/heading-levels-89309.rs similarity index 100% rename from tests/rustdoc/heading-levels-89309.rs rename to tests/rustdoc-html/heading-levels-89309.rs diff --git a/tests/rustdoc/heterogeneous-concat.rs b/tests/rustdoc-html/heterogeneous-concat.rs similarity index 100% rename from tests/rustdoc/heterogeneous-concat.rs rename to tests/rustdoc-html/heterogeneous-concat.rs diff --git a/tests/rustdoc/hidden-line.rs b/tests/rustdoc-html/hidden-line.rs similarity index 100% rename from tests/rustdoc/hidden-line.rs rename to tests/rustdoc-html/hidden-line.rs diff --git a/tests/rustdoc/hidden-methods.rs b/tests/rustdoc-html/hidden-methods.rs similarity index 100% rename from tests/rustdoc/hidden-methods.rs rename to tests/rustdoc-html/hidden-methods.rs diff --git a/tests/rustdoc/hidden-trait-methods-with-document-hidden-items.rs b/tests/rustdoc-html/hidden-trait-methods-with-document-hidden-items.rs similarity index 100% rename from tests/rustdoc/hidden-trait-methods-with-document-hidden-items.rs rename to tests/rustdoc-html/hidden-trait-methods-with-document-hidden-items.rs diff --git a/tests/rustdoc/hidden-trait-methods.rs b/tests/rustdoc-html/hidden-trait-methods.rs similarity index 100% rename from tests/rustdoc/hidden-trait-methods.rs rename to tests/rustdoc-html/hidden-trait-methods.rs diff --git a/tests/rustdoc/hide-unstable-trait.rs b/tests/rustdoc-html/hide-unstable-trait.rs similarity index 100% rename from tests/rustdoc/hide-unstable-trait.rs rename to tests/rustdoc-html/hide-unstable-trait.rs diff --git a/tests/rustdoc/higher-ranked-trait-bounds.rs b/tests/rustdoc-html/higher-ranked-trait-bounds.rs similarity index 100% rename from tests/rustdoc/higher-ranked-trait-bounds.rs rename to tests/rustdoc-html/higher-ranked-trait-bounds.rs diff --git a/tests/rustdoc/highlight-invalid-rust-12834.rs b/tests/rustdoc-html/highlight-invalid-rust-12834.rs similarity index 100% rename from tests/rustdoc/highlight-invalid-rust-12834.rs rename to tests/rustdoc-html/highlight-invalid-rust-12834.rs diff --git a/tests/rustdoc/ice-type-error-19181.rs b/tests/rustdoc-html/ice-type-error-19181.rs similarity index 100% rename from tests/rustdoc/ice-type-error-19181.rs rename to tests/rustdoc-html/ice-type-error-19181.rs diff --git a/tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc-html/impl/auxiliary/cross-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/cross-crate-hidden-impl-parameter.rs rename to tests/rustdoc-html/impl/auxiliary/cross-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/impl/auxiliary/extern-impl-trait.rs b/tests/rustdoc-html/impl/auxiliary/extern-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/extern-impl-trait.rs rename to tests/rustdoc-html/impl/auxiliary/extern-impl-trait.rs diff --git a/tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs b/tests/rustdoc-html/impl/auxiliary/incoherent-impl-types.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/incoherent-impl-types.rs rename to tests/rustdoc-html/impl/auxiliary/incoherent-impl-types.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-100204-aux.rs b/tests/rustdoc-html/impl/auxiliary/issue-100204-aux.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-100204-aux.rs rename to tests/rustdoc-html/impl/auxiliary/issue-100204-aux.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-17476.rs b/tests/rustdoc-html/impl/auxiliary/issue-17476.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-17476.rs rename to tests/rustdoc-html/impl/auxiliary/issue-17476.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-21092.rs b/tests/rustdoc-html/impl/auxiliary/issue-21092.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-21092.rs rename to tests/rustdoc-html/impl/auxiliary/issue-21092.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-22025.rs b/tests/rustdoc-html/impl/auxiliary/issue-22025.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-22025.rs rename to tests/rustdoc-html/impl/auxiliary/issue-22025.rs diff --git a/tests/rustdoc/impl/auxiliary/issue-53689.rs b/tests/rustdoc-html/impl/auxiliary/issue-53689.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/issue-53689.rs rename to tests/rustdoc-html/impl/auxiliary/issue-53689.rs diff --git a/tests/rustdoc/impl/auxiliary/precise-capturing.rs b/tests/rustdoc-html/impl/auxiliary/precise-capturing.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/precise-capturing.rs rename to tests/rustdoc-html/impl/auxiliary/precise-capturing.rs diff --git a/tests/rustdoc/impl/auxiliary/real_gimli.rs b/tests/rustdoc-html/impl/auxiliary/real_gimli.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/real_gimli.rs rename to tests/rustdoc-html/impl/auxiliary/real_gimli.rs diff --git a/tests/rustdoc/impl/auxiliary/realcore.rs b/tests/rustdoc-html/impl/auxiliary/realcore.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/realcore.rs rename to tests/rustdoc-html/impl/auxiliary/realcore.rs diff --git a/tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs b/tests/rustdoc-html/impl/auxiliary/rustdoc-default-impl.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/rustdoc-default-impl.rs rename to tests/rustdoc-html/impl/auxiliary/rustdoc-default-impl.rs diff --git a/tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs b/tests/rustdoc-html/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs similarity index 100% rename from tests/rustdoc/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs rename to tests/rustdoc-html/impl/auxiliary/rustdoc-impl-parts-crosscrate.rs diff --git a/tests/rustdoc/impl/blanket-impl-29503.rs b/tests/rustdoc-html/impl/blanket-impl-29503.rs similarity index 100% rename from tests/rustdoc/impl/blanket-impl-29503.rs rename to tests/rustdoc-html/impl/blanket-impl-29503.rs diff --git a/tests/rustdoc/impl/blanket-impl-78673.rs b/tests/rustdoc-html/impl/blanket-impl-78673.rs similarity index 100% rename from tests/rustdoc/impl/blanket-impl-78673.rs rename to tests/rustdoc-html/impl/blanket-impl-78673.rs diff --git a/tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs b/tests/rustdoc-html/impl/cross-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/impl/cross-crate-hidden-impl-parameter.rs rename to tests/rustdoc-html/impl/cross-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs b/tests/rustdoc-html/impl/deduplicate-glob-import-impl-21474.rs similarity index 100% rename from tests/rustdoc/impl/deduplicate-glob-import-impl-21474.rs rename to tests/rustdoc-html/impl/deduplicate-glob-import-impl-21474.rs diff --git a/tests/rustdoc/impl/deduplicate-trait-impl-22025.rs b/tests/rustdoc-html/impl/deduplicate-trait-impl-22025.rs similarity index 100% rename from tests/rustdoc/impl/deduplicate-trait-impl-22025.rs rename to tests/rustdoc-html/impl/deduplicate-trait-impl-22025.rs diff --git a/tests/rustdoc/impl/default-impl.rs b/tests/rustdoc-html/impl/default-impl.rs similarity index 100% rename from tests/rustdoc/impl/default-impl.rs rename to tests/rustdoc-html/impl/default-impl.rs diff --git a/tests/rustdoc/impl/deprecated-impls.rs b/tests/rustdoc-html/impl/deprecated-impls.rs similarity index 100% rename from tests/rustdoc/impl/deprecated-impls.rs rename to tests/rustdoc-html/impl/deprecated-impls.rs diff --git a/tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs b/tests/rustdoc-html/impl/doc-hidden-trait-implementors-33069.rs similarity index 100% rename from tests/rustdoc/impl/doc-hidden-trait-implementors-33069.rs rename to tests/rustdoc-html/impl/doc-hidden-trait-implementors-33069.rs diff --git a/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs b/tests/rustdoc-html/impl/doc_auto_cfg_nested_impl.rs similarity index 100% rename from tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs rename to tests/rustdoc-html/impl/doc_auto_cfg_nested_impl.rs diff --git a/tests/rustdoc/impl/duplicated_impl.rs b/tests/rustdoc-html/impl/duplicated_impl.rs similarity index 100% rename from tests/rustdoc/impl/duplicated_impl.rs rename to tests/rustdoc-html/impl/duplicated_impl.rs diff --git a/tests/rustdoc/impl/empty-impl-block.rs b/tests/rustdoc-html/impl/empty-impl-block.rs similarity index 100% rename from tests/rustdoc/impl/empty-impl-block.rs rename to tests/rustdoc-html/impl/empty-impl-block.rs diff --git a/tests/rustdoc/impl/empty-impls.rs b/tests/rustdoc-html/impl/empty-impls.rs similarity index 100% rename from tests/rustdoc/impl/empty-impls.rs rename to tests/rustdoc-html/impl/empty-impls.rs diff --git a/tests/rustdoc/impl/extern-impl-trait.rs b/tests/rustdoc-html/impl/extern-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/extern-impl-trait.rs rename to tests/rustdoc-html/impl/extern-impl-trait.rs diff --git a/tests/rustdoc/impl/extern-impl.rs b/tests/rustdoc-html/impl/extern-impl.rs similarity index 100% rename from tests/rustdoc/impl/extern-impl.rs rename to tests/rustdoc-html/impl/extern-impl.rs diff --git a/tests/rustdoc/impl/foreign-implementors-js-43701.rs b/tests/rustdoc-html/impl/foreign-implementors-js-43701.rs similarity index 100% rename from tests/rustdoc/impl/foreign-implementors-js-43701.rs rename to tests/rustdoc-html/impl/foreign-implementors-js-43701.rs diff --git a/tests/rustdoc/impl/generic-impl.rs b/tests/rustdoc-html/impl/generic-impl.rs similarity index 100% rename from tests/rustdoc/impl/generic-impl.rs rename to tests/rustdoc-html/impl/generic-impl.rs diff --git a/tests/rustdoc/impl/hidden-implementors-90781.rs b/tests/rustdoc-html/impl/hidden-implementors-90781.rs similarity index 100% rename from tests/rustdoc/impl/hidden-implementors-90781.rs rename to tests/rustdoc-html/impl/hidden-implementors-90781.rs diff --git a/tests/rustdoc/impl/hidden-impls.rs b/tests/rustdoc-html/impl/hidden-impls.rs similarity index 100% rename from tests/rustdoc/impl/hidden-impls.rs rename to tests/rustdoc-html/impl/hidden-impls.rs diff --git a/tests/rustdoc/impl/hidden-trait-struct-impls.rs b/tests/rustdoc-html/impl/hidden-trait-struct-impls.rs similarity index 100% rename from tests/rustdoc/impl/hidden-trait-struct-impls.rs rename to tests/rustdoc-html/impl/hidden-trait-struct-impls.rs diff --git a/tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs b/tests/rustdoc-html/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs similarity index 100% rename from tests/rustdoc/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs rename to tests/rustdoc-html/impl/hide-mut-methods-if-no-derefmut-impl-74083.rs diff --git a/tests/rustdoc/impl/impl-alias-substituted.rs b/tests/rustdoc-html/impl/impl-alias-substituted.rs similarity index 100% rename from tests/rustdoc/impl/impl-alias-substituted.rs rename to tests/rustdoc-html/impl/impl-alias-substituted.rs diff --git a/tests/rustdoc/impl/impl-assoc-type-21092.rs b/tests/rustdoc-html/impl/impl-assoc-type-21092.rs similarity index 100% rename from tests/rustdoc/impl/impl-assoc-type-21092.rs rename to tests/rustdoc-html/impl/impl-assoc-type-21092.rs diff --git a/tests/rustdoc/impl/impl-associated-items-order.rs b/tests/rustdoc-html/impl/impl-associated-items-order.rs similarity index 100% rename from tests/rustdoc/impl/impl-associated-items-order.rs rename to tests/rustdoc-html/impl/impl-associated-items-order.rs diff --git a/tests/rustdoc/impl/impl-associated-items-sidebar.rs b/tests/rustdoc-html/impl/impl-associated-items-sidebar.rs similarity index 100% rename from tests/rustdoc/impl/impl-associated-items-sidebar.rs rename to tests/rustdoc-html/impl/impl-associated-items-sidebar.rs diff --git a/tests/rustdoc/impl/impl-blanket-53689.rs b/tests/rustdoc-html/impl/impl-blanket-53689.rs similarity index 100% rename from tests/rustdoc/impl/impl-blanket-53689.rs rename to tests/rustdoc-html/impl/impl-blanket-53689.rs diff --git a/tests/rustdoc/impl/impl-box.rs b/tests/rustdoc-html/impl/impl-box.rs similarity index 100% rename from tests/rustdoc/impl/impl-box.rs rename to tests/rustdoc-html/impl/impl-box.rs diff --git a/tests/rustdoc/impl/impl-disambiguation.rs b/tests/rustdoc-html/impl/impl-disambiguation.rs similarity index 100% rename from tests/rustdoc/impl/impl-disambiguation.rs rename to tests/rustdoc-html/impl/impl-disambiguation.rs diff --git a/tests/rustdoc/impl/impl-everywhere.rs b/tests/rustdoc-html/impl/impl-everywhere.rs similarity index 100% rename from tests/rustdoc/impl/impl-everywhere.rs rename to tests/rustdoc-html/impl/impl-everywhere.rs diff --git a/tests/rustdoc/impl/impl-in-const-block.rs b/tests/rustdoc-html/impl/impl-in-const-block.rs similarity index 100% rename from tests/rustdoc/impl/impl-in-const-block.rs rename to tests/rustdoc-html/impl/impl-in-const-block.rs diff --git a/tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs b/tests/rustdoc-html/impl/impl-on-ty-alias-issue-119015.rs similarity index 100% rename from tests/rustdoc/impl/impl-on-ty-alias-issue-119015.rs rename to tests/rustdoc-html/impl/impl-on-ty-alias-issue-119015.rs diff --git a/tests/rustdoc/impl/impl-parts-crosscrate.rs b/tests/rustdoc-html/impl/impl-parts-crosscrate.rs similarity index 100% rename from tests/rustdoc/impl/impl-parts-crosscrate.rs rename to tests/rustdoc-html/impl/impl-parts-crosscrate.rs diff --git a/tests/rustdoc/impl/impl-parts.rs b/tests/rustdoc-html/impl/impl-parts.rs similarity index 100% rename from tests/rustdoc/impl/impl-parts.rs rename to tests/rustdoc-html/impl/impl-parts.rs diff --git a/tests/rustdoc/impl/impl-ref-20175.rs b/tests/rustdoc-html/impl/impl-ref-20175.rs similarity index 100% rename from tests/rustdoc/impl/impl-ref-20175.rs rename to tests/rustdoc-html/impl/impl-ref-20175.rs diff --git a/tests/rustdoc/impl/impl-trait-43869.rs b/tests/rustdoc-html/impl/impl-trait-43869.rs similarity index 100% rename from tests/rustdoc/impl/impl-trait-43869.rs rename to tests/rustdoc-html/impl/impl-trait-43869.rs diff --git a/tests/rustdoc/impl/impl-trait-alias.rs b/tests/rustdoc-html/impl/impl-trait-alias.rs similarity index 100% rename from tests/rustdoc/impl/impl-trait-alias.rs rename to tests/rustdoc-html/impl/impl-trait-alias.rs diff --git a/tests/rustdoc/impl/impl-trait-precise-capturing.rs b/tests/rustdoc-html/impl/impl-trait-precise-capturing.rs similarity index 100% rename from tests/rustdoc/impl/impl-trait-precise-capturing.rs rename to tests/rustdoc-html/impl/impl-trait-precise-capturing.rs diff --git a/tests/rustdoc/impl/impl-type-parameter-33592.rs b/tests/rustdoc-html/impl/impl-type-parameter-33592.rs similarity index 100% rename from tests/rustdoc/impl/impl-type-parameter-33592.rs rename to tests/rustdoc-html/impl/impl-type-parameter-33592.rs diff --git a/tests/rustdoc/impl/implementor-stable-version.rs b/tests/rustdoc-html/impl/implementor-stable-version.rs similarity index 100% rename from tests/rustdoc/impl/implementor-stable-version.rs rename to tests/rustdoc-html/impl/implementor-stable-version.rs diff --git a/tests/rustdoc/impl/implementors-unstable-75588.rs b/tests/rustdoc-html/impl/implementors-unstable-75588.rs similarity index 100% rename from tests/rustdoc/impl/implementors-unstable-75588.rs rename to tests/rustdoc-html/impl/implementors-unstable-75588.rs diff --git a/tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs b/tests/rustdoc-html/impl/inline-impl-through-glob-import-100204.rs similarity index 100% rename from tests/rustdoc/impl/inline-impl-through-glob-import-100204.rs rename to tests/rustdoc-html/impl/inline-impl-through-glob-import-100204.rs diff --git a/tests/rustdoc/impl/manual_impl.rs b/tests/rustdoc-html/impl/manual_impl.rs similarity index 100% rename from tests/rustdoc/impl/manual_impl.rs rename to tests/rustdoc-html/impl/manual_impl.rs diff --git a/tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs b/tests/rustdoc-html/impl/method-link-foreign-trait-impl-17476.rs similarity index 100% rename from tests/rustdoc/impl/method-link-foreign-trait-impl-17476.rs rename to tests/rustdoc-html/impl/method-link-foreign-trait-impl-17476.rs diff --git a/tests/rustdoc/impl/module-impls.rs b/tests/rustdoc-html/impl/module-impls.rs similarity index 100% rename from tests/rustdoc/impl/module-impls.rs rename to tests/rustdoc-html/impl/module-impls.rs diff --git a/tests/rustdoc/impl/must_implement_one_of.rs b/tests/rustdoc-html/impl/must_implement_one_of.rs similarity index 100% rename from tests/rustdoc/impl/must_implement_one_of.rs rename to tests/rustdoc-html/impl/must_implement_one_of.rs diff --git a/tests/rustdoc/impl/negative-impl-no-items.rs b/tests/rustdoc-html/impl/negative-impl-no-items.rs similarity index 100% rename from tests/rustdoc/impl/negative-impl-no-items.rs rename to tests/rustdoc-html/impl/negative-impl-no-items.rs diff --git a/tests/rustdoc/impl/negative-impl-sidebar.rs b/tests/rustdoc-html/impl/negative-impl-sidebar.rs similarity index 100% rename from tests/rustdoc/impl/negative-impl-sidebar.rs rename to tests/rustdoc-html/impl/negative-impl-sidebar.rs diff --git a/tests/rustdoc/impl/negative-impl.rs b/tests/rustdoc-html/impl/negative-impl.rs similarity index 100% rename from tests/rustdoc/impl/negative-impl.rs rename to tests/rustdoc-html/impl/negative-impl.rs diff --git a/tests/rustdoc/impl/return-impl-trait.rs b/tests/rustdoc-html/impl/return-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/return-impl-trait.rs rename to tests/rustdoc-html/impl/return-impl-trait.rs diff --git a/tests/rustdoc/impl/rustc-incoherent-impls.rs b/tests/rustdoc-html/impl/rustc-incoherent-impls.rs similarity index 100% rename from tests/rustdoc/impl/rustc-incoherent-impls.rs rename to tests/rustdoc-html/impl/rustc-incoherent-impls.rs diff --git a/tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs b/tests/rustdoc-html/impl/same-crate-hidden-impl-parameter.rs similarity index 100% rename from tests/rustdoc/impl/same-crate-hidden-impl-parameter.rs rename to tests/rustdoc-html/impl/same-crate-hidden-impl-parameter.rs diff --git a/tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs b/tests/rustdoc-html/impl/sidebar-trait-impl-disambiguate-78701.rs similarity index 100% rename from tests/rustdoc/impl/sidebar-trait-impl-disambiguate-78701.rs rename to tests/rustdoc-html/impl/sidebar-trait-impl-disambiguate-78701.rs diff --git a/tests/rustdoc/impl/struct-implementations-title.rs b/tests/rustdoc-html/impl/struct-implementations-title.rs similarity index 100% rename from tests/rustdoc/impl/struct-implementations-title.rs rename to tests/rustdoc-html/impl/struct-implementations-title.rs diff --git a/tests/rustdoc/impl/trait-impl.rs b/tests/rustdoc-html/impl/trait-impl.rs similarity index 100% rename from tests/rustdoc/impl/trait-impl.rs rename to tests/rustdoc-html/impl/trait-impl.rs diff --git a/tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs b/tests/rustdoc-html/impl/trait-implementations-duplicate-self-45584.rs similarity index 100% rename from tests/rustdoc/impl/trait-implementations-duplicate-self-45584.rs rename to tests/rustdoc-html/impl/trait-implementations-duplicate-self-45584.rs diff --git a/tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs b/tests/rustdoc-html/impl/underscore-type-in-trait-impl-96381.rs similarity index 100% rename from tests/rustdoc/impl/underscore-type-in-trait-impl-96381.rs rename to tests/rustdoc-html/impl/underscore-type-in-trait-impl-96381.rs diff --git a/tests/rustdoc/impl/universal-impl-trait.rs b/tests/rustdoc-html/impl/universal-impl-trait.rs similarity index 100% rename from tests/rustdoc/impl/universal-impl-trait.rs rename to tests/rustdoc-html/impl/universal-impl-trait.rs diff --git a/tests/rustdoc/impl/unneeded-trait-implementations-title.rs b/tests/rustdoc-html/impl/unneeded-trait-implementations-title.rs similarity index 100% rename from tests/rustdoc/impl/unneeded-trait-implementations-title.rs rename to tests/rustdoc-html/impl/unneeded-trait-implementations-title.rs diff --git a/tests/rustdoc-html/import-remapped-paths.rs b/tests/rustdoc-html/import-remapped-paths.rs new file mode 100644 index 000000000000..9e7518f7c017 --- /dev/null +++ b/tests/rustdoc-html/import-remapped-paths.rs @@ -0,0 +1,19 @@ +// This is a regression for `--remap-path-prefix` in an auxiliary dependency. +// +// We want to make sure that we can still have the "Source" links to the dependency +// even if its paths are remapped. +// +// See also rust-lang/rust#150100 + +//@ aux-build:remapped-paths.rs +//@ build-aux-docs + +#![crate_name = "foo"] + +extern crate remapped_paths; + +//@ has foo/struct.MyStruct.html +//@ has - '//a[@href="../src/remapped_paths/remapped-paths.rs.html#3"]' 'Source' +//@ has - '//a[@href="../src/remapped_paths/remapped-paths.rs.html#8"]' 'Source' + +pub use remapped_paths::MyStruct; diff --git a/tests/rustdoc/impossible-default.rs b/tests/rustdoc-html/impossible-default.rs similarity index 100% rename from tests/rustdoc/impossible-default.rs rename to tests/rustdoc-html/impossible-default.rs diff --git a/tests/rustdoc/include_str_cut.rs b/tests/rustdoc-html/include_str_cut.rs similarity index 100% rename from tests/rustdoc/include_str_cut.rs rename to tests/rustdoc-html/include_str_cut.rs diff --git a/tests/rustdoc/index-page.rs b/tests/rustdoc-html/index-page.rs similarity index 100% rename from tests/rustdoc/index-page.rs rename to tests/rustdoc-html/index-page.rs diff --git a/tests/rustdoc/infinite-redirection-16265-1.rs b/tests/rustdoc-html/infinite-redirection-16265-1.rs similarity index 100% rename from tests/rustdoc/infinite-redirection-16265-1.rs rename to tests/rustdoc-html/infinite-redirection-16265-1.rs diff --git a/tests/rustdoc/infinite-redirection-16265-2.rs b/tests/rustdoc-html/infinite-redirection-16265-2.rs similarity index 100% rename from tests/rustdoc/infinite-redirection-16265-2.rs rename to tests/rustdoc-html/infinite-redirection-16265-2.rs diff --git a/tests/rustdoc/infinite-redirection.rs b/tests/rustdoc-html/infinite-redirection.rs similarity index 100% rename from tests/rustdoc/infinite-redirection.rs rename to tests/rustdoc-html/infinite-redirection.rs diff --git a/tests/rustdoc/inherent-projections.rs b/tests/rustdoc-html/inherent-projections.rs similarity index 100% rename from tests/rustdoc/inherent-projections.rs rename to tests/rustdoc-html/inherent-projections.rs diff --git a/tests/rustdoc/inline-default-methods.rs b/tests/rustdoc-html/inline-default-methods.rs similarity index 100% rename from tests/rustdoc/inline-default-methods.rs rename to tests/rustdoc-html/inline-default-methods.rs diff --git a/tests/rustdoc/inline-rename-34473.rs b/tests/rustdoc-html/inline-rename-34473.rs similarity index 100% rename from tests/rustdoc/inline-rename-34473.rs rename to tests/rustdoc-html/inline-rename-34473.rs diff --git a/tests/rustdoc/inline_cross/add-docs.rs b/tests/rustdoc-html/inline_cross/add-docs.rs similarity index 100% rename from tests/rustdoc/inline_cross/add-docs.rs rename to tests/rustdoc-html/inline_cross/add-docs.rs diff --git a/tests/rustdoc/inline_cross/assoc-const-equality.rs b/tests/rustdoc-html/inline_cross/assoc-const-equality.rs similarity index 100% rename from tests/rustdoc/inline_cross/assoc-const-equality.rs rename to tests/rustdoc-html/inline_cross/assoc-const-equality.rs diff --git a/tests/rustdoc/inline_cross/assoc-items.rs b/tests/rustdoc-html/inline_cross/assoc-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/assoc-items.rs rename to tests/rustdoc-html/inline_cross/assoc-items.rs diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out0.html similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.out0.html rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out0.html diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out2.html similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.out2.html rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out2.html diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.out9.html b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out9.html similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.out9.html rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.out9.html diff --git a/tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs b/tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.rs similarity index 100% rename from tests/rustdoc/inline_cross/assoc_item_trait_bounds.rs rename to tests/rustdoc-html/inline_cross/assoc_item_trait_bounds.rs diff --git a/tests/rustdoc/inline_cross/async-fn.rs b/tests/rustdoc-html/inline_cross/async-fn.rs similarity index 100% rename from tests/rustdoc/inline_cross/async-fn.rs rename to tests/rustdoc-html/inline_cross/async-fn.rs diff --git a/tests/rustdoc/inline_cross/attributes.rs b/tests/rustdoc-html/inline_cross/attributes.rs similarity index 100% rename from tests/rustdoc/inline_cross/attributes.rs rename to tests/rustdoc-html/inline_cross/attributes.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/add-docs.rs b/tests/rustdoc-html/inline_cross/auxiliary/add-docs.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/add-docs.rs rename to tests/rustdoc-html/inline_cross/auxiliary/add-docs.rs diff --git a/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs new file mode 100644 index 000000000000..939740d8f918 --- /dev/null +++ b/tests/rustdoc-html/inline_cross/auxiliary/assoc-const-equality.rs @@ -0,0 +1,8 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +pub fn accept(_: impl Trait) {} + +pub trait Trait { + type const K: i32; +} diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-items.rs b/tests/rustdoc-html/inline_cross/auxiliary/assoc-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/assoc-items.rs rename to tests/rustdoc-html/inline_cross/auxiliary/assoc-items.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs b/tests/rustdoc-html/inline_cross/auxiliary/assoc_item_trait_bounds.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds.rs rename to tests/rustdoc-html/inline_cross/auxiliary/assoc_item_trait_bounds.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/async-fn.rs b/tests/rustdoc-html/inline_cross/auxiliary/async-fn.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/async-fn.rs rename to tests/rustdoc-html/inline_cross/auxiliary/async-fn.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/attributes.rs b/tests/rustdoc-html/inline_cross/auxiliary/attributes.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/attributes.rs rename to tests/rustdoc-html/inline_cross/auxiliary/attributes.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs b/tests/rustdoc-html/inline_cross/auxiliary/const-effect-param.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/const-effect-param.rs rename to tests/rustdoc-html/inline_cross/auxiliary/const-effect-param.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/cross-glob.rs b/tests/rustdoc-html/inline_cross/auxiliary/cross-glob.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/cross-glob.rs rename to tests/rustdoc-html/inline_cross/auxiliary/cross-glob.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/default-generic-args.rs b/tests/rustdoc-html/inline_cross/auxiliary/default-generic-args.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/default-generic-args.rs rename to tests/rustdoc-html/inline_cross/auxiliary/default-generic-args.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/default-trait-method.rs b/tests/rustdoc-html/inline_cross/auxiliary/default-trait-method.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/default-trait-method.rs rename to tests/rustdoc-html/inline_cross/auxiliary/default-trait-method.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs b/tests/rustdoc-html/inline_cross/auxiliary/doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/doc-auto-cfg.rs rename to tests/rustdoc-html/inline_cross/auxiliary/doc-auto-cfg.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs b/tests/rustdoc-html/inline_cross/auxiliary/dyn_trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs rename to tests/rustdoc-html/inline_cross/auxiliary/dyn_trait.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs b/tests/rustdoc-html/inline_cross/auxiliary/early-late-bound-lifetime-params.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/early-late-bound-lifetime-params.rs rename to tests/rustdoc-html/inline_cross/auxiliary/early-late-bound-lifetime-params.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/fn-ptr-ty.rs b/tests/rustdoc-html/inline_cross/auxiliary/fn-ptr-ty.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/fn-ptr-ty.rs rename to tests/rustdoc-html/inline_cross/auxiliary/fn-ptr-ty.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/generic-const-items.rs b/tests/rustdoc-html/inline_cross/auxiliary/generic-const-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/generic-const-items.rs rename to tests/rustdoc-html/inline_cross/auxiliary/generic-const-items.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs b/tests/rustdoc-html/inline_cross/auxiliary/impl-inline-without-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs rename to tests/rustdoc-html/inline_cross/auxiliary/impl-inline-without-trait.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/impl-sized.rs b/tests/rustdoc-html/inline_cross/auxiliary/impl-sized.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/impl-sized.rs rename to tests/rustdoc-html/inline_cross/auxiliary/impl-sized.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/tests/rustdoc-html/inline_cross/auxiliary/impl_trait_aux.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs rename to tests/rustdoc-html/inline_cross/auxiliary/impl_trait_aux.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/implementors_inline.rs b/tests/rustdoc-html/inline_cross/auxiliary/implementors_inline.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/implementors_inline.rs rename to tests/rustdoc-html/inline_cross/auxiliary/implementors_inline.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-21801.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-21801.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-21801.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-21801.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-23207-1.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-23207-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-23207-1.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-23207-1.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-23207-2.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-23207-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-23207-2.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-23207-2.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-24183.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-24183.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-24183.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-24183.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-27362-aux.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-27362-aux.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-27362-aux.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-27362-aux.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-29584.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-29584.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-29584.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-29584.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-33113.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-33113.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-33113.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-33113.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-46727.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-46727.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-46727.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-46727.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-57180.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-57180.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-57180.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-57180.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-76736-1.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-76736-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-76736-1.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-76736-1.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-76736-2.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-76736-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-76736-2.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-76736-2.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/issue-85454.rs b/tests/rustdoc-html/inline_cross/auxiliary/issue-85454.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/issue-85454.rs rename to tests/rustdoc-html/inline_cross/auxiliary/issue-85454.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/macro-vis.rs b/tests/rustdoc-html/inline_cross/auxiliary/macro-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/macro-vis.rs rename to tests/rustdoc-html/inline_cross/auxiliary/macro-vis.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/macros.rs b/tests/rustdoc-html/inline_cross/auxiliary/macros.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/macros.rs rename to tests/rustdoc-html/inline_cross/auxiliary/macros.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs b/tests/rustdoc-html/inline_cross/auxiliary/non_lifetime_binders.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs rename to tests/rustdoc-html/inline_cross/auxiliary/non_lifetime_binders.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/proc_macro.rs b/tests/rustdoc-html/inline_cross/auxiliary/proc_macro.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/proc_macro.rs rename to tests/rustdoc-html/inline_cross/auxiliary/proc_macro.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs b/tests/rustdoc-html/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs rename to tests/rustdoc-html/inline_cross/auxiliary/reexport-with-anonymous-lifetime-98697.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/renamed-via-module.rs b/tests/rustdoc-html/inline_cross/auxiliary/renamed-via-module.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/renamed-via-module.rs rename to tests/rustdoc-html/inline_cross/auxiliary/renamed-via-module.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs b/tests/rustdoc-html/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs rename to tests/rustdoc-html/inline_cross/auxiliary/ret-pos-impl-trait-in-trait.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden-sig.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden-sig.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden-sig.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden-sig.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-hidden.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-hidden.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs b/tests/rustdoc-html/inline_cross/auxiliary/rustdoc-trait-object-impl.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs rename to tests/rustdoc-html/inline_cross/auxiliary/rustdoc-trait-object-impl.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/trait-vis.rs b/tests/rustdoc-html/inline_cross/auxiliary/trait-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/trait-vis.rs rename to tests/rustdoc-html/inline_cross/auxiliary/trait-vis.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/use_crate.rs b/tests/rustdoc-html/inline_cross/auxiliary/use_crate.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/use_crate.rs rename to tests/rustdoc-html/inline_cross/auxiliary/use_crate.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/use_crate_2.rs b/tests/rustdoc-html/inline_cross/auxiliary/use_crate_2.rs similarity index 100% rename from tests/rustdoc/inline_cross/auxiliary/use_crate_2.rs rename to tests/rustdoc-html/inline_cross/auxiliary/use_crate_2.rs diff --git a/tests/rustdoc/inline_cross/const-effect-param.rs b/tests/rustdoc-html/inline_cross/const-effect-param.rs similarity index 100% rename from tests/rustdoc/inline_cross/const-effect-param.rs rename to tests/rustdoc-html/inline_cross/const-effect-param.rs diff --git a/tests/rustdoc/inline_cross/const-eval-46727.rs b/tests/rustdoc-html/inline_cross/const-eval-46727.rs similarity index 100% rename from tests/rustdoc/inline_cross/const-eval-46727.rs rename to tests/rustdoc-html/inline_cross/const-eval-46727.rs diff --git a/tests/rustdoc/inline_cross/const-fn-27362.rs b/tests/rustdoc-html/inline_cross/const-fn-27362.rs similarity index 100% rename from tests/rustdoc/inline_cross/const-fn-27362.rs rename to tests/rustdoc-html/inline_cross/const-fn-27362.rs diff --git a/tests/rustdoc/inline_cross/cross-glob.rs b/tests/rustdoc-html/inline_cross/cross-glob.rs similarity index 100% rename from tests/rustdoc/inline_cross/cross-glob.rs rename to tests/rustdoc-html/inline_cross/cross-glob.rs diff --git a/tests/rustdoc/inline_cross/deduplicate-inlined-items-23207.rs b/tests/rustdoc-html/inline_cross/deduplicate-inlined-items-23207.rs similarity index 100% rename from tests/rustdoc/inline_cross/deduplicate-inlined-items-23207.rs rename to tests/rustdoc-html/inline_cross/deduplicate-inlined-items-23207.rs diff --git a/tests/rustdoc/inline_cross/default-generic-args.rs b/tests/rustdoc-html/inline_cross/default-generic-args.rs similarity index 100% rename from tests/rustdoc/inline_cross/default-generic-args.rs rename to tests/rustdoc-html/inline_cross/default-generic-args.rs diff --git a/tests/rustdoc/inline_cross/default-trait-method.rs b/tests/rustdoc-html/inline_cross/default-trait-method.rs similarity index 100% rename from tests/rustdoc/inline_cross/default-trait-method.rs rename to tests/rustdoc-html/inline_cross/default-trait-method.rs diff --git a/tests/rustdoc/inline_cross/doc-auto-cfg.rs b/tests/rustdoc-html/inline_cross/doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-auto-cfg.rs rename to tests/rustdoc-html/inline_cross/doc-auto-cfg.rs diff --git a/tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs b/tests/rustdoc-html/inline_cross/doc-hidden-broken-link-28480.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-hidden-broken-link-28480.rs rename to tests/rustdoc-html/inline_cross/doc-hidden-broken-link-28480.rs diff --git a/tests/rustdoc/inline_cross/doc-hidden-extern-trait-impl-29584.rs b/tests/rustdoc-html/inline_cross/doc-hidden-extern-trait-impl-29584.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-hidden-extern-trait-impl-29584.rs rename to tests/rustdoc-html/inline_cross/doc-hidden-extern-trait-impl-29584.rs diff --git a/tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs b/tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-reachability-impl-31948-1.rs rename to tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-1.rs diff --git a/tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs b/tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-reachability-impl-31948-2.rs rename to tests/rustdoc-html/inline_cross/doc-reachability-impl-31948-2.rs diff --git a/tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs b/tests/rustdoc-html/inline_cross/doc-reachability-impl-31948.rs similarity index 100% rename from tests/rustdoc/inline_cross/doc-reachability-impl-31948.rs rename to tests/rustdoc-html/inline_cross/doc-reachability-impl-31948.rs diff --git a/tests/rustdoc/inline_cross/dyn_trait.rs b/tests/rustdoc-html/inline_cross/dyn_trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/dyn_trait.rs rename to tests/rustdoc-html/inline_cross/dyn_trait.rs diff --git a/tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs b/tests/rustdoc-html/inline_cross/early-late-bound-lifetime-params.rs similarity index 100% rename from tests/rustdoc/inline_cross/early-late-bound-lifetime-params.rs rename to tests/rustdoc-html/inline_cross/early-late-bound-lifetime-params.rs diff --git a/tests/rustdoc/inline_cross/fn-ptr-ty.rs b/tests/rustdoc-html/inline_cross/fn-ptr-ty.rs similarity index 100% rename from tests/rustdoc/inline_cross/fn-ptr-ty.rs rename to tests/rustdoc-html/inline_cross/fn-ptr-ty.rs diff --git a/tests/rustdoc/inline_cross/generic-const-items.rs b/tests/rustdoc-html/inline_cross/generic-const-items.rs similarity index 100% rename from tests/rustdoc/inline_cross/generic-const-items.rs rename to tests/rustdoc-html/inline_cross/generic-const-items.rs diff --git a/tests/rustdoc/inline_cross/hidden-use.rs b/tests/rustdoc-html/inline_cross/hidden-use.rs similarity index 100% rename from tests/rustdoc/inline_cross/hidden-use.rs rename to tests/rustdoc-html/inline_cross/hidden-use.rs diff --git a/tests/rustdoc/inline_cross/ice-import-crate-57180.rs b/tests/rustdoc-html/inline_cross/ice-import-crate-57180.rs similarity index 100% rename from tests/rustdoc/inline_cross/ice-import-crate-57180.rs rename to tests/rustdoc-html/inline_cross/ice-import-crate-57180.rs diff --git a/tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs b/tests/rustdoc-html/inline_cross/impl-dyn-trait-32881.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-dyn-trait-32881.rs rename to tests/rustdoc-html/inline_cross/impl-dyn-trait-32881.rs diff --git a/tests/rustdoc/inline_cross/impl-inline-without-trait.rs b/tests/rustdoc-html/inline_cross/impl-inline-without-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-inline-without-trait.rs rename to tests/rustdoc-html/inline_cross/impl-inline-without-trait.rs diff --git a/tests/rustdoc/inline_cross/impl-ref-33113.rs b/tests/rustdoc-html/inline_cross/impl-ref-33113.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-ref-33113.rs rename to tests/rustdoc-html/inline_cross/impl-ref-33113.rs diff --git a/tests/rustdoc/inline_cross/impl-sized.rs b/tests/rustdoc-html/inline_cross/impl-sized.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl-sized.rs rename to tests/rustdoc-html/inline_cross/impl-sized.rs diff --git a/tests/rustdoc/inline_cross/impl_trait.rs b/tests/rustdoc-html/inline_cross/impl_trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/impl_trait.rs rename to tests/rustdoc-html/inline_cross/impl_trait.rs diff --git a/tests/rustdoc/inline_cross/implementors-js.rs b/tests/rustdoc-html/inline_cross/implementors-js.rs similarity index 100% rename from tests/rustdoc/inline_cross/implementors-js.rs rename to tests/rustdoc-html/inline_cross/implementors-js.rs diff --git a/tests/rustdoc/inline_cross/inline_hidden.rs b/tests/rustdoc-html/inline_cross/inline_hidden.rs similarity index 100% rename from tests/rustdoc/inline_cross/inline_hidden.rs rename to tests/rustdoc-html/inline_cross/inline_hidden.rs diff --git a/tests/rustdoc/inline_cross/macro-vis.rs b/tests/rustdoc-html/inline_cross/macro-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/macro-vis.rs rename to tests/rustdoc-html/inline_cross/macro-vis.rs diff --git a/tests/rustdoc/inline_cross/macros.rs b/tests/rustdoc-html/inline_cross/macros.rs similarity index 100% rename from tests/rustdoc/inline_cross/macros.rs rename to tests/rustdoc-html/inline_cross/macros.rs diff --git a/tests/rustdoc/inline_cross/non_lifetime_binders.rs b/tests/rustdoc-html/inline_cross/non_lifetime_binders.rs similarity index 100% rename from tests/rustdoc/inline_cross/non_lifetime_binders.rs rename to tests/rustdoc-html/inline_cross/non_lifetime_binders.rs diff --git a/tests/rustdoc/inline_cross/proc_macro.rs b/tests/rustdoc-html/inline_cross/proc_macro.rs similarity index 100% rename from tests/rustdoc/inline_cross/proc_macro.rs rename to tests/rustdoc-html/inline_cross/proc_macro.rs diff --git a/tests/rustdoc/inline_cross/qpath-self-85454.rs b/tests/rustdoc-html/inline_cross/qpath-self-85454.rs similarity index 100% rename from tests/rustdoc/inline_cross/qpath-self-85454.rs rename to tests/rustdoc-html/inline_cross/qpath-self-85454.rs diff --git a/tests/rustdoc/inline_cross/reexport-with-anonymous-lifetime-98697.rs b/tests/rustdoc-html/inline_cross/reexport-with-anonymous-lifetime-98697.rs similarity index 100% rename from tests/rustdoc/inline_cross/reexport-with-anonymous-lifetime-98697.rs rename to tests/rustdoc-html/inline_cross/reexport-with-anonymous-lifetime-98697.rs diff --git a/tests/rustdoc/inline_cross/renamed-via-module.rs b/tests/rustdoc-html/inline_cross/renamed-via-module.rs similarity index 100% rename from tests/rustdoc/inline_cross/renamed-via-module.rs rename to tests/rustdoc-html/inline_cross/renamed-via-module.rs diff --git a/tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs b/tests/rustdoc-html/inline_cross/ret-pos-impl-trait-in-trait.rs similarity index 100% rename from tests/rustdoc/inline_cross/ret-pos-impl-trait-in-trait.rs rename to tests/rustdoc-html/inline_cross/ret-pos-impl-trait-in-trait.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-1.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-1.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-1.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-1.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-2.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-2.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-2.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-2.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-3.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-3.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-3.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-3.rs diff --git a/tests/rustdoc/inline_cross/rustc-private-76736-4.rs b/tests/rustdoc-html/inline_cross/rustc-private-76736-4.rs similarity index 100% rename from tests/rustdoc/inline_cross/rustc-private-76736-4.rs rename to tests/rustdoc-html/inline_cross/rustc-private-76736-4.rs diff --git a/tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html b/tests/rustdoc-html/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html similarity index 100% rename from tests/rustdoc/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html rename to tests/rustdoc-html/inline_cross/self-sized-bounds-24183.method_no_where_self_sized.html diff --git a/tests/rustdoc/inline_cross/self-sized-bounds-24183.rs b/tests/rustdoc-html/inline_cross/self-sized-bounds-24183.rs similarity index 100% rename from tests/rustdoc/inline_cross/self-sized-bounds-24183.rs rename to tests/rustdoc-html/inline_cross/self-sized-bounds-24183.rs diff --git a/tests/rustdoc/inline_cross/sugar-closure-crate-21801.rs b/tests/rustdoc-html/inline_cross/sugar-closure-crate-21801.rs similarity index 100% rename from tests/rustdoc/inline_cross/sugar-closure-crate-21801.rs rename to tests/rustdoc-html/inline_cross/sugar-closure-crate-21801.rs diff --git a/tests/rustdoc/inline_cross/trait-vis.rs b/tests/rustdoc-html/inline_cross/trait-vis.rs similarity index 100% rename from tests/rustdoc/inline_cross/trait-vis.rs rename to tests/rustdoc-html/inline_cross/trait-vis.rs diff --git a/tests/rustdoc/inline_cross/use_crate.rs b/tests/rustdoc-html/inline_cross/use_crate.rs similarity index 100% rename from tests/rustdoc/inline_cross/use_crate.rs rename to tests/rustdoc-html/inline_cross/use_crate.rs diff --git a/tests/rustdoc/inline_local/blanket-impl-reexported-trait-94183.rs b/tests/rustdoc-html/inline_local/blanket-impl-reexported-trait-94183.rs similarity index 100% rename from tests/rustdoc/inline_local/blanket-impl-reexported-trait-94183.rs rename to tests/rustdoc-html/inline_local/blanket-impl-reexported-trait-94183.rs diff --git a/tests/rustdoc/inline_local/doc-no-inline-32343.rs b/tests/rustdoc-html/inline_local/doc-no-inline-32343.rs similarity index 100% rename from tests/rustdoc/inline_local/doc-no-inline-32343.rs rename to tests/rustdoc-html/inline_local/doc-no-inline-32343.rs diff --git a/tests/rustdoc/inline_local/enum-variant-reexport-46766.rs b/tests/rustdoc-html/inline_local/enum-variant-reexport-46766.rs similarity index 100% rename from tests/rustdoc/inline_local/enum-variant-reexport-46766.rs rename to tests/rustdoc-html/inline_local/enum-variant-reexport-46766.rs diff --git a/tests/rustdoc/inline_local/fully-stable-path-is-better.rs b/tests/rustdoc-html/inline_local/fully-stable-path-is-better.rs similarity index 100% rename from tests/rustdoc/inline_local/fully-stable-path-is-better.rs rename to tests/rustdoc-html/inline_local/fully-stable-path-is-better.rs diff --git a/tests/rustdoc/inline_local/glob-extern-document-private-items.rs b/tests/rustdoc-html/inline_local/glob-extern-document-private-items.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-extern-document-private-items.rs rename to tests/rustdoc-html/inline_local/glob-extern-document-private-items.rs diff --git a/tests/rustdoc/inline_local/glob-extern.rs b/tests/rustdoc-html/inline_local/glob-extern.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-extern.rs rename to tests/rustdoc-html/inline_local/glob-extern.rs diff --git a/tests/rustdoc/inline_local/glob-private-document-private-items.rs b/tests/rustdoc-html/inline_local/glob-private-document-private-items.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-private-document-private-items.rs rename to tests/rustdoc-html/inline_local/glob-private-document-private-items.rs diff --git a/tests/rustdoc/inline_local/glob-private.rs b/tests/rustdoc-html/inline_local/glob-private.rs similarity index 100% rename from tests/rustdoc/inline_local/glob-private.rs rename to tests/rustdoc-html/inline_local/glob-private.rs diff --git a/tests/rustdoc/inline_local/hidden-use.rs b/tests/rustdoc-html/inline_local/hidden-use.rs similarity index 100% rename from tests/rustdoc/inline_local/hidden-use.rs rename to tests/rustdoc-html/inline_local/hidden-use.rs diff --git a/tests/rustdoc/inline_local/macro_by_example.rs b/tests/rustdoc-html/inline_local/macro_by_example.rs similarity index 100% rename from tests/rustdoc/inline_local/macro_by_example.rs rename to tests/rustdoc-html/inline_local/macro_by_example.rs diff --git a/tests/rustdoc/inline_local/parent-path-is-better.rs b/tests/rustdoc-html/inline_local/parent-path-is-better.rs similarity index 100% rename from tests/rustdoc/inline_local/parent-path-is-better.rs rename to tests/rustdoc-html/inline_local/parent-path-is-better.rs diff --git a/tests/rustdoc/inline_local/please_inline.rs b/tests/rustdoc-html/inline_local/please_inline.rs similarity index 100% rename from tests/rustdoc/inline_local/please_inline.rs rename to tests/rustdoc-html/inline_local/please_inline.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-81141-2.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141-2.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-81141-2.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141-2.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-81141.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-generics-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-generics-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-generics-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-generics-81141.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-hidden-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-hidden-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-hidden-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-hidden-81141.rs diff --git a/tests/rustdoc/inline_local/private-reexport-in-public-api-private-81141.rs b/tests/rustdoc-html/inline_local/private-reexport-in-public-api-private-81141.rs similarity index 100% rename from tests/rustdoc/inline_local/private-reexport-in-public-api-private-81141.rs rename to tests/rustdoc-html/inline_local/private-reexport-in-public-api-private-81141.rs diff --git a/tests/rustdoc/inline_local/pub-re-export-28537.rs b/tests/rustdoc-html/inline_local/pub-re-export-28537.rs similarity index 100% rename from tests/rustdoc/inline_local/pub-re-export-28537.rs rename to tests/rustdoc-html/inline_local/pub-re-export-28537.rs diff --git a/tests/rustdoc/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs b/tests/rustdoc-html/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs similarity index 100% rename from tests/rustdoc/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs rename to tests/rustdoc-html/inline_local/reexported-macro-and-macro-export-sidebar-89852.rs diff --git a/tests/rustdoc/inline_local/staged-inline.rs b/tests/rustdoc-html/inline_local/staged-inline.rs similarity index 100% rename from tests/rustdoc/inline_local/staged-inline.rs rename to tests/rustdoc-html/inline_local/staged-inline.rs diff --git a/tests/rustdoc/inline_local/trait-vis.rs b/tests/rustdoc-html/inline_local/trait-vis.rs similarity index 100% rename from tests/rustdoc/inline_local/trait-vis.rs rename to tests/rustdoc-html/inline_local/trait-vis.rs diff --git a/tests/rustdoc/internal.rs b/tests/rustdoc-html/internal.rs similarity index 100% rename from tests/rustdoc/internal.rs rename to tests/rustdoc-html/internal.rs diff --git a/tests/rustdoc/intra-doc-crate/auxiliary/self.rs b/tests/rustdoc-html/intra-doc-crate/auxiliary/self.rs similarity index 100% rename from tests/rustdoc/intra-doc-crate/auxiliary/self.rs rename to tests/rustdoc-html/intra-doc-crate/auxiliary/self.rs diff --git a/tests/rustdoc/intra-doc-crate/self.rs b/tests/rustdoc-html/intra-doc-crate/self.rs similarity index 100% rename from tests/rustdoc/intra-doc-crate/self.rs rename to tests/rustdoc-html/intra-doc-crate/self.rs diff --git a/tests/rustdoc-html/intra-doc/adt-through-alias.rs b/tests/rustdoc-html/intra-doc/adt-through-alias.rs new file mode 100644 index 000000000000..6d5454bbaf20 --- /dev/null +++ b/tests/rustdoc-html/intra-doc/adt-through-alias.rs @@ -0,0 +1,71 @@ +#![crate_name = "foo"] + +//! [`TheStructAlias::the_field`] +//! [`TheEnumAlias::TheVariant`] +//! [`TheEnumAlias::TheVariant::the_field`] +//! [`TheUnionAlias::f1`] +//! +//! [`TheStruct::trait_`] +//! [`TheStructAlias::trait_`] +//! [`TheEnum::trait_`] +//! [`TheEnumAlias::trait_`] +//! +//! [`TheStruct::inherent`] +//! [`TheStructAlias::inherent`] +//! [`TheEnum::inherent`] +//! [`TheEnumAlias::inherent`] + +//@ has foo/index.html '//a[@href="type.TheStructAlias.html#structfield.the_field"]' 'TheStructAlias::the_field' +//@ has foo/index.html '//a[@href="type.TheEnumAlias.html#variant.TheVariant"]' 'TheEnumAlias::TheVariant' +//@ has foo/index.html '//a[@href="type.TheEnumAlias.html#variant.TheVariant.field.the_field"]' 'TheEnumAlias::TheVariant::the_field' +//@ has foo/index.html '//a[@href="type.TheUnionAlias.html#structfield.f1"]' 'TheUnionAlias::f1' + +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.trait_"]' 'TheStruct::trait_' +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.trait_"]' 'TheStructAlias::trait_' +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.trait_"]' 'TheEnum::trait_' +// FIXME: this one should resolve to alias since it's impl Trait for TheEnumAlias +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.trait_"]' 'TheEnumAlias::trait_' + +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.inherent"]' 'TheStruct::inherent' +// FIXME: this one should resolve to alias +//@ has foo/index.html '//a[@href="struct.TheStruct.html#method.inherent"]' 'TheStructAlias::inherent' +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.inherent"]' 'TheEnum::inherent' +// FIXME: this one should resolve to alias +//@ has foo/index.html '//a[@href="enum.TheEnum.html#method.inherent"]' 'TheEnumAlias::inherent' + +pub struct TheStruct { + pub the_field: i32, +} + +pub type TheStructAlias = TheStruct; + +pub enum TheEnum { + TheVariant { the_field: i32 }, +} + +pub type TheEnumAlias = TheEnum; + +pub trait Trait { + fn trait_() {} +} + +impl Trait for TheStruct {} + +impl Trait for TheEnumAlias {} + +impl TheStruct { + pub fn inherent() {} +} + +impl TheEnumAlias { + pub fn inherent() {} +} + +pub union TheUnion { + pub f1: usize, + pub f2: isize, +} + +pub type TheUnionAlias = TheUnion; + +fn main() {} diff --git a/tests/rustdoc/intra-doc/anchors.rs b/tests/rustdoc-html/intra-doc/anchors.rs similarity index 100% rename from tests/rustdoc/intra-doc/anchors.rs rename to tests/rustdoc-html/intra-doc/anchors.rs diff --git a/tests/rustdoc/intra-doc/assoc-reexport-super.rs b/tests/rustdoc-html/intra-doc/assoc-reexport-super.rs similarity index 100% rename from tests/rustdoc/intra-doc/assoc-reexport-super.rs rename to tests/rustdoc-html/intra-doc/assoc-reexport-super.rs diff --git a/tests/rustdoc/intra-doc/associated-defaults.rs b/tests/rustdoc-html/intra-doc/associated-defaults.rs similarity index 100% rename from tests/rustdoc/intra-doc/associated-defaults.rs rename to tests/rustdoc-html/intra-doc/associated-defaults.rs diff --git a/tests/rustdoc/intra-doc/associated-items.rs b/tests/rustdoc-html/intra-doc/associated-items.rs similarity index 92% rename from tests/rustdoc/intra-doc/associated-items.rs rename to tests/rustdoc-html/intra-doc/associated-items.rs index 84cfd06111df..b3bed196aded 100644 --- a/tests/rustdoc/intra-doc/associated-items.rs +++ b/tests/rustdoc-html/intra-doc/associated-items.rs @@ -13,7 +13,9 @@ pub fn foo() {} //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from struct' //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.clone"]' 'MyStruct::clone' //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#associatedtype.Input"]' 'MyStruct::Input' -pub struct MyStruct { foo: () } +pub struct MyStruct { + foo: (), +} impl Clone for MyStruct { fn clone(&self) -> Self { @@ -31,8 +33,7 @@ impl T for MyStruct { /// [link from method][MyStruct::method] on method //@ has 'associated_items/struct.MyStruct.html' '//a[@href="struct.MyStruct.html#method.method"]' 'link from method' - fn method(i: usize) { - } + fn method(i: usize) {} } /// Ambiguity between which trait to use @@ -57,7 +58,7 @@ impl T2 for S { fn ambiguous_method() {} } -//@ has associated_items/enum.MyEnum.html '//a/@href' 'enum.MyEnum.html#variant.MyVariant' +//@ has associated_items/enum.MyEnum.html '//a/@href' 'type.MyEnumAlias.html#variant.MyVariant' /// Link to [MyEnumAlias::MyVariant] pub enum MyEnum { MyVariant, diff --git a/tests/rustdoc/intra-doc/auxiliary/empty.rs b/tests/rustdoc-html/intra-doc/auxiliary/empty.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/empty.rs rename to tests/rustdoc-html/intra-doc/auxiliary/empty.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/empty2.rs b/tests/rustdoc-html/intra-doc/auxiliary/empty2.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/empty2.rs rename to tests/rustdoc-html/intra-doc/auxiliary/empty2.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs b/tests/rustdoc-html/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs rename to tests/rustdoc-html/intra-doc/auxiliary/extern-builtin-type-impl-dep.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs b/tests/rustdoc-html/intra-doc/auxiliary/extern-inherent-impl-dep.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs rename to tests/rustdoc-html/intra-doc/auxiliary/extern-inherent-impl-dep.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-link-extern-crate.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-link-extern-crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-link-extern-crate.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-link-extern-crate.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-link-pub-use.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-link-pub-use.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-link-pub-use.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-link-pub-use.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-link-reexport-additional-docs.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/intra-links-external-traits.rs b/tests/rustdoc-html/intra-doc/auxiliary/intra-links-external-traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/intra-links-external-traits.rs rename to tests/rustdoc-html/intra-doc/auxiliary/intra-links-external-traits.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/issue-66159-1.rs b/tests/rustdoc-html/intra-doc/auxiliary/issue-66159-1.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/issue-66159-1.rs rename to tests/rustdoc-html/intra-doc/auxiliary/issue-66159-1.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/my-core.rs b/tests/rustdoc-html/intra-doc/auxiliary/my-core.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/my-core.rs rename to tests/rustdoc-html/intra-doc/auxiliary/my-core.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/proc-macro-macro.rs b/tests/rustdoc-html/intra-doc/auxiliary/proc-macro-macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/proc-macro-macro.rs rename to tests/rustdoc-html/intra-doc/auxiliary/proc-macro-macro.rs diff --git a/tests/rustdoc/intra-doc/auxiliary/pub-struct.rs b/tests/rustdoc-html/intra-doc/auxiliary/pub-struct.rs similarity index 100% rename from tests/rustdoc/intra-doc/auxiliary/pub-struct.rs rename to tests/rustdoc-html/intra-doc/auxiliary/pub-struct.rs diff --git a/tests/rustdoc/intra-doc/basic.rs b/tests/rustdoc-html/intra-doc/basic.rs similarity index 100% rename from tests/rustdoc/intra-doc/basic.rs rename to tests/rustdoc-html/intra-doc/basic.rs diff --git a/tests/rustdoc/intra-doc/builtin-macros.rs b/tests/rustdoc-html/intra-doc/builtin-macros.rs similarity index 100% rename from tests/rustdoc/intra-doc/builtin-macros.rs rename to tests/rustdoc-html/intra-doc/builtin-macros.rs diff --git a/tests/rustdoc/intra-doc/crate-relative-assoc.rs b/tests/rustdoc-html/intra-doc/crate-relative-assoc.rs similarity index 100% rename from tests/rustdoc/intra-doc/crate-relative-assoc.rs rename to tests/rustdoc-html/intra-doc/crate-relative-assoc.rs diff --git a/tests/rustdoc/intra-doc/crate-relative.rs b/tests/rustdoc-html/intra-doc/crate-relative.rs similarity index 100% rename from tests/rustdoc/intra-doc/crate-relative.rs rename to tests/rustdoc-html/intra-doc/crate-relative.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/additional_doc.rs b/tests/rustdoc-html/intra-doc/cross-crate/additional_doc.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/additional_doc.rs rename to tests/rustdoc-html/intra-doc/cross-crate/additional_doc.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/additional_doc.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/additional_doc.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/additional_doc.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/additional_doc.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/hidden.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/hidden.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/hidden.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/hidden.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-doc-basic.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/intra-link-cross-crate-crate.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/macro_inner.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/macro_inner.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/macro_inner.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/macro_inner.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/module.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/module.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/module.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/module.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/proc_macro.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/proc_macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/proc_macro.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/proc_macro.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-inner.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-inner.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-inner.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-inner.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-outer.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-outer.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/submodule-outer.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/submodule-outer.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/auxiliary/traits.rs b/tests/rustdoc-html/intra-doc/cross-crate/auxiliary/traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/auxiliary/traits.rs rename to tests/rustdoc-html/intra-doc/cross-crate/auxiliary/traits.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/basic.rs b/tests/rustdoc-html/intra-doc/cross-crate/basic.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/basic.rs rename to tests/rustdoc-html/intra-doc/cross-crate/basic.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/crate.rs b/tests/rustdoc-html/intra-doc/cross-crate/crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/crate.rs rename to tests/rustdoc-html/intra-doc/cross-crate/crate.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/hidden.rs b/tests/rustdoc-html/intra-doc/cross-crate/hidden.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/hidden.rs rename to tests/rustdoc-html/intra-doc/cross-crate/hidden.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/macro.rs b/tests/rustdoc-html/intra-doc/cross-crate/macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/macro.rs rename to tests/rustdoc-html/intra-doc/cross-crate/macro.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/module.rs b/tests/rustdoc-html/intra-doc/cross-crate/module.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/module.rs rename to tests/rustdoc-html/intra-doc/cross-crate/module.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/submodule-inner.rs b/tests/rustdoc-html/intra-doc/cross-crate/submodule-inner.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/submodule-inner.rs rename to tests/rustdoc-html/intra-doc/cross-crate/submodule-inner.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/submodule-outer.rs b/tests/rustdoc-html/intra-doc/cross-crate/submodule-outer.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/submodule-outer.rs rename to tests/rustdoc-html/intra-doc/cross-crate/submodule-outer.rs diff --git a/tests/rustdoc/intra-doc/cross-crate/traits.rs b/tests/rustdoc-html/intra-doc/cross-crate/traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/cross-crate/traits.rs rename to tests/rustdoc-html/intra-doc/cross-crate/traits.rs diff --git a/tests/rustdoc-html/intra-doc/deprecated.rs b/tests/rustdoc-html/intra-doc/deprecated.rs new file mode 100644 index 000000000000..6f8639593a2d --- /dev/null +++ b/tests/rustdoc-html/intra-doc/deprecated.rs @@ -0,0 +1,12 @@ +//@ has deprecated/struct.A.html '//a[@href="{{channel}}/core/ops/range/struct.Range.html#structfield.start"]' 'start' +//@ has deprecated/struct.B1.html '//a[@href="{{channel}}/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found' +//@ has deprecated/struct.B2.html '//a[@href="{{channel}}/std/io/error/enum.ErrorKind.html#variant.NotFound"]' 'not_found' + +#[deprecated = "[start][std::ops::Range::start]"] +pub struct A; + +#[deprecated(since = "0.0.0", note = "[not_found][std::io::ErrorKind::NotFound]")] +pub struct B1; + +#[deprecated(note = "[not_found][std::io::ErrorKind::NotFound]", since = "0.0.0")] +pub struct B2; diff --git a/tests/rustdoc/intra-doc/deps.rs b/tests/rustdoc-html/intra-doc/deps.rs similarity index 86% rename from tests/rustdoc/intra-doc/deps.rs rename to tests/rustdoc-html/intra-doc/deps.rs index fd40b8326d0f..1670a2d8fe7b 100644 --- a/tests/rustdoc/intra-doc/deps.rs +++ b/tests/rustdoc-html/intra-doc/deps.rs @@ -6,7 +6,7 @@ //@ compile-flags: --extern-html-root-url=empty=https://empty.example/ // This one is to ensure that we don't link to any item we see which has // an external html root URL unless it actually exists. -//@ compile-flags: --extern-html-root-url=non_existant=https://non-existant.example/ +//@ compile-flags: --extern-html-root-url=non_existent=https://non-existent.example/ //@ aux-build: empty.rs #![crate_name = "foo"] @@ -14,10 +14,10 @@ //@ has 'foo/index.html' //@ has - '//a[@href="https://empty.example/empty/index.html"]' 'empty' -// There should only be one intra doc links, we should not link `non_existant`. +// There should only be one intra doc links, we should not link `non_existent`. //@ count - '//*[@class="docblock"]//a' 1 //! [`empty`] //! -//! [`non_existant`] +//! [`non_existent`] extern crate empty; diff --git a/tests/rustdoc/intra-doc/disambiguators-removed.rs b/tests/rustdoc-html/intra-doc/disambiguators-removed.rs similarity index 100% rename from tests/rustdoc/intra-doc/disambiguators-removed.rs rename to tests/rustdoc-html/intra-doc/disambiguators-removed.rs diff --git a/tests/rustdoc/intra-doc/email-address.rs b/tests/rustdoc-html/intra-doc/email-address.rs similarity index 100% rename from tests/rustdoc/intra-doc/email-address.rs rename to tests/rustdoc-html/intra-doc/email-address.rs diff --git a/tests/rustdoc/intra-doc/enum-self-82209.rs b/tests/rustdoc-html/intra-doc/enum-self-82209.rs similarity index 100% rename from tests/rustdoc/intra-doc/enum-self-82209.rs rename to tests/rustdoc-html/intra-doc/enum-self-82209.rs diff --git a/tests/rustdoc/intra-doc/enum-struct-field.rs b/tests/rustdoc-html/intra-doc/enum-struct-field.rs similarity index 100% rename from tests/rustdoc/intra-doc/enum-struct-field.rs rename to tests/rustdoc-html/intra-doc/enum-struct-field.rs diff --git a/tests/rustdoc/intra-doc/extern-builtin-type-impl.rs b/tests/rustdoc-html/intra-doc/extern-builtin-type-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-builtin-type-impl.rs rename to tests/rustdoc-html/intra-doc/extern-builtin-type-impl.rs diff --git a/tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs b/tests/rustdoc-html/intra-doc/extern-crate-only-used-in-link.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-crate-only-used-in-link.rs rename to tests/rustdoc-html/intra-doc/extern-crate-only-used-in-link.rs diff --git a/tests/rustdoc/intra-doc/extern-crate.rs b/tests/rustdoc-html/intra-doc/extern-crate.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-crate.rs rename to tests/rustdoc-html/intra-doc/extern-crate.rs diff --git a/tests/rustdoc/intra-doc/extern-inherent-impl.rs b/tests/rustdoc-html/intra-doc/extern-inherent-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-inherent-impl.rs rename to tests/rustdoc-html/intra-doc/extern-inherent-impl.rs diff --git a/tests/rustdoc/intra-doc/extern-reference-link.rs b/tests/rustdoc-html/intra-doc/extern-reference-link.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-reference-link.rs rename to tests/rustdoc-html/intra-doc/extern-reference-link.rs diff --git a/tests/rustdoc/intra-doc/extern-type.rs b/tests/rustdoc-html/intra-doc/extern-type.rs similarity index 100% rename from tests/rustdoc/intra-doc/extern-type.rs rename to tests/rustdoc-html/intra-doc/extern-type.rs diff --git a/tests/rustdoc/intra-doc/external-traits.rs b/tests/rustdoc-html/intra-doc/external-traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/external-traits.rs rename to tests/rustdoc-html/intra-doc/external-traits.rs diff --git a/tests/rustdoc/intra-doc/field.rs b/tests/rustdoc-html/intra-doc/field.rs similarity index 100% rename from tests/rustdoc/intra-doc/field.rs rename to tests/rustdoc-html/intra-doc/field.rs diff --git a/tests/rustdoc/intra-doc/filter-out-private.rs b/tests/rustdoc-html/intra-doc/filter-out-private.rs similarity index 100% rename from tests/rustdoc/intra-doc/filter-out-private.rs rename to tests/rustdoc-html/intra-doc/filter-out-private.rs diff --git a/tests/rustdoc/intra-doc/generic-params.rs b/tests/rustdoc-html/intra-doc/generic-params.rs similarity index 100% rename from tests/rustdoc/intra-doc/generic-params.rs rename to tests/rustdoc-html/intra-doc/generic-params.rs diff --git a/tests/rustdoc/intra-doc/generic-trait-impl.rs b/tests/rustdoc-html/intra-doc/generic-trait-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/generic-trait-impl.rs rename to tests/rustdoc-html/intra-doc/generic-trait-impl.rs diff --git a/tests/rustdoc-html/intra-doc/ice-deprecated-note-on-reexport.rs b/tests/rustdoc-html/intra-doc/ice-deprecated-note-on-reexport.rs new file mode 100644 index 000000000000..99415a9a2fd4 --- /dev/null +++ b/tests/rustdoc-html/intra-doc/ice-deprecated-note-on-reexport.rs @@ -0,0 +1,11 @@ +// This test ensures that the intra-doc link in `deprecated` note is resolved at the correct +// location (ie in the current crate and not in the reexported item's location/crate) and +// therefore doesn't crash. +// +// This is a regression test for . + +#![crate_name = "foo"] + +#[deprecated(note = "use [`std::mem::forget`]")] +#[doc(inline)] +pub use std::mem::drop; diff --git a/tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs b/tests/rustdoc-html/intra-doc/ice-intra-doc-links-107995.rs similarity index 100% rename from tests/rustdoc/intra-doc/ice-intra-doc-links-107995.rs rename to tests/rustdoc-html/intra-doc/ice-intra-doc-links-107995.rs diff --git a/tests/rustdoc/intra-doc/in-bodies.rs b/tests/rustdoc-html/intra-doc/in-bodies.rs similarity index 100% rename from tests/rustdoc/intra-doc/in-bodies.rs rename to tests/rustdoc-html/intra-doc/in-bodies.rs diff --git a/tests/rustdoc/intra-doc/inherent-associated-types.rs b/tests/rustdoc-html/intra-doc/inherent-associated-types.rs similarity index 100% rename from tests/rustdoc/intra-doc/inherent-associated-types.rs rename to tests/rustdoc-html/intra-doc/inherent-associated-types.rs diff --git a/tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs b/tests/rustdoc-html/intra-doc/intra-doc-link-method-trait-impl-72340.rs similarity index 100% rename from tests/rustdoc/intra-doc/intra-doc-link-method-trait-impl-72340.rs rename to tests/rustdoc-html/intra-doc/intra-doc-link-method-trait-impl-72340.rs diff --git a/tests/rustdoc/intra-doc/libstd-re-export.rs b/tests/rustdoc-html/intra-doc/libstd-re-export.rs similarity index 100% rename from tests/rustdoc/intra-doc/libstd-re-export.rs rename to tests/rustdoc-html/intra-doc/libstd-re-export.rs diff --git a/tests/rustdoc/intra-doc/link-in-footnotes-132208.rs b/tests/rustdoc-html/intra-doc/link-in-footnotes-132208.rs similarity index 100% rename from tests/rustdoc/intra-doc/link-in-footnotes-132208.rs rename to tests/rustdoc-html/intra-doc/link-in-footnotes-132208.rs diff --git a/tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs b/tests/rustdoc-html/intra-doc/link-same-name-different-disambiguator-108459.rs similarity index 100% rename from tests/rustdoc/intra-doc/link-same-name-different-disambiguator-108459.rs rename to tests/rustdoc-html/intra-doc/link-same-name-different-disambiguator-108459.rs diff --git a/tests/rustdoc/intra-doc/link-to-proc-macro.rs b/tests/rustdoc-html/intra-doc/link-to-proc-macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/link-to-proc-macro.rs rename to tests/rustdoc-html/intra-doc/link-to-proc-macro.rs diff --git a/tests/rustdoc/intra-doc/macro-caching-144965.rs b/tests/rustdoc-html/intra-doc/macro-caching-144965.rs similarity index 100% rename from tests/rustdoc/intra-doc/macro-caching-144965.rs rename to tests/rustdoc-html/intra-doc/macro-caching-144965.rs diff --git a/tests/rustdoc/intra-doc/macros-disambiguators.rs b/tests/rustdoc-html/intra-doc/macros-disambiguators.rs similarity index 100% rename from tests/rustdoc/intra-doc/macros-disambiguators.rs rename to tests/rustdoc-html/intra-doc/macros-disambiguators.rs diff --git a/tests/rustdoc/intra-doc/mod-ambiguity.rs b/tests/rustdoc-html/intra-doc/mod-ambiguity.rs similarity index 100% rename from tests/rustdoc/intra-doc/mod-ambiguity.rs rename to tests/rustdoc-html/intra-doc/mod-ambiguity.rs diff --git a/tests/rustdoc/intra-doc/mod-relative.rs b/tests/rustdoc-html/intra-doc/mod-relative.rs similarity index 100% rename from tests/rustdoc/intra-doc/mod-relative.rs rename to tests/rustdoc-html/intra-doc/mod-relative.rs diff --git a/tests/rustdoc/intra-doc/module-scope-name-resolution-55364.rs b/tests/rustdoc-html/intra-doc/module-scope-name-resolution-55364.rs similarity index 100% rename from tests/rustdoc/intra-doc/module-scope-name-resolution-55364.rs rename to tests/rustdoc-html/intra-doc/module-scope-name-resolution-55364.rs diff --git a/tests/rustdoc/intra-doc/nested-use.rs b/tests/rustdoc-html/intra-doc/nested-use.rs similarity index 100% rename from tests/rustdoc/intra-doc/nested-use.rs rename to tests/rustdoc-html/intra-doc/nested-use.rs diff --git a/tests/rustdoc/intra-doc/no-doc-primitive.rs b/tests/rustdoc-html/intra-doc/no-doc-primitive.rs similarity index 100% rename from tests/rustdoc/intra-doc/no-doc-primitive.rs rename to tests/rustdoc-html/intra-doc/no-doc-primitive.rs diff --git a/tests/rustdoc/intra-doc/non-path-primitives.rs b/tests/rustdoc-html/intra-doc/non-path-primitives.rs similarity index 100% rename from tests/rustdoc/intra-doc/non-path-primitives.rs rename to tests/rustdoc-html/intra-doc/non-path-primitives.rs diff --git a/tests/rustdoc/intra-doc/prim-assoc.rs b/tests/rustdoc-html/intra-doc/prim-assoc.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-assoc.rs rename to tests/rustdoc-html/intra-doc/prim-assoc.rs diff --git a/tests/rustdoc/intra-doc/prim-associated-traits.rs b/tests/rustdoc-html/intra-doc/prim-associated-traits.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-associated-traits.rs rename to tests/rustdoc-html/intra-doc/prim-associated-traits.rs diff --git a/tests/rustdoc/intra-doc/prim-methods-external-core.rs b/tests/rustdoc-html/intra-doc/prim-methods-external-core.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-methods-external-core.rs rename to tests/rustdoc-html/intra-doc/prim-methods-external-core.rs diff --git a/tests/rustdoc/intra-doc/prim-methods-local.rs b/tests/rustdoc-html/intra-doc/prim-methods-local.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-methods-local.rs rename to tests/rustdoc-html/intra-doc/prim-methods-local.rs diff --git a/tests/rustdoc/intra-doc/prim-methods.rs b/tests/rustdoc-html/intra-doc/prim-methods.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-methods.rs rename to tests/rustdoc-html/intra-doc/prim-methods.rs diff --git a/tests/rustdoc/intra-doc/prim-precedence.rs b/tests/rustdoc-html/intra-doc/prim-precedence.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-precedence.rs rename to tests/rustdoc-html/intra-doc/prim-precedence.rs diff --git a/tests/rustdoc/intra-doc/prim-self.rs b/tests/rustdoc-html/intra-doc/prim-self.rs similarity index 100% rename from tests/rustdoc/intra-doc/prim-self.rs rename to tests/rustdoc-html/intra-doc/prim-self.rs diff --git a/tests/rustdoc/intra-doc/primitive-disambiguators.rs b/tests/rustdoc-html/intra-doc/primitive-disambiguators.rs similarity index 100% rename from tests/rustdoc/intra-doc/primitive-disambiguators.rs rename to tests/rustdoc-html/intra-doc/primitive-disambiguators.rs diff --git a/tests/rustdoc/intra-doc/primitive-non-default-impl.rs b/tests/rustdoc-html/intra-doc/primitive-non-default-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/primitive-non-default-impl.rs rename to tests/rustdoc-html/intra-doc/primitive-non-default-impl.rs diff --git a/tests/rustdoc/intra-doc/private-failures-ignored.rs b/tests/rustdoc-html/intra-doc/private-failures-ignored.rs similarity index 100% rename from tests/rustdoc/intra-doc/private-failures-ignored.rs rename to tests/rustdoc-html/intra-doc/private-failures-ignored.rs diff --git a/tests/rustdoc/intra-doc/private.rs b/tests/rustdoc-html/intra-doc/private.rs similarity index 100% rename from tests/rustdoc/intra-doc/private.rs rename to tests/rustdoc-html/intra-doc/private.rs diff --git a/tests/rustdoc/intra-doc/proc-macro.rs b/tests/rustdoc-html/intra-doc/proc-macro.rs similarity index 100% rename from tests/rustdoc/intra-doc/proc-macro.rs rename to tests/rustdoc-html/intra-doc/proc-macro.rs diff --git a/tests/rustdoc/intra-doc/pub-use.rs b/tests/rustdoc-html/intra-doc/pub-use.rs similarity index 100% rename from tests/rustdoc/intra-doc/pub-use.rs rename to tests/rustdoc-html/intra-doc/pub-use.rs diff --git a/tests/rustdoc/intra-doc/raw-ident-self.rs b/tests/rustdoc-html/intra-doc/raw-ident-self.rs similarity index 100% rename from tests/rustdoc/intra-doc/raw-ident-self.rs rename to tests/rustdoc-html/intra-doc/raw-ident-self.rs diff --git a/tests/rustdoc/intra-doc/reexport-additional-docs.rs b/tests/rustdoc-html/intra-doc/reexport-additional-docs.rs similarity index 100% rename from tests/rustdoc/intra-doc/reexport-additional-docs.rs rename to tests/rustdoc-html/intra-doc/reexport-additional-docs.rs diff --git a/tests/rustdoc/intra-doc/same-name-different-crates-66159.rs b/tests/rustdoc-html/intra-doc/same-name-different-crates-66159.rs similarity index 100% rename from tests/rustdoc/intra-doc/same-name-different-crates-66159.rs rename to tests/rustdoc-html/intra-doc/same-name-different-crates-66159.rs diff --git a/tests/rustdoc/intra-doc/self-cache.rs b/tests/rustdoc-html/intra-doc/self-cache.rs similarity index 100% rename from tests/rustdoc/intra-doc/self-cache.rs rename to tests/rustdoc-html/intra-doc/self-cache.rs diff --git a/tests/rustdoc/intra-doc/self.rs b/tests/rustdoc-html/intra-doc/self.rs similarity index 100% rename from tests/rustdoc/intra-doc/self.rs rename to tests/rustdoc-html/intra-doc/self.rs diff --git a/tests/rustdoc/intra-doc/trait-impl.rs b/tests/rustdoc-html/intra-doc/trait-impl.rs similarity index 100% rename from tests/rustdoc/intra-doc/trait-impl.rs rename to tests/rustdoc-html/intra-doc/trait-impl.rs diff --git a/tests/rustdoc/intra-doc/trait-item.rs b/tests/rustdoc-html/intra-doc/trait-item.rs similarity index 100% rename from tests/rustdoc/intra-doc/trait-item.rs rename to tests/rustdoc-html/intra-doc/trait-item.rs diff --git a/tests/rustdoc/intra-doc/true-false.rs b/tests/rustdoc-html/intra-doc/true-false.rs similarity index 100% rename from tests/rustdoc/intra-doc/true-false.rs rename to tests/rustdoc-html/intra-doc/true-false.rs diff --git a/tests/rustdoc/intra-doc/type-alias-primitive.rs b/tests/rustdoc-html/intra-doc/type-alias-primitive.rs similarity index 100% rename from tests/rustdoc/intra-doc/type-alias-primitive.rs rename to tests/rustdoc-html/intra-doc/type-alias-primitive.rs diff --git a/tests/rustdoc/intra-doc/type-alias.rs b/tests/rustdoc-html/intra-doc/type-alias.rs similarity index 100% rename from tests/rustdoc/intra-doc/type-alias.rs rename to tests/rustdoc-html/intra-doc/type-alias.rs diff --git a/tests/rustdoc/invalid$crate$name.rs b/tests/rustdoc-html/invalid$crate$name.rs similarity index 100% rename from tests/rustdoc/invalid$crate$name.rs rename to tests/rustdoc-html/invalid$crate$name.rs diff --git a/tests/rustdoc/item-desc-list-at-start.item-table.html b/tests/rustdoc-html/item-desc-list-at-start.item-table.html similarity index 100% rename from tests/rustdoc/item-desc-list-at-start.item-table.html rename to tests/rustdoc-html/item-desc-list-at-start.item-table.html diff --git a/tests/rustdoc/item-desc-list-at-start.rs b/tests/rustdoc-html/item-desc-list-at-start.rs similarity index 100% rename from tests/rustdoc/item-desc-list-at-start.rs rename to tests/rustdoc-html/item-desc-list-at-start.rs diff --git a/tests/rustdoc/jump-to-def/assoc-items.rs b/tests/rustdoc-html/jump-to-def/assoc-items.rs similarity index 100% rename from tests/rustdoc/jump-to-def/assoc-items.rs rename to tests/rustdoc-html/jump-to-def/assoc-items.rs diff --git a/tests/rustdoc/jump-to-def/assoc-types.rs b/tests/rustdoc-html/jump-to-def/assoc-types.rs similarity index 100% rename from tests/rustdoc/jump-to-def/assoc-types.rs rename to tests/rustdoc-html/jump-to-def/assoc-types.rs diff --git a/tests/rustdoc/jump-to-def/auxiliary/symbols.rs b/tests/rustdoc-html/jump-to-def/auxiliary/symbols.rs similarity index 100% rename from tests/rustdoc/jump-to-def/auxiliary/symbols.rs rename to tests/rustdoc-html/jump-to-def/auxiliary/symbols.rs diff --git a/tests/rustdoc/jump-to-def/derive-macro.rs b/tests/rustdoc-html/jump-to-def/derive-macro.rs similarity index 100% rename from tests/rustdoc/jump-to-def/derive-macro.rs rename to tests/rustdoc-html/jump-to-def/derive-macro.rs diff --git a/tests/rustdoc/jump-to-def/doc-links-calls.rs b/tests/rustdoc-html/jump-to-def/doc-links-calls.rs similarity index 100% rename from tests/rustdoc/jump-to-def/doc-links-calls.rs rename to tests/rustdoc-html/jump-to-def/doc-links-calls.rs diff --git a/tests/rustdoc/jump-to-def/doc-links.rs b/tests/rustdoc-html/jump-to-def/doc-links.rs similarity index 100% rename from tests/rustdoc/jump-to-def/doc-links.rs rename to tests/rustdoc-html/jump-to-def/doc-links.rs diff --git a/tests/rustdoc/jump-to-def/macro.rs b/tests/rustdoc-html/jump-to-def/macro.rs similarity index 100% rename from tests/rustdoc/jump-to-def/macro.rs rename to tests/rustdoc-html/jump-to-def/macro.rs diff --git a/tests/rustdoc/jump-to-def/no-body-items.rs b/tests/rustdoc-html/jump-to-def/no-body-items.rs similarity index 100% rename from tests/rustdoc/jump-to-def/no-body-items.rs rename to tests/rustdoc-html/jump-to-def/no-body-items.rs diff --git a/tests/rustdoc/jump-to-def/non-local-method.rs b/tests/rustdoc-html/jump-to-def/non-local-method.rs similarity index 100% rename from tests/rustdoc/jump-to-def/non-local-method.rs rename to tests/rustdoc-html/jump-to-def/non-local-method.rs diff --git a/tests/rustdoc/jump-to-def/patterns.rs b/tests/rustdoc-html/jump-to-def/patterns.rs similarity index 100% rename from tests/rustdoc/jump-to-def/patterns.rs rename to tests/rustdoc-html/jump-to-def/patterns.rs diff --git a/tests/rustdoc/jump-to-def/prelude-types.rs b/tests/rustdoc-html/jump-to-def/prelude-types.rs similarity index 100% rename from tests/rustdoc/jump-to-def/prelude-types.rs rename to tests/rustdoc-html/jump-to-def/prelude-types.rs diff --git a/tests/rustdoc/jump-to-def/shebang.rs b/tests/rustdoc-html/jump-to-def/shebang.rs similarity index 100% rename from tests/rustdoc/jump-to-def/shebang.rs rename to tests/rustdoc-html/jump-to-def/shebang.rs diff --git a/tests/rustdoc/keyword.rs b/tests/rustdoc-html/keyword.rs similarity index 100% rename from tests/rustdoc/keyword.rs rename to tests/rustdoc-html/keyword.rs diff --git a/tests/rustdoc/lifetime-name.rs b/tests/rustdoc-html/lifetime-name.rs similarity index 100% rename from tests/rustdoc/lifetime-name.rs rename to tests/rustdoc-html/lifetime-name.rs diff --git a/tests/rustdoc/line-breaks.rs b/tests/rustdoc-html/line-breaks.rs similarity index 100% rename from tests/rustdoc/line-breaks.rs rename to tests/rustdoc-html/line-breaks.rs diff --git a/tests/rustdoc/link-on-path-with-generics.rs b/tests/rustdoc-html/link-on-path-with-generics.rs similarity index 100% rename from tests/rustdoc/link-on-path-with-generics.rs rename to tests/rustdoc-html/link-on-path-with-generics.rs diff --git a/tests/rustdoc/link-title-escape.rs b/tests/rustdoc-html/link-title-escape.rs similarity index 100% rename from tests/rustdoc/link-title-escape.rs rename to tests/rustdoc-html/link-title-escape.rs diff --git a/tests/rustdoc/links-in-headings.rs b/tests/rustdoc-html/links-in-headings.rs similarity index 100% rename from tests/rustdoc/links-in-headings.rs rename to tests/rustdoc-html/links-in-headings.rs diff --git a/tests/rustdoc/logo-class-default.rs b/tests/rustdoc-html/logo-class-default.rs similarity index 100% rename from tests/rustdoc/logo-class-default.rs rename to tests/rustdoc-html/logo-class-default.rs diff --git a/tests/rustdoc/logo-class-rust.rs b/tests/rustdoc-html/logo-class-rust.rs similarity index 100% rename from tests/rustdoc/logo-class-rust.rs rename to tests/rustdoc-html/logo-class-rust.rs diff --git a/tests/rustdoc/logo-class.rs b/tests/rustdoc-html/logo-class.rs similarity index 100% rename from tests/rustdoc/logo-class.rs rename to tests/rustdoc-html/logo-class.rs diff --git a/tests/rustdoc-html/macro-expansion/field-followed-by-exclamation.rs b/tests/rustdoc-html/macro-expansion/field-followed-by-exclamation.rs new file mode 100644 index 000000000000..e80b4c4ec873 --- /dev/null +++ b/tests/rustdoc-html/macro-expansion/field-followed-by-exclamation.rs @@ -0,0 +1,26 @@ +// This test ensures that the macro expansion is correctly handled in cases like: +// `field: !f!`, because the `:` was simply not considered because of how paths +// are handled. + +//@ compile-flags: -Zunstable-options --generate-macro-expansion + +#![crate_name = "foo"] + +//@ has 'src/foo/field-followed-by-exclamation.rs.html' + +struct Bar { + bla: bool, +} + +macro_rules! f { + () => {{ false }} +} + +const X: Bar = Bar { + //@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'f!' + //@ has - '//*[@class="expansion"]/*[@class="original"]' 'f!()' + //@ has - '//*[@class="expansion"]/*[@class="expanded"]' '{ false }' + // It includes both original and expanded code. + //@ has - '//*[@class="expansion"]' ' bla: !{ false }f!()' + bla: !f!(), +}; diff --git a/tests/rustdoc-html/macro-expansion/type-macro-expansion.rs b/tests/rustdoc-html/macro-expansion/type-macro-expansion.rs new file mode 100644 index 000000000000..d7d28fdac666 --- /dev/null +++ b/tests/rustdoc-html/macro-expansion/type-macro-expansion.rs @@ -0,0 +1,27 @@ +// Ensure macro invocations at type position are expanded correctly + +//@ compile-flags: -Zunstable-options --generate-macro-expansion + +#![crate_name = "foo"] + +//@ has 'src/foo/type-macro-expansion.rs.html' + +macro_rules! foo { + () => { + fn(()) + }; + ($_arg:expr) => { + [(); 1] + }; +} + +fn bar() { + //@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'foo!' + //@ has - '//*[@class="expansion"]/*[@class="original"]' 'foo!()' + //@ has - '//*[@class="expansion"]/*[@class="expanded"]' 'fn(())' + let _: foo!(); + //@ has - '//*[@class="expansion"]/*[@class="original"]/*[@class="macro"]' 'foo!' + //@ has - '//*[@class="expansion"]/*[@class="original"]' 'foo!(42)' + //@ has - '//*[@class="expansion"]/*[@class="expanded"]' '[(); 1]' + let _: foo!(42); +} diff --git a/tests/rustdoc/macro/auxiliary/external-macro-src.rs b/tests/rustdoc-html/macro/auxiliary/external-macro-src.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/external-macro-src.rs rename to tests/rustdoc-html/macro/auxiliary/external-macro-src.rs diff --git a/tests/rustdoc/macro/auxiliary/issue-99221-aux.rs b/tests/rustdoc-html/macro/auxiliary/issue-99221-aux.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/issue-99221-aux.rs rename to tests/rustdoc-html/macro/auxiliary/issue-99221-aux.rs diff --git a/tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs b/tests/rustdoc-html/macro/auxiliary/macro_pub_in_module.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/macro_pub_in_module.rs rename to tests/rustdoc-html/macro/auxiliary/macro_pub_in_module.rs diff --git a/tests/rustdoc/macro/auxiliary/one-line-expand.rs b/tests/rustdoc-html/macro/auxiliary/one-line-expand.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/one-line-expand.rs rename to tests/rustdoc-html/macro/auxiliary/one-line-expand.rs diff --git a/tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs b/tests/rustdoc-html/macro/auxiliary/pub-use-extern-macros.rs similarity index 100% rename from tests/rustdoc/macro/auxiliary/pub-use-extern-macros.rs rename to tests/rustdoc-html/macro/auxiliary/pub-use-extern-macros.rs diff --git a/tests/rustdoc/macro/compiler-derive-proc-macro.rs b/tests/rustdoc-html/macro/compiler-derive-proc-macro.rs similarity index 100% rename from tests/rustdoc/macro/compiler-derive-proc-macro.rs rename to tests/rustdoc-html/macro/compiler-derive-proc-macro.rs diff --git a/tests/rustdoc/macro/const-rendering-macros-33302.rs b/tests/rustdoc-html/macro/const-rendering-macros-33302.rs similarity index 100% rename from tests/rustdoc/macro/const-rendering-macros-33302.rs rename to tests/rustdoc-html/macro/const-rendering-macros-33302.rs diff --git a/tests/rustdoc/macro/decl_macro.rs b/tests/rustdoc-html/macro/decl_macro.rs similarity index 100% rename from tests/rustdoc/macro/decl_macro.rs rename to tests/rustdoc-html/macro/decl_macro.rs diff --git a/tests/rustdoc/macro/decl_macro_priv.rs b/tests/rustdoc-html/macro/decl_macro_priv.rs similarity index 100% rename from tests/rustdoc/macro/decl_macro_priv.rs rename to tests/rustdoc-html/macro/decl_macro_priv.rs diff --git a/tests/rustdoc/macro/doc-proc-macro.rs b/tests/rustdoc-html/macro/doc-proc-macro.rs similarity index 100% rename from tests/rustdoc/macro/doc-proc-macro.rs rename to tests/rustdoc-html/macro/doc-proc-macro.rs diff --git a/tests/rustdoc/macro/external-macro-src.rs b/tests/rustdoc-html/macro/external-macro-src.rs similarity index 100% rename from tests/rustdoc/macro/external-macro-src.rs rename to tests/rustdoc-html/macro/external-macro-src.rs diff --git a/tests/rustdoc/macro/macro-const-display-115295.rs b/tests/rustdoc-html/macro/macro-const-display-115295.rs similarity index 100% rename from tests/rustdoc/macro/macro-const-display-115295.rs rename to tests/rustdoc-html/macro/macro-const-display-115295.rs diff --git a/tests/rustdoc/macro/macro-doc-comment-23812.rs b/tests/rustdoc-html/macro/macro-doc-comment-23812.rs similarity index 100% rename from tests/rustdoc/macro/macro-doc-comment-23812.rs rename to tests/rustdoc-html/macro/macro-doc-comment-23812.rs diff --git a/tests/rustdoc/macro/macro-export-crate-root-108231.rs b/tests/rustdoc-html/macro/macro-export-crate-root-108231.rs similarity index 100% rename from tests/rustdoc/macro/macro-export-crate-root-108231.rs rename to tests/rustdoc-html/macro/macro-export-crate-root-108231.rs diff --git a/tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html b/tests/rustdoc-html/macro/macro-generated-macro.macro_linebreak_pre.html similarity index 100% rename from tests/rustdoc/macro/macro-generated-macro.macro_linebreak_pre.html rename to tests/rustdoc-html/macro/macro-generated-macro.macro_linebreak_pre.html diff --git a/tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html b/tests/rustdoc-html/macro/macro-generated-macro.macro_morestuff_pre.html similarity index 100% rename from tests/rustdoc/macro/macro-generated-macro.macro_morestuff_pre.html rename to tests/rustdoc-html/macro/macro-generated-macro.macro_morestuff_pre.html diff --git a/tests/rustdoc/macro/macro-generated-macro.rs b/tests/rustdoc-html/macro/macro-generated-macro.rs similarity index 100% rename from tests/rustdoc/macro/macro-generated-macro.rs rename to tests/rustdoc-html/macro/macro-generated-macro.rs diff --git a/tests/rustdoc/macro/macro-higher-kinded-function.rs b/tests/rustdoc-html/macro/macro-higher-kinded-function.rs similarity index 100% rename from tests/rustdoc/macro/macro-higher-kinded-function.rs rename to tests/rustdoc-html/macro/macro-higher-kinded-function.rs diff --git a/tests/rustdoc/macro/macro-ice-16019.rs b/tests/rustdoc-html/macro/macro-ice-16019.rs similarity index 100% rename from tests/rustdoc/macro/macro-ice-16019.rs rename to tests/rustdoc-html/macro/macro-ice-16019.rs diff --git a/tests/rustdoc/macro/macro-in-async-block.rs b/tests/rustdoc-html/macro/macro-in-async-block.rs similarity index 100% rename from tests/rustdoc/macro/macro-in-async-block.rs rename to tests/rustdoc-html/macro/macro-in-async-block.rs diff --git a/tests/rustdoc/macro/macro-in-closure.rs b/tests/rustdoc-html/macro/macro-in-closure.rs similarity index 100% rename from tests/rustdoc/macro/macro-in-closure.rs rename to tests/rustdoc-html/macro/macro-in-closure.rs diff --git a/tests/rustdoc/macro/macro-indirect-use.rs b/tests/rustdoc-html/macro/macro-indirect-use.rs similarity index 100% rename from tests/rustdoc/macro/macro-indirect-use.rs rename to tests/rustdoc-html/macro/macro-indirect-use.rs diff --git a/tests/rustdoc/macro/macro_expansion.rs b/tests/rustdoc-html/macro/macro_expansion.rs similarity index 100% rename from tests/rustdoc/macro/macro_expansion.rs rename to tests/rustdoc-html/macro/macro_expansion.rs diff --git a/tests/rustdoc/macro/macro_pub_in_module.rs b/tests/rustdoc-html/macro/macro_pub_in_module.rs similarity index 97% rename from tests/rustdoc/macro/macro_pub_in_module.rs rename to tests/rustdoc-html/macro/macro_pub_in_module.rs index 2dce73c2cf26..a4b39e20d126 100644 --- a/tests/rustdoc/macro/macro_pub_in_module.rs +++ b/tests/rustdoc-html/macro/macro_pub_in_module.rs @@ -33,7 +33,7 @@ pub mod inner { // Make sure the logic is not affected by re-exports. mod unrenamed { //@ !has krate/macro.unrenamed.html - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] pub macro unrenamed() {} } //@ has krate/inner/macro.unrenamed.html diff --git a/tests/rustdoc/macro/macro_rules-matchers.rs b/tests/rustdoc-html/macro/macro_rules-matchers.rs similarity index 100% rename from tests/rustdoc/macro/macro_rules-matchers.rs rename to tests/rustdoc-html/macro/macro_rules-matchers.rs diff --git a/tests/rustdoc/macro/macros.rs b/tests/rustdoc-html/macro/macros.rs similarity index 100% rename from tests/rustdoc/macro/macros.rs rename to tests/rustdoc-html/macro/macros.rs diff --git a/tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs b/tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-99221.rs similarity index 100% rename from tests/rustdoc/macro/multiple-macro-rules-w-same-name-99221.rs rename to tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-99221.rs diff --git a/tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs b/tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-submodule-99221.rs similarity index 100% rename from tests/rustdoc/macro/multiple-macro-rules-w-same-name-submodule-99221.rs rename to tests/rustdoc-html/macro/multiple-macro-rules-w-same-name-submodule-99221.rs diff --git a/tests/rustdoc/macro/one-line-expand.rs b/tests/rustdoc-html/macro/one-line-expand.rs similarity index 100% rename from tests/rustdoc/macro/one-line-expand.rs rename to tests/rustdoc-html/macro/one-line-expand.rs diff --git a/tests/rustdoc/macro/proc-macro.rs b/tests/rustdoc-html/macro/proc-macro.rs similarity index 100% rename from tests/rustdoc/macro/proc-macro.rs rename to tests/rustdoc-html/macro/proc-macro.rs diff --git a/tests/rustdoc/macro/pub-use-extern-macros.rs b/tests/rustdoc-html/macro/pub-use-extern-macros.rs similarity index 100% rename from tests/rustdoc/macro/pub-use-extern-macros.rs rename to tests/rustdoc-html/macro/pub-use-extern-macros.rs diff --git a/tests/rustdoc/macro/rustc-macro-crate.rs b/tests/rustdoc-html/macro/rustc-macro-crate.rs similarity index 100% rename from tests/rustdoc/macro/rustc-macro-crate.rs rename to tests/rustdoc-html/macro/rustc-macro-crate.rs diff --git a/tests/rustdoc/markdown-60482.rs b/tests/rustdoc-html/markdown-60482.rs similarity index 100% rename from tests/rustdoc/markdown-60482.rs rename to tests/rustdoc-html/markdown-60482.rs diff --git a/tests/rustdoc/markdown-table-escape-pipe-27862.rs b/tests/rustdoc-html/markdown-table-escape-pipe-27862.rs similarity index 100% rename from tests/rustdoc/markdown-table-escape-pipe-27862.rs rename to tests/rustdoc-html/markdown-table-escape-pipe-27862.rs diff --git a/tests/rustdoc/masked.rs b/tests/rustdoc-html/masked.rs similarity index 100% rename from tests/rustdoc/masked.rs rename to tests/rustdoc-html/masked.rs diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs b/tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs rename to tests/rustdoc-html/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-separate/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/no-merge-write-anyway/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-include/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite-but-separate/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/overwrite/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/overwrite/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-crate-finalize/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-crate-finalize/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-crate-read-write/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-crate-read-write/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-crate-write-anyway/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-crate-write-anyway/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-finalize/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-none/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-merge-read-write/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs b/tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/sierra.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs rename to tests/rustdoc-html/merge-cross-crate-info/transitive-no-info/sierra.rs diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs b/tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs rename to tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs b/tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/echo.rs similarity index 100% rename from tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs rename to tests/rustdoc-html/merge-cross-crate-info/two-separate-out-dir/echo.rs diff --git a/tests/rustdoc/method-list.rs b/tests/rustdoc-html/method-list.rs similarity index 100% rename from tests/rustdoc/method-list.rs rename to tests/rustdoc-html/method-list.rs diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html b/tests/rustdoc-html/mixing-doc-comments-and-attrs.S1_top-doc.html similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.S1_top-doc.html rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.S1_top-doc.html diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html b/tests/rustdoc-html/mixing-doc-comments-and-attrs.S2_top-doc.html similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.S2_top-doc.html rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.S2_top-doc.html diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.S3_top-doc.html b/tests/rustdoc-html/mixing-doc-comments-and-attrs.S3_top-doc.html similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.S3_top-doc.html rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.S3_top-doc.html diff --git a/tests/rustdoc/mixing-doc-comments-and-attrs.rs b/tests/rustdoc-html/mixing-doc-comments-and-attrs.rs similarity index 100% rename from tests/rustdoc/mixing-doc-comments-and-attrs.rs rename to tests/rustdoc-html/mixing-doc-comments-and-attrs.rs diff --git a/tests/rustdoc/mod-stackoverflow.rs b/tests/rustdoc-html/mod-stackoverflow.rs similarity index 100% rename from tests/rustdoc/mod-stackoverflow.rs rename to tests/rustdoc-html/mod-stackoverflow.rs diff --git a/tests/rustdoc/multiple-foreigns-w-same-name-99734.rs b/tests/rustdoc-html/multiple-foreigns-w-same-name-99734.rs similarity index 100% rename from tests/rustdoc/multiple-foreigns-w-same-name-99734.rs rename to tests/rustdoc-html/multiple-foreigns-w-same-name-99734.rs diff --git a/tests/rustdoc/multiple-import-levels.rs b/tests/rustdoc-html/multiple-import-levels.rs similarity index 100% rename from tests/rustdoc/multiple-import-levels.rs rename to tests/rustdoc-html/multiple-import-levels.rs diff --git a/tests/rustdoc/multiple-mods-w-same-name-99734.rs b/tests/rustdoc-html/multiple-mods-w-same-name-99734.rs similarity index 100% rename from tests/rustdoc/multiple-mods-w-same-name-99734.rs rename to tests/rustdoc-html/multiple-mods-w-same-name-99734.rs diff --git a/tests/rustdoc/multiple-mods-w-same-name-doc-inline-83375.rs b/tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-83375.rs similarity index 100% rename from tests/rustdoc/multiple-mods-w-same-name-doc-inline-83375.rs rename to tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-83375.rs diff --git a/tests/rustdoc/multiple-mods-w-same-name-doc-inline-last-item-83375.rs b/tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-last-item-83375.rs similarity index 100% rename from tests/rustdoc/multiple-mods-w-same-name-doc-inline-last-item-83375.rs rename to tests/rustdoc-html/multiple-mods-w-same-name-doc-inline-last-item-83375.rs diff --git a/tests/rustdoc/multiple-structs-w-same-name-99221.rs b/tests/rustdoc-html/multiple-structs-w-same-name-99221.rs similarity index 100% rename from tests/rustdoc/multiple-structs-w-same-name-99221.rs rename to tests/rustdoc-html/multiple-structs-w-same-name-99221.rs diff --git a/tests/rustdoc/mut-params.rs b/tests/rustdoc-html/mut-params.rs similarity index 100% rename from tests/rustdoc/mut-params.rs rename to tests/rustdoc-html/mut-params.rs diff --git a/tests/rustdoc/namespaces.rs b/tests/rustdoc-html/namespaces.rs similarity index 100% rename from tests/rustdoc/namespaces.rs rename to tests/rustdoc-html/namespaces.rs diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc-html/nested-items-issue-111415.rs similarity index 100% rename from tests/rustdoc/nested-items-issue-111415.rs rename to tests/rustdoc-html/nested-items-issue-111415.rs diff --git a/tests/rustdoc/nested-modules.rs b/tests/rustdoc-html/nested-modules.rs similarity index 100% rename from tests/rustdoc/nested-modules.rs rename to tests/rustdoc-html/nested-modules.rs diff --git a/tests/rustdoc/no-run-still-checks-lints.rs b/tests/rustdoc-html/no-run-still-checks-lints.rs similarity index 100% rename from tests/rustdoc/no-run-still-checks-lints.rs rename to tests/rustdoc-html/no-run-still-checks-lints.rs diff --git a/tests/rustdoc/no-stack-overflow-25295.rs b/tests/rustdoc-html/no-stack-overflow-25295.rs similarity index 100% rename from tests/rustdoc/no-stack-overflow-25295.rs rename to tests/rustdoc-html/no-stack-overflow-25295.rs diff --git a/tests/rustdoc/no-unit-struct-field.rs b/tests/rustdoc-html/no-unit-struct-field.rs similarity index 100% rename from tests/rustdoc/no-unit-struct-field.rs rename to tests/rustdoc-html/no-unit-struct-field.rs diff --git a/tests/rustdoc/non_lifetime_binders.rs b/tests/rustdoc-html/non_lifetime_binders.rs similarity index 100% rename from tests/rustdoc/non_lifetime_binders.rs rename to tests/rustdoc-html/non_lifetime_binders.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-negative.negative.html b/tests/rustdoc-html/notable-trait/doc-notable_trait-negative.negative.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-negative.negative.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait-negative.negative.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-negative.positive.html b/tests/rustdoc-html/notable-trait/doc-notable_trait-negative.positive.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-negative.positive.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait-negative.positive.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-negative.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-negative.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-negative.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-negative.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html b/tests/rustdoc-html/notable-trait/doc-notable_trait-slice.bare_fn_matches.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-slice.bare_fn_matches.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait-slice.bare_fn_matches.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-slice.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait-slice.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait-slice.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait-slice.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html b/tests/rustdoc-html/notable-trait/doc-notable_trait.bare-fn.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.bare-fn.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait.bare-fn.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait.rs diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html b/tests/rustdoc-html/notable-trait/doc-notable_trait.some-struct-new.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.some-struct-new.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait.some-struct-new.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html b/tests/rustdoc-html/notable-trait/doc-notable_trait.wrap-me.html similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait.wrap-me.html rename to tests/rustdoc-html/notable-trait/doc-notable_trait.wrap-me.html diff --git a/tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs b/tests/rustdoc-html/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs similarity index 100% rename from tests/rustdoc/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs rename to tests/rustdoc-html/notable-trait/doc-notable_trait_box_is_not_an_iterator.rs diff --git a/tests/rustdoc/notable-trait/notable-trait-generics.rs b/tests/rustdoc-html/notable-trait/notable-trait-generics.rs similarity index 100% rename from tests/rustdoc/notable-trait/notable-trait-generics.rs rename to tests/rustdoc-html/notable-trait/notable-trait-generics.rs diff --git a/tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html b/tests/rustdoc-html/notable-trait/spotlight-from-dependency.odd.html similarity index 100% rename from tests/rustdoc/notable-trait/spotlight-from-dependency.odd.html rename to tests/rustdoc-html/notable-trait/spotlight-from-dependency.odd.html diff --git a/tests/rustdoc/notable-trait/spotlight-from-dependency.rs b/tests/rustdoc-html/notable-trait/spotlight-from-dependency.rs similarity index 100% rename from tests/rustdoc/notable-trait/spotlight-from-dependency.rs rename to tests/rustdoc-html/notable-trait/spotlight-from-dependency.rs diff --git a/tests/rustdoc/nul-error.rs b/tests/rustdoc-html/nul-error.rs similarity index 100% rename from tests/rustdoc/nul-error.rs rename to tests/rustdoc-html/nul-error.rs diff --git a/tests/rustdoc/playground-arg.rs b/tests/rustdoc-html/playground-arg.rs similarity index 100% rename from tests/rustdoc/playground-arg.rs rename to tests/rustdoc-html/playground-arg.rs diff --git a/tests/rustdoc/playground-empty.rs b/tests/rustdoc-html/playground-empty.rs similarity index 100% rename from tests/rustdoc/playground-empty.rs rename to tests/rustdoc-html/playground-empty.rs diff --git a/tests/rustdoc/playground-none.rs b/tests/rustdoc-html/playground-none.rs similarity index 100% rename from tests/rustdoc/playground-none.rs rename to tests/rustdoc-html/playground-none.rs diff --git a/tests/rustdoc/playground-syntax-error.rs b/tests/rustdoc-html/playground-syntax-error.rs similarity index 100% rename from tests/rustdoc/playground-syntax-error.rs rename to tests/rustdoc-html/playground-syntax-error.rs diff --git a/tests/rustdoc/playground.rs b/tests/rustdoc-html/playground.rs similarity index 100% rename from tests/rustdoc/playground.rs rename to tests/rustdoc-html/playground.rs diff --git a/tests/rustdoc/primitive/auxiliary/issue-15318.rs b/tests/rustdoc-html/primitive/auxiliary/issue-15318.rs similarity index 100% rename from tests/rustdoc/primitive/auxiliary/issue-15318.rs rename to tests/rustdoc-html/primitive/auxiliary/issue-15318.rs diff --git a/tests/rustdoc/primitive/auxiliary/primitive-doc.rs b/tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs similarity index 100% rename from tests/rustdoc/primitive/auxiliary/primitive-doc.rs rename to tests/rustdoc-html/primitive/auxiliary/primitive-doc.rs diff --git a/tests/rustdoc/primitive/cross-crate-primitive-doc.rs b/tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs similarity index 100% rename from tests/rustdoc/primitive/cross-crate-primitive-doc.rs rename to tests/rustdoc-html/primitive/cross-crate-primitive-doc.rs diff --git a/tests/rustdoc/primitive/no_std-primitive.rs b/tests/rustdoc-html/primitive/no_std-primitive.rs similarity index 100% rename from tests/rustdoc/primitive/no_std-primitive.rs rename to tests/rustdoc-html/primitive/no_std-primitive.rs diff --git a/tests/rustdoc/primitive/no_std.rs b/tests/rustdoc-html/primitive/no_std.rs similarity index 100% rename from tests/rustdoc/primitive/no_std.rs rename to tests/rustdoc-html/primitive/no_std.rs diff --git a/tests/rustdoc/primitive/primitive-generic-impl.rs b/tests/rustdoc-html/primitive/primitive-generic-impl.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-generic-impl.rs rename to tests/rustdoc-html/primitive/primitive-generic-impl.rs diff --git a/tests/rustdoc/primitive/primitive-link.rs b/tests/rustdoc-html/primitive/primitive-link.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-link.rs rename to tests/rustdoc-html/primitive/primitive-link.rs diff --git a/tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-raw-pointer-dox-15318-3.rs rename to tests/rustdoc-html/primitive/primitive-raw-pointer-dox-15318-3.rs diff --git a/tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-link-15318.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-raw-pointer-link-15318.rs rename to tests/rustdoc-html/primitive/primitive-raw-pointer-link-15318.rs diff --git a/tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs b/tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs rename to tests/rustdoc-html/primitive/primitive-raw-pointer-link-no-inlined-15318-2.rs diff --git a/tests/rustdoc/primitive/primitive-reference.rs b/tests/rustdoc-html/primitive/primitive-reference.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-reference.rs rename to tests/rustdoc-html/primitive/primitive-reference.rs diff --git a/tests/rustdoc/primitive/primitive-slice-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-slice-auto-trait.rs rename to tests/rustdoc-html/primitive/primitive-slice-auto-trait.rs diff --git a/tests/rustdoc/primitive/primitive-tuple-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-tuple-auto-trait.rs rename to tests/rustdoc-html/primitive/primitive-tuple-auto-trait.rs diff --git a/tests/rustdoc/primitive/primitive-tuple-variadic.rs b/tests/rustdoc-html/primitive/primitive-tuple-variadic.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-tuple-variadic.rs rename to tests/rustdoc-html/primitive/primitive-tuple-variadic.rs diff --git a/tests/rustdoc/primitive/primitive-unit-auto-trait.rs b/tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs similarity index 100% rename from tests/rustdoc/primitive/primitive-unit-auto-trait.rs rename to tests/rustdoc-html/primitive/primitive-unit-auto-trait.rs diff --git a/tests/rustdoc/primitive/primitive.rs b/tests/rustdoc-html/primitive/primitive.rs similarity index 100% rename from tests/rustdoc/primitive/primitive.rs rename to tests/rustdoc-html/primitive/primitive.rs diff --git a/tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs b/tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs similarity index 100% rename from tests/rustdoc/primitive/search-index-primitive-inherent-method-23511.rs rename to tests/rustdoc-html/primitive/search-index-primitive-inherent-method-23511.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-both.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-both.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-both.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-both.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-hidden.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-hidden.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-hidden.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-hidden.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-neither.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-neither.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-neither.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-neither.rs diff --git a/tests/rustdoc/private/doc-hidden-private-67851-private.rs b/tests/rustdoc-html/private/doc-hidden-private-67851-private.rs similarity index 100% rename from tests/rustdoc/private/doc-hidden-private-67851-private.rs rename to tests/rustdoc-html/private/doc-hidden-private-67851-private.rs diff --git a/tests/rustdoc/private/empty-impl-block-private-with-doc.rs b/tests/rustdoc-html/private/empty-impl-block-private-with-doc.rs similarity index 100% rename from tests/rustdoc/private/empty-impl-block-private-with-doc.rs rename to tests/rustdoc-html/private/empty-impl-block-private-with-doc.rs diff --git a/tests/rustdoc/private/empty-impl-block-private.rs b/tests/rustdoc-html/private/empty-impl-block-private.rs similarity index 100% rename from tests/rustdoc/private/empty-impl-block-private.rs rename to tests/rustdoc-html/private/empty-impl-block-private.rs diff --git a/tests/rustdoc/private/empty-mod-private.rs b/tests/rustdoc-html/private/empty-mod-private.rs similarity index 100% rename from tests/rustdoc/private/empty-mod-private.rs rename to tests/rustdoc-html/private/empty-mod-private.rs diff --git a/tests/rustdoc/private/enum-variant-private-46767.rs b/tests/rustdoc-html/private/enum-variant-private-46767.rs similarity index 100% rename from tests/rustdoc/private/enum-variant-private-46767.rs rename to tests/rustdoc-html/private/enum-variant-private-46767.rs diff --git a/tests/rustdoc/private/files-creation-private.rs b/tests/rustdoc-html/private/files-creation-private.rs similarity index 100% rename from tests/rustdoc/private/files-creation-private.rs rename to tests/rustdoc-html/private/files-creation-private.rs diff --git a/tests/rustdoc/private/hidden-private.rs b/tests/rustdoc-html/private/hidden-private.rs similarity index 100% rename from tests/rustdoc/private/hidden-private.rs rename to tests/rustdoc-html/private/hidden-private.rs diff --git a/tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc-html/private/inline-private-with-intermediate-doc-hidden.rs similarity index 100% rename from tests/rustdoc/private/inline-private-with-intermediate-doc-hidden.rs rename to tests/rustdoc-html/private/inline-private-with-intermediate-doc-hidden.rs diff --git a/tests/rustdoc/private/inner-private-110422.rs b/tests/rustdoc-html/private/inner-private-110422.rs similarity index 100% rename from tests/rustdoc/private/inner-private-110422.rs rename to tests/rustdoc-html/private/inner-private-110422.rs diff --git a/tests/rustdoc/private/macro-document-private-duplicate.rs b/tests/rustdoc-html/private/macro-document-private-duplicate.rs similarity index 100% rename from tests/rustdoc/private/macro-document-private-duplicate.rs rename to tests/rustdoc-html/private/macro-document-private-duplicate.rs diff --git a/tests/rustdoc/private/macro-document-private.rs b/tests/rustdoc-html/private/macro-document-private.rs similarity index 100% rename from tests/rustdoc/private/macro-document-private.rs rename to tests/rustdoc-html/private/macro-document-private.rs diff --git a/tests/rustdoc/private/macro-private-not-documented.rs b/tests/rustdoc-html/private/macro-private-not-documented.rs similarity index 100% rename from tests/rustdoc/private/macro-private-not-documented.rs rename to tests/rustdoc-html/private/macro-private-not-documented.rs diff --git a/tests/rustdoc/private/missing-private-inlining-109258.rs b/tests/rustdoc-html/private/missing-private-inlining-109258.rs similarity index 100% rename from tests/rustdoc/private/missing-private-inlining-109258.rs rename to tests/rustdoc-html/private/missing-private-inlining-109258.rs diff --git a/tests/rustdoc/private/private-fields-tuple-struct.rs b/tests/rustdoc-html/private/private-fields-tuple-struct.rs similarity index 100% rename from tests/rustdoc/private/private-fields-tuple-struct.rs rename to tests/rustdoc-html/private/private-fields-tuple-struct.rs diff --git a/tests/rustdoc/private/private-non-local-fields-2.rs b/tests/rustdoc-html/private/private-non-local-fields-2.rs similarity index 100% rename from tests/rustdoc/private/private-non-local-fields-2.rs rename to tests/rustdoc-html/private/private-non-local-fields-2.rs diff --git a/tests/rustdoc/private/private-non-local-fields.rs b/tests/rustdoc-html/private/private-non-local-fields.rs similarity index 100% rename from tests/rustdoc/private/private-non-local-fields.rs rename to tests/rustdoc-html/private/private-non-local-fields.rs diff --git a/tests/rustdoc/private/private-type-alias.rs b/tests/rustdoc-html/private/private-type-alias.rs similarity index 100% rename from tests/rustdoc/private/private-type-alias.rs rename to tests/rustdoc-html/private/private-type-alias.rs diff --git a/tests/rustdoc/private/private-type-cycle-110629.rs b/tests/rustdoc-html/private/private-type-cycle-110629.rs similarity index 100% rename from tests/rustdoc/private/private-type-cycle-110629.rs rename to tests/rustdoc-html/private/private-type-cycle-110629.rs diff --git a/tests/rustdoc/private/private-use-decl-macro-47038.rs b/tests/rustdoc-html/private/private-use-decl-macro-47038.rs similarity index 100% rename from tests/rustdoc/private/private-use-decl-macro-47038.rs rename to tests/rustdoc-html/private/private-use-decl-macro-47038.rs diff --git a/tests/rustdoc/private/private-use.rs b/tests/rustdoc-html/private/private-use.rs similarity index 100% rename from tests/rustdoc/private/private-use.rs rename to tests/rustdoc-html/private/private-use.rs diff --git a/tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs b/tests/rustdoc-html/private/public-impl-mention-private-generic-46380-2.rs similarity index 100% rename from tests/rustdoc/private/public-impl-mention-private-generic-46380-2.rs rename to tests/rustdoc-html/private/public-impl-mention-private-generic-46380-2.rs diff --git a/tests/rustdoc/private/traits-in-bodies-private.rs b/tests/rustdoc-html/private/traits-in-bodies-private.rs similarity index 100% rename from tests/rustdoc/private/traits-in-bodies-private.rs rename to tests/rustdoc-html/private/traits-in-bodies-private.rs diff --git a/tests/rustdoc/process-termination.rs b/tests/rustdoc-html/process-termination.rs similarity index 100% rename from tests/rustdoc/process-termination.rs rename to tests/rustdoc-html/process-termination.rs diff --git a/tests/rustdoc/pub-method.rs b/tests/rustdoc-html/pub-method.rs similarity index 100% rename from tests/rustdoc/pub-method.rs rename to tests/rustdoc-html/pub-method.rs diff --git a/tests/rustdoc/pub-use-loop-107350.rs b/tests/rustdoc-html/pub-use-loop-107350.rs similarity index 100% rename from tests/rustdoc/pub-use-loop-107350.rs rename to tests/rustdoc-html/pub-use-loop-107350.rs diff --git a/tests/rustdoc/pub-use-root-path-95873.rs b/tests/rustdoc-html/pub-use-root-path-95873.rs similarity index 100% rename from tests/rustdoc/pub-use-root-path-95873.rs rename to tests/rustdoc-html/pub-use-root-path-95873.rs diff --git a/tests/rustdoc/range-arg-pattern.rs b/tests/rustdoc-html/range-arg-pattern.rs similarity index 100% rename from tests/rustdoc/range-arg-pattern.rs rename to tests/rustdoc-html/range-arg-pattern.rs diff --git a/tests/rustdoc/raw-ident-eliminate-r-hashtag.rs b/tests/rustdoc-html/raw-ident-eliminate-r-hashtag.rs similarity index 100% rename from tests/rustdoc/raw-ident-eliminate-r-hashtag.rs rename to tests/rustdoc-html/raw-ident-eliminate-r-hashtag.rs diff --git a/tests/rustdoc/read-more-unneeded.rs b/tests/rustdoc-html/read-more-unneeded.rs similarity index 100% rename from tests/rustdoc/read-more-unneeded.rs rename to tests/rustdoc-html/read-more-unneeded.rs diff --git a/tests/rustdoc/recursion1.rs b/tests/rustdoc-html/recursion1.rs similarity index 100% rename from tests/rustdoc/recursion1.rs rename to tests/rustdoc-html/recursion1.rs diff --git a/tests/rustdoc/recursion2.rs b/tests/rustdoc-html/recursion2.rs similarity index 100% rename from tests/rustdoc/recursion2.rs rename to tests/rustdoc-html/recursion2.rs diff --git a/tests/rustdoc/recursion3.rs b/tests/rustdoc-html/recursion3.rs similarity index 100% rename from tests/rustdoc/recursion3.rs rename to tests/rustdoc-html/recursion3.rs diff --git a/tests/rustdoc/redirect-map-empty.rs b/tests/rustdoc-html/redirect-map-empty.rs similarity index 100% rename from tests/rustdoc/redirect-map-empty.rs rename to tests/rustdoc-html/redirect-map-empty.rs diff --git a/tests/rustdoc/redirect-map.rs b/tests/rustdoc-html/redirect-map.rs similarity index 100% rename from tests/rustdoc/redirect-map.rs rename to tests/rustdoc-html/redirect-map.rs diff --git a/tests/rustdoc/redirect-rename.rs b/tests/rustdoc-html/redirect-rename.rs similarity index 100% rename from tests/rustdoc/redirect-rename.rs rename to tests/rustdoc-html/redirect-rename.rs diff --git a/tests/rustdoc/redirect.rs b/tests/rustdoc-html/redirect.rs similarity index 100% rename from tests/rustdoc/redirect.rs rename to tests/rustdoc-html/redirect.rs diff --git a/tests/rustdoc/reexport/alias-reexport.rs b/tests/rustdoc-html/reexport/alias-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/alias-reexport.rs rename to tests/rustdoc-html/reexport/alias-reexport.rs diff --git a/tests/rustdoc/reexport/alias-reexport2.rs b/tests/rustdoc-html/reexport/alias-reexport2.rs similarity index 100% rename from tests/rustdoc/reexport/alias-reexport2.rs rename to tests/rustdoc-html/reexport/alias-reexport2.rs diff --git a/tests/rustdoc/reexport/anonymous-reexport-108931.rs b/tests/rustdoc-html/reexport/anonymous-reexport-108931.rs similarity index 100% rename from tests/rustdoc/reexport/anonymous-reexport-108931.rs rename to tests/rustdoc-html/reexport/anonymous-reexport-108931.rs diff --git a/tests/rustdoc/reexport/anonymous-reexport.rs b/tests/rustdoc-html/reexport/anonymous-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/anonymous-reexport.rs rename to tests/rustdoc-html/reexport/anonymous-reexport.rs diff --git a/tests/rustdoc/reexport/auxiliary/alias-reexport.rs b/tests/rustdoc-html/reexport/auxiliary/alias-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/alias-reexport.rs rename to tests/rustdoc-html/reexport/auxiliary/alias-reexport.rs diff --git a/tests/rustdoc/reexport/auxiliary/alias-reexport2.rs b/tests/rustdoc-html/reexport/auxiliary/alias-reexport2.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/alias-reexport2.rs rename to tests/rustdoc-html/reexport/auxiliary/alias-reexport2.rs diff --git a/tests/rustdoc/reexport/auxiliary/all-item-types.rs b/tests/rustdoc-html/reexport/auxiliary/all-item-types.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/all-item-types.rs rename to tests/rustdoc-html/reexport/auxiliary/all-item-types.rs diff --git a/tests/rustdoc/reexport/auxiliary/issue-28927-1.rs b/tests/rustdoc-html/reexport/auxiliary/issue-28927-1.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/issue-28927-1.rs rename to tests/rustdoc-html/reexport/auxiliary/issue-28927-1.rs diff --git a/tests/rustdoc/reexport/auxiliary/issue-28927-2.rs b/tests/rustdoc-html/reexport/auxiliary/issue-28927-2.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/issue-28927-2.rs rename to tests/rustdoc-html/reexport/auxiliary/issue-28927-2.rs diff --git a/tests/rustdoc/reexport/auxiliary/primitive-reexport.rs b/tests/rustdoc-html/reexport/auxiliary/primitive-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/primitive-reexport.rs rename to tests/rustdoc-html/reexport/auxiliary/primitive-reexport.rs diff --git a/tests/rustdoc/reexport/auxiliary/reexport-check.rs b/tests/rustdoc-html/reexport/auxiliary/reexport-check.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/reexport-check.rs rename to tests/rustdoc-html/reexport/auxiliary/reexport-check.rs diff --git a/tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs b/tests/rustdoc-html/reexport/auxiliary/reexport-doc-aux.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/reexport-doc-aux.rs rename to tests/rustdoc-html/reexport/auxiliary/reexport-doc-aux.rs diff --git a/tests/rustdoc/reexport/auxiliary/reexports.rs b/tests/rustdoc-html/reexport/auxiliary/reexports.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/reexports.rs rename to tests/rustdoc-html/reexport/auxiliary/reexports.rs diff --git a/tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs b/tests/rustdoc-html/reexport/auxiliary/wrap-unnamable-type.rs similarity index 100% rename from tests/rustdoc/reexport/auxiliary/wrap-unnamable-type.rs rename to tests/rustdoc-html/reexport/auxiliary/wrap-unnamable-type.rs diff --git a/tests/rustdoc/reexport/blanket-reexport-item.rs b/tests/rustdoc-html/reexport/blanket-reexport-item.rs similarity index 100% rename from tests/rustdoc/reexport/blanket-reexport-item.rs rename to tests/rustdoc-html/reexport/blanket-reexport-item.rs diff --git a/tests/rustdoc/reexport/cfg_doc_reexport.rs b/tests/rustdoc-html/reexport/cfg_doc_reexport.rs similarity index 100% rename from tests/rustdoc/reexport/cfg_doc_reexport.rs rename to tests/rustdoc-html/reexport/cfg_doc_reexport.rs diff --git a/tests/rustdoc/reexport/doc-hidden-reexports-109449.rs b/tests/rustdoc-html/reexport/doc-hidden-reexports-109449.rs similarity index 100% rename from tests/rustdoc/reexport/doc-hidden-reexports-109449.rs rename to tests/rustdoc-html/reexport/doc-hidden-reexports-109449.rs diff --git a/tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs b/tests/rustdoc-html/reexport/duplicated-glob-reexport-60522.rs similarity index 100% rename from tests/rustdoc/reexport/duplicated-glob-reexport-60522.rs rename to tests/rustdoc-html/reexport/duplicated-glob-reexport-60522.rs diff --git a/tests/rustdoc/reexport/enum-variant-reexport-35488.rs b/tests/rustdoc-html/reexport/enum-variant-reexport-35488.rs similarity index 100% rename from tests/rustdoc/reexport/enum-variant-reexport-35488.rs rename to tests/rustdoc-html/reexport/enum-variant-reexport-35488.rs diff --git a/tests/rustdoc/reexport/enum-variant.rs b/tests/rustdoc-html/reexport/enum-variant.rs similarity index 100% rename from tests/rustdoc/reexport/enum-variant.rs rename to tests/rustdoc-html/reexport/enum-variant.rs diff --git a/tests/rustdoc/reexport/extern-135092.rs b/tests/rustdoc-html/reexport/extern-135092.rs similarity index 100% rename from tests/rustdoc/reexport/extern-135092.rs rename to tests/rustdoc-html/reexport/extern-135092.rs diff --git a/tests/rustdoc/reexport/foreigntype-reexport.rs b/tests/rustdoc-html/reexport/foreigntype-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/foreigntype-reexport.rs rename to tests/rustdoc-html/reexport/foreigntype-reexport.rs diff --git a/tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs b/tests/rustdoc-html/reexport/glob-reexport-attribute-merge-120487.rs similarity index 100% rename from tests/rustdoc/reexport/glob-reexport-attribute-merge-120487.rs rename to tests/rustdoc-html/reexport/glob-reexport-attribute-merge-120487.rs diff --git a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc-html/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs similarity index 100% rename from tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs rename to tests/rustdoc-html/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs diff --git a/tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs b/tests/rustdoc-html/reexport/ice-reexport-crate-root-28927.rs similarity index 100% rename from tests/rustdoc/reexport/ice-reexport-crate-root-28927.rs rename to tests/rustdoc-html/reexport/ice-reexport-crate-root-28927.rs diff --git a/tests/rustdoc/reexport/import_trait_associated_functions.rs b/tests/rustdoc-html/reexport/import_trait_associated_functions.rs similarity index 100% rename from tests/rustdoc/reexport/import_trait_associated_functions.rs rename to tests/rustdoc-html/reexport/import_trait_associated_functions.rs diff --git a/tests/rustdoc/reexport/local-reexport-doc.rs b/tests/rustdoc-html/reexport/local-reexport-doc.rs similarity index 100% rename from tests/rustdoc/reexport/local-reexport-doc.rs rename to tests/rustdoc-html/reexport/local-reexport-doc.rs diff --git a/tests/rustdoc/reexport/merge-glob-and-non-glob.rs b/tests/rustdoc-html/reexport/merge-glob-and-non-glob.rs similarity index 100% rename from tests/rustdoc/reexport/merge-glob-and-non-glob.rs rename to tests/rustdoc-html/reexport/merge-glob-and-non-glob.rs diff --git a/tests/rustdoc/reexport/no-compiler-reexport.rs b/tests/rustdoc-html/reexport/no-compiler-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/no-compiler-reexport.rs rename to tests/rustdoc-html/reexport/no-compiler-reexport.rs diff --git a/tests/rustdoc/reexport/overlapping-reexport-105735-2.rs b/tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs similarity index 100% rename from tests/rustdoc/reexport/overlapping-reexport-105735-2.rs rename to tests/rustdoc-html/reexport/overlapping-reexport-105735-2.rs diff --git a/tests/rustdoc/reexport/overlapping-reexport-105735.rs b/tests/rustdoc-html/reexport/overlapping-reexport-105735.rs similarity index 100% rename from tests/rustdoc/reexport/overlapping-reexport-105735.rs rename to tests/rustdoc-html/reexport/overlapping-reexport-105735.rs diff --git a/tests/rustdoc/reexport/primitive-reexport.rs b/tests/rustdoc-html/reexport/primitive-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/primitive-reexport.rs rename to tests/rustdoc-html/reexport/primitive-reexport.rs diff --git a/tests/rustdoc/reexport/private-mod-override-reexport.rs b/tests/rustdoc-html/reexport/private-mod-override-reexport.rs similarity index 100% rename from tests/rustdoc/reexport/private-mod-override-reexport.rs rename to tests/rustdoc-html/reexport/private-mod-override-reexport.rs diff --git a/tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs b/tests/rustdoc-html/reexport/pub-reexport-of-pub-reexport-46506.rs similarity index 100% rename from tests/rustdoc/reexport/pub-reexport-of-pub-reexport-46506.rs rename to tests/rustdoc-html/reexport/pub-reexport-of-pub-reexport-46506.rs diff --git a/tests/rustdoc/reexport/reexport-attr-merge.rs b/tests/rustdoc-html/reexport/reexport-attr-merge.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-attr-merge.rs rename to tests/rustdoc-html/reexport/reexport-attr-merge.rs diff --git a/tests/rustdoc/reexport/reexport-cfg.rs b/tests/rustdoc-html/reexport/reexport-cfg.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-cfg.rs rename to tests/rustdoc-html/reexport/reexport-cfg.rs diff --git a/tests/rustdoc/reexport/reexport-check.rs b/tests/rustdoc-html/reexport/reexport-check.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-check.rs rename to tests/rustdoc-html/reexport/reexport-check.rs diff --git a/tests/rustdoc/reexport/reexport-dep-foreign-fn.rs b/tests/rustdoc-html/reexport/reexport-dep-foreign-fn.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-dep-foreign-fn.rs rename to tests/rustdoc-html/reexport/reexport-dep-foreign-fn.rs diff --git a/tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs b/tests/rustdoc-html/reexport/reexport-doc-hidden-inside-private.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-doc-hidden-inside-private.rs rename to tests/rustdoc-html/reexport/reexport-doc-hidden-inside-private.rs diff --git a/tests/rustdoc/reexport/reexport-doc-hidden.rs b/tests/rustdoc-html/reexport/reexport-doc-hidden.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-doc-hidden.rs rename to tests/rustdoc-html/reexport/reexport-doc-hidden.rs diff --git a/tests/rustdoc/reexport/reexport-doc.rs b/tests/rustdoc-html/reexport/reexport-doc.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-doc.rs rename to tests/rustdoc-html/reexport/reexport-doc.rs diff --git a/tests/rustdoc/reexport/reexport-hidden-macro.rs b/tests/rustdoc-html/reexport/reexport-hidden-macro.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-hidden-macro.rs rename to tests/rustdoc-html/reexport/reexport-hidden-macro.rs diff --git a/tests/rustdoc/reexport/reexport-macro.rs b/tests/rustdoc-html/reexport/reexport-macro.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-macro.rs rename to tests/rustdoc-html/reexport/reexport-macro.rs diff --git a/tests/rustdoc/reexport/reexport-of-doc-hidden.rs b/tests/rustdoc-html/reexport/reexport-of-doc-hidden.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-of-doc-hidden.rs rename to tests/rustdoc-html/reexport/reexport-of-doc-hidden.rs diff --git a/tests/rustdoc/reexport/reexport-of-reexport-108679.rs b/tests/rustdoc-html/reexport/reexport-of-reexport-108679.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-of-reexport-108679.rs rename to tests/rustdoc-html/reexport/reexport-of-reexport-108679.rs diff --git a/tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs b/tests/rustdoc-html/reexport/reexport-stability-tags-deprecated-and-portability.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-stability-tags-deprecated-and-portability.rs rename to tests/rustdoc-html/reexport/reexport-stability-tags-deprecated-and-portability.rs diff --git a/tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs b/tests/rustdoc-html/reexport/reexport-stability-tags-unstable-and-portability.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-stability-tags-unstable-and-portability.rs rename to tests/rustdoc-html/reexport/reexport-stability-tags-unstable-and-portability.rs diff --git a/tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs b/tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064-2.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-trait-from-hidden-111064-2.rs rename to tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064-2.rs diff --git a/tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs b/tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064.rs similarity index 100% rename from tests/rustdoc/reexport/reexport-trait-from-hidden-111064.rs rename to tests/rustdoc-html/reexport/reexport-trait-from-hidden-111064.rs diff --git a/tests/rustdoc/reexport/reexports-of-same-name.rs b/tests/rustdoc-html/reexport/reexports-of-same-name.rs similarity index 100% rename from tests/rustdoc/reexport/reexports-of-same-name.rs rename to tests/rustdoc-html/reexport/reexports-of-same-name.rs diff --git a/tests/rustdoc/reexport/reexports-priv.rs b/tests/rustdoc-html/reexport/reexports-priv.rs similarity index 100% rename from tests/rustdoc/reexport/reexports-priv.rs rename to tests/rustdoc-html/reexport/reexports-priv.rs diff --git a/tests/rustdoc/reexport/reexports.rs b/tests/rustdoc-html/reexport/reexports.rs similarity index 100% rename from tests/rustdoc/reexport/reexports.rs rename to tests/rustdoc-html/reexport/reexports.rs diff --git a/tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs b/tests/rustdoc-html/reexport/wrapped-unnamble-type-143222.rs similarity index 100% rename from tests/rustdoc/reexport/wrapped-unnamble-type-143222.rs rename to tests/rustdoc-html/reexport/wrapped-unnamble-type-143222.rs diff --git a/tests/rustdoc/remove-duplicates.rs b/tests/rustdoc-html/remove-duplicates.rs similarity index 100% rename from tests/rustdoc/remove-duplicates.rs rename to tests/rustdoc-html/remove-duplicates.rs diff --git a/tests/rustdoc/remove-url-from-headings.rs b/tests/rustdoc-html/remove-url-from-headings.rs similarity index 100% rename from tests/rustdoc/remove-url-from-headings.rs rename to tests/rustdoc-html/remove-url-from-headings.rs diff --git a/tests/rustdoc/repr.rs b/tests/rustdoc-html/repr.rs similarity index 100% rename from tests/rustdoc/repr.rs rename to tests/rustdoc-html/repr.rs diff --git a/tests/rustdoc/resolve-ice-124363.rs b/tests/rustdoc-html/resolve-ice-124363.rs similarity index 100% rename from tests/rustdoc/resolve-ice-124363.rs rename to tests/rustdoc-html/resolve-ice-124363.rs diff --git a/tests/rustdoc/return-type-notation.rs b/tests/rustdoc-html/return-type-notation.rs similarity index 100% rename from tests/rustdoc/return-type-notation.rs rename to tests/rustdoc-html/return-type-notation.rs diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc-html/safe-intrinsic.rs similarity index 100% rename from tests/rustdoc/safe-intrinsic.rs rename to tests/rustdoc-html/safe-intrinsic.rs diff --git a/tests/rustdoc/sanitizer-option.rs b/tests/rustdoc-html/sanitizer-option.rs similarity index 100% rename from tests/rustdoc/sanitizer-option.rs rename to tests/rustdoc-html/sanitizer-option.rs diff --git a/tests/rustdoc/search-index-summaries.rs b/tests/rustdoc-html/search-index-summaries.rs similarity index 100% rename from tests/rustdoc/search-index-summaries.rs rename to tests/rustdoc-html/search-index-summaries.rs diff --git a/tests/rustdoc/search-index.rs b/tests/rustdoc-html/search-index.rs similarity index 100% rename from tests/rustdoc/search-index.rs rename to tests/rustdoc-html/search-index.rs diff --git a/tests/rustdoc/short-docblock-codeblock.rs b/tests/rustdoc-html/short-docblock-codeblock.rs similarity index 100% rename from tests/rustdoc/short-docblock-codeblock.rs rename to tests/rustdoc-html/short-docblock-codeblock.rs diff --git a/tests/rustdoc/short-docblock.rs b/tests/rustdoc-html/short-docblock.rs similarity index 100% rename from tests/rustdoc/short-docblock.rs rename to tests/rustdoc-html/short-docblock.rs diff --git a/tests/rustdoc/short-line.md b/tests/rustdoc-html/short-line.md similarity index 100% rename from tests/rustdoc/short-line.md rename to tests/rustdoc-html/short-line.md diff --git a/tests/rustdoc/sidebar/module.rs b/tests/rustdoc-html/sidebar/module.rs similarity index 100% rename from tests/rustdoc/sidebar/module.rs rename to tests/rustdoc-html/sidebar/module.rs diff --git a/tests/rustdoc/sidebar/sidebar-all-page.rs b/tests/rustdoc-html/sidebar/sidebar-all-page.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-all-page.rs rename to tests/rustdoc-html/sidebar/sidebar-all-page.rs diff --git a/tests/rustdoc/sidebar/sidebar-items.rs b/tests/rustdoc-html/sidebar/sidebar-items.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-items.rs rename to tests/rustdoc-html/sidebar/sidebar-items.rs diff --git a/tests/rustdoc/sidebar/sidebar-link-generation.rs b/tests/rustdoc-html/sidebar/sidebar-link-generation.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-link-generation.rs rename to tests/rustdoc-html/sidebar/sidebar-link-generation.rs diff --git a/tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs b/tests/rustdoc-html/sidebar/sidebar-links-to-foreign-impl.rs similarity index 100% rename from tests/rustdoc/sidebar/sidebar-links-to-foreign-impl.rs rename to tests/rustdoc-html/sidebar/sidebar-links-to-foreign-impl.rs diff --git a/tests/rustdoc/sidebar/top-toc-html.rs b/tests/rustdoc-html/sidebar/top-toc-html.rs similarity index 100% rename from tests/rustdoc/sidebar/top-toc-html.rs rename to tests/rustdoc-html/sidebar/top-toc-html.rs diff --git a/tests/rustdoc/sidebar/top-toc-idmap.rs b/tests/rustdoc-html/sidebar/top-toc-idmap.rs similarity index 100% rename from tests/rustdoc/sidebar/top-toc-idmap.rs rename to tests/rustdoc-html/sidebar/top-toc-idmap.rs diff --git a/tests/rustdoc/sidebar/top-toc-nil.rs b/tests/rustdoc-html/sidebar/top-toc-nil.rs similarity index 100% rename from tests/rustdoc/sidebar/top-toc-nil.rs rename to tests/rustdoc-html/sidebar/top-toc-nil.rs diff --git a/tests/rustdoc/sized_trait.rs b/tests/rustdoc-html/sized_trait.rs similarity index 100% rename from tests/rustdoc/sized_trait.rs rename to tests/rustdoc-html/sized_trait.rs diff --git a/tests/rustdoc/slice-links.link_box_generic.html b/tests/rustdoc-html/slice-links.link_box_generic.html similarity index 100% rename from tests/rustdoc/slice-links.link_box_generic.html rename to tests/rustdoc-html/slice-links.link_box_generic.html diff --git a/tests/rustdoc/slice-links.link_box_u32.html b/tests/rustdoc-html/slice-links.link_box_u32.html similarity index 100% rename from tests/rustdoc/slice-links.link_box_u32.html rename to tests/rustdoc-html/slice-links.link_box_u32.html diff --git a/tests/rustdoc/slice-links.link_slice_generic.html b/tests/rustdoc-html/slice-links.link_slice_generic.html similarity index 100% rename from tests/rustdoc/slice-links.link_slice_generic.html rename to tests/rustdoc-html/slice-links.link_slice_generic.html diff --git a/tests/rustdoc/slice-links.link_slice_u32.html b/tests/rustdoc-html/slice-links.link_slice_u32.html similarity index 100% rename from tests/rustdoc/slice-links.link_slice_u32.html rename to tests/rustdoc-html/slice-links.link_slice_u32.html diff --git a/tests/rustdoc/slice-links.rs b/tests/rustdoc-html/slice-links.rs similarity index 100% rename from tests/rustdoc/slice-links.rs rename to tests/rustdoc-html/slice-links.rs diff --git a/tests/rustdoc/smart-punct.rs b/tests/rustdoc-html/smart-punct.rs similarity index 100% rename from tests/rustdoc/smart-punct.rs rename to tests/rustdoc-html/smart-punct.rs diff --git a/tests/rustdoc/smoke.rs b/tests/rustdoc-html/smoke.rs similarity index 100% rename from tests/rustdoc/smoke.rs rename to tests/rustdoc-html/smoke.rs diff --git a/tests/rustdoc/sort-53812.rs b/tests/rustdoc-html/sort-53812.rs similarity index 100% rename from tests/rustdoc/sort-53812.rs rename to tests/rustdoc-html/sort-53812.rs diff --git a/tests/rustdoc/sort-modules-by-appearance.rs b/tests/rustdoc-html/sort-modules-by-appearance.rs similarity index 100% rename from tests/rustdoc/sort-modules-by-appearance.rs rename to tests/rustdoc-html/sort-modules-by-appearance.rs diff --git a/tests/rustdoc/source-code-pages/assoc-type-source-link.rs b/tests/rustdoc-html/source-code-pages/assoc-type-source-link.rs similarity index 100% rename from tests/rustdoc/source-code-pages/assoc-type-source-link.rs rename to tests/rustdoc-html/source-code-pages/assoc-type-source-link.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs b/tests/rustdoc-html/source-code-pages/auxiliary/issue-26606-macro.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/issue-26606-macro.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/issue-26606-macro.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs b/tests/rustdoc-html/source-code-pages/auxiliary/issue-34274.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/issue-34274.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/issue-34274.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs b/tests/rustdoc-html/source-code-pages/auxiliary/source-code-bar.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/source-code-bar.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/source-code-bar.rs diff --git a/tests/rustdoc/source-code-pages/auxiliary/source_code.rs b/tests/rustdoc-html/source-code-pages/auxiliary/source_code.rs similarity index 100% rename from tests/rustdoc/source-code-pages/auxiliary/source_code.rs rename to tests/rustdoc-html/source-code-pages/auxiliary/source_code.rs diff --git a/tests/rustdoc-html/source-code-pages/auxiliary/src-links-external.rs b/tests/rustdoc-html/source-code-pages/auxiliary/src-links-external.rs new file mode 100644 index 000000000000..4a835673a596 --- /dev/null +++ b/tests/rustdoc-html/source-code-pages/auxiliary/src-links-external.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs b/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def-std.rs similarity index 100% rename from tests/rustdoc/source-code-pages/check-source-code-urls-to-def-std.rs rename to tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def-std.rs diff --git a/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs b/tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs similarity index 100% rename from tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs rename to tests/rustdoc-html/source-code-pages/check-source-code-urls-to-def.rs diff --git a/tests/rustdoc/source-code-pages/doc-hidden-source.rs b/tests/rustdoc-html/source-code-pages/doc-hidden-source.rs similarity index 100% rename from tests/rustdoc/source-code-pages/doc-hidden-source.rs rename to tests/rustdoc-html/source-code-pages/doc-hidden-source.rs diff --git a/tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs b/tests/rustdoc-html/source-code-pages/failing-expansion-on-wrong-macro.rs similarity index 100% rename from tests/rustdoc/source-code-pages/failing-expansion-on-wrong-macro.rs rename to tests/rustdoc-html/source-code-pages/failing-expansion-on-wrong-macro.rs diff --git a/tests/rustdoc/source-code-pages/frontmatter.rs b/tests/rustdoc-html/source-code-pages/frontmatter.rs similarity index 100% rename from tests/rustdoc/source-code-pages/frontmatter.rs rename to tests/rustdoc-html/source-code-pages/frontmatter.rs diff --git a/tests/rustdoc/source-code-pages/html-no-source.rs b/tests/rustdoc-html/source-code-pages/html-no-source.rs similarity index 100% rename from tests/rustdoc/source-code-pages/html-no-source.rs rename to tests/rustdoc-html/source-code-pages/html-no-source.rs diff --git a/tests/rustdoc/source-code-pages/keyword-macros.rs b/tests/rustdoc-html/source-code-pages/keyword-macros.rs similarity index 100% rename from tests/rustdoc/source-code-pages/keyword-macros.rs rename to tests/rustdoc-html/source-code-pages/keyword-macros.rs diff --git a/tests/rustdoc-html/source-code-pages/macro-call-2.rs b/tests/rustdoc-html/source-code-pages/macro-call-2.rs new file mode 100644 index 000000000000..d9c3df57c602 --- /dev/null +++ b/tests/rustdoc-html/source-code-pages/macro-call-2.rs @@ -0,0 +1,18 @@ +// This is yet another test to ensure that only macro calls are considered as such +// by the rustdoc highlighter, in particular when named `macro_rules`. +// This is a regression test for . + +#![crate_name = "foo"] + +//@ has src/foo/macro-call-2.rs.html +//@ count - '//code/span[@class="macro"]' 2 +//@ has - '//code/span[@class="macro"]' 'macro_rules!' +//@ has - '//code/span[@class="macro"]' 'r#macro_rules!' + +macro_rules! r#macro_rules { + () => { + fn main() {} + } +} + +r#macro_rules!(); diff --git a/tests/rustdoc-html/source-code-pages/macro-call.rs b/tests/rustdoc-html/source-code-pages/macro-call.rs new file mode 100644 index 000000000000..df2d22aa9b60 --- /dev/null +++ b/tests/rustdoc-html/source-code-pages/macro-call.rs @@ -0,0 +1,29 @@ +// This is yet another test to ensure that only macro calls are considered as such +// by the rustdoc highlighter. +// This is a regression test for . + +#![crate_name = "foo"] + +//@ has src/foo/macro-call.rs.html +//@ count - '//code/span[@class="macro"]' 2 +//@ has - '//code/span[@class="macro"]' 'panic!' +//@ has - '//code/span[@class="macro"]' 'macro_rules!' + +pub struct Layout; + +impl Layout { + pub fn new() {} +} + +pub fn bar() { + let layout = Layout::new::(); + if layout != Layout::new::() { + panic!(); + } + let macro_rules = 3; + if macro_rules != 3 {} +} + +macro_rules! blob { + () => {} +} diff --git a/tests/rustdoc/source-code-pages/shebang.rs b/tests/rustdoc-html/source-code-pages/shebang.rs similarity index 100% rename from tests/rustdoc/source-code-pages/shebang.rs rename to tests/rustdoc-html/source-code-pages/shebang.rs diff --git a/tests/rustdoc/source-code-pages/source-code-highlight.rs b/tests/rustdoc-html/source-code-pages/source-code-highlight.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-code-highlight.rs rename to tests/rustdoc-html/source-code-pages/source-code-highlight.rs diff --git a/tests/rustdoc/source-code-pages/source-file.rs b/tests/rustdoc-html/source-code-pages/source-file.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-file.rs rename to tests/rustdoc-html/source-code-pages/source-file.rs diff --git a/tests/rustdoc/source-code-pages/source-line-numbers.rs b/tests/rustdoc-html/source-code-pages/source-line-numbers.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-line-numbers.rs rename to tests/rustdoc-html/source-code-pages/source-line-numbers.rs diff --git a/tests/rustdoc/source-code-pages/source-version-separator.rs b/tests/rustdoc-html/source-code-pages/source-version-separator.rs similarity index 100% rename from tests/rustdoc/source-code-pages/source-version-separator.rs rename to tests/rustdoc-html/source-code-pages/source-version-separator.rs diff --git a/tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs b/tests/rustdoc-html/source-code-pages/src-link-external-macro-26606.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-link-external-macro-26606.rs rename to tests/rustdoc-html/source-code-pages/src-link-external-macro-26606.rs diff --git a/tests/rustdoc/source-code-pages/src-links-auto-impls.rs b/tests/rustdoc-html/source-code-pages/src-links-auto-impls.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-auto-impls.rs rename to tests/rustdoc-html/source-code-pages/src-links-auto-impls.rs diff --git a/tests/rustdoc/source-code-pages/src-links-external.rs b/tests/rustdoc-html/source-code-pages/src-links-external.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-external.rs rename to tests/rustdoc-html/source-code-pages/src-links-external.rs diff --git a/tests/rustdoc/source-code-pages/src-links-implementor-43893.rs b/tests/rustdoc-html/source-code-pages/src-links-implementor-43893.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-implementor-43893.rs rename to tests/rustdoc-html/source-code-pages/src-links-implementor-43893.rs diff --git a/tests/rustdoc/source-code-pages/src-links-inlined-34274.rs b/tests/rustdoc-html/source-code-pages/src-links-inlined-34274.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links-inlined-34274.rs rename to tests/rustdoc-html/source-code-pages/src-links-inlined-34274.rs diff --git a/tests/rustdoc/source-code-pages/src-links.rs b/tests/rustdoc-html/source-code-pages/src-links.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links.rs rename to tests/rustdoc-html/source-code-pages/src-links.rs diff --git a/tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir b/tests/rustdoc-html/source-code-pages/src-links/compiletest-ignore-dir similarity index 100% rename from tests/rustdoc/source-code-pages/src-links/compiletest-ignore-dir rename to tests/rustdoc-html/source-code-pages/src-links/compiletest-ignore-dir diff --git a/tests/rustdoc/source-code-pages/src-links/fizz.rs b/tests/rustdoc-html/source-code-pages/src-links/fizz.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links/fizz.rs rename to tests/rustdoc-html/source-code-pages/src-links/fizz.rs diff --git a/tests/rustdoc/source-code-pages/src-links/mod.rs b/tests/rustdoc-html/source-code-pages/src-links/mod.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-links/mod.rs rename to tests/rustdoc-html/source-code-pages/src-links/mod.rs diff --git a/tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs b/tests/rustdoc-html/source-code-pages/src-mod-path-absolute-26995.rs similarity index 100% rename from tests/rustdoc/source-code-pages/src-mod-path-absolute-26995.rs rename to tests/rustdoc-html/source-code-pages/src-mod-path-absolute-26995.rs diff --git a/tests/rustdoc/source-code-pages/version-separator-without-source.rs b/tests/rustdoc-html/source-code-pages/version-separator-without-source.rs similarity index 100% rename from tests/rustdoc/source-code-pages/version-separator-without-source.rs rename to tests/rustdoc-html/source-code-pages/version-separator-without-source.rs diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc-html/stability.rs similarity index 100% rename from tests/rustdoc/stability.rs rename to tests/rustdoc-html/stability.rs diff --git a/tests/rustdoc/staged-api-deprecated-unstable-32374.rs b/tests/rustdoc-html/staged-api-deprecated-unstable-32374.rs similarity index 100% rename from tests/rustdoc/staged-api-deprecated-unstable-32374.rs rename to tests/rustdoc-html/staged-api-deprecated-unstable-32374.rs diff --git a/tests/rustdoc/staged-api-feature-issue-27759.rs b/tests/rustdoc-html/staged-api-feature-issue-27759.rs similarity index 100% rename from tests/rustdoc/staged-api-feature-issue-27759.rs rename to tests/rustdoc-html/staged-api-feature-issue-27759.rs diff --git a/tests/rustdoc/static-root-path.rs b/tests/rustdoc-html/static-root-path.rs similarity index 100% rename from tests/rustdoc/static-root-path.rs rename to tests/rustdoc-html/static-root-path.rs diff --git a/tests/rustdoc/static.rs b/tests/rustdoc-html/static.rs similarity index 100% rename from tests/rustdoc/static.rs rename to tests/rustdoc-html/static.rs diff --git a/tests/rustdoc/strip-block-doc-comments-stars.docblock.html b/tests/rustdoc-html/strip-block-doc-comments-stars.docblock.html similarity index 100% rename from tests/rustdoc/strip-block-doc-comments-stars.docblock.html rename to tests/rustdoc-html/strip-block-doc-comments-stars.docblock.html diff --git a/tests/rustdoc/strip-block-doc-comments-stars.rs b/tests/rustdoc-html/strip-block-doc-comments-stars.rs similarity index 100% rename from tests/rustdoc/strip-block-doc-comments-stars.rs rename to tests/rustdoc-html/strip-block-doc-comments-stars.rs diff --git a/tests/rustdoc/strip-priv-imports-pass-27104.rs b/tests/rustdoc-html/strip-priv-imports-pass-27104.rs similarity index 100% rename from tests/rustdoc/strip-priv-imports-pass-27104.rs rename to tests/rustdoc-html/strip-priv-imports-pass-27104.rs diff --git a/tests/rustdoc/struct-arg-pattern.rs b/tests/rustdoc-html/struct-arg-pattern.rs similarity index 100% rename from tests/rustdoc/struct-arg-pattern.rs rename to tests/rustdoc-html/struct-arg-pattern.rs diff --git a/tests/rustdoc/struct-field.rs b/tests/rustdoc-html/struct-field.rs similarity index 100% rename from tests/rustdoc/struct-field.rs rename to tests/rustdoc-html/struct-field.rs diff --git a/tests/rustdoc/structfields.rs b/tests/rustdoc-html/structfields.rs similarity index 100% rename from tests/rustdoc/structfields.rs rename to tests/rustdoc-html/structfields.rs diff --git a/tests/rustdoc/summary-codeblock-31899.rs b/tests/rustdoc-html/summary-codeblock-31899.rs similarity index 100% rename from tests/rustdoc/summary-codeblock-31899.rs rename to tests/rustdoc-html/summary-codeblock-31899.rs diff --git a/tests/rustdoc/summary-header-46377.rs b/tests/rustdoc-html/summary-header-46377.rs similarity index 100% rename from tests/rustdoc/summary-header-46377.rs rename to tests/rustdoc-html/summary-header-46377.rs diff --git a/tests/rustdoc/summary-reference-link-30366.rs b/tests/rustdoc-html/summary-reference-link-30366.rs similarity index 100% rename from tests/rustdoc/summary-reference-link-30366.rs rename to tests/rustdoc-html/summary-reference-link-30366.rs diff --git a/tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs b/tests/rustdoc-html/synthetic_auto/auto-trait-lifetimes-56822.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs rename to tests/rustdoc-html/synthetic_auto/auto-trait-lifetimes-56822.rs diff --git a/tests/rustdoc-html/synthetic_auto/basic.rs b/tests/rustdoc-html/synthetic_auto/basic.rs new file mode 100644 index 000000000000..e8c2f5da9fe6 --- /dev/null +++ b/tests/rustdoc-html/synthetic_auto/basic.rs @@ -0,0 +1,9 @@ +//@ has basic/struct.Foo.html +//@ has - '//h3[@class="code-header"]' 'impl Send for Foowhere T: Send' +//@ has - '//h3[@class="code-header"]' 'impl Sync for Foowhere T: Sync' +//@ count - '//*[@id="implementations-list"]//*[@class="impl"]' 0 +//@ count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 7 +// The number here will need updating when new auto traits are added: ^ +pub struct Foo { + field: T, +} diff --git a/tests/rustdoc/synthetic_auto/bounds.rs b/tests/rustdoc-html/synthetic_auto/bounds.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/bounds.rs rename to tests/rustdoc-html/synthetic_auto/bounds.rs diff --git a/tests/rustdoc/synthetic_auto/complex.rs b/tests/rustdoc-html/synthetic_auto/complex.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/complex.rs rename to tests/rustdoc-html/synthetic_auto/complex.rs diff --git a/tests/rustdoc/synthetic_auto/crate-local.rs b/tests/rustdoc-html/synthetic_auto/crate-local.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/crate-local.rs rename to tests/rustdoc-html/synthetic_auto/crate-local.rs diff --git a/tests/rustdoc/synthetic_auto/issue-72213-projection-lifetime.rs b/tests/rustdoc-html/synthetic_auto/issue-72213-projection-lifetime.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/issue-72213-projection-lifetime.rs rename to tests/rustdoc-html/synthetic_auto/issue-72213-projection-lifetime.rs diff --git a/tests/rustdoc/synthetic_auto/lifetimes.rs b/tests/rustdoc-html/synthetic_auto/lifetimes.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/lifetimes.rs rename to tests/rustdoc-html/synthetic_auto/lifetimes.rs diff --git a/tests/rustdoc/synthetic_auto/manual.rs b/tests/rustdoc-html/synthetic_auto/manual.rs similarity index 85% rename from tests/rustdoc/synthetic_auto/manual.rs rename to tests/rustdoc-html/synthetic_auto/manual.rs index bbf361a6e596..830bfccca09e 100644 --- a/tests/rustdoc/synthetic_auto/manual.rs +++ b/tests/rustdoc-html/synthetic_auto/manual.rs @@ -6,7 +6,8 @@ // 'impl Send for Foo' // //@ count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1 -//@ count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5 +//@ count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6 +// The number here will need updating when new auto traits are added: ^ pub struct Foo { field: T, } diff --git a/tests/rustdoc/synthetic_auto/negative.rs b/tests/rustdoc-html/synthetic_auto/negative.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/negative.rs rename to tests/rustdoc-html/synthetic_auto/negative.rs diff --git a/tests/rustdoc/synthetic_auto/nested.rs b/tests/rustdoc-html/synthetic_auto/nested.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/nested.rs rename to tests/rustdoc-html/synthetic_auto/nested.rs diff --git a/tests/rustdoc/synthetic_auto/no-redundancy.rs b/tests/rustdoc-html/synthetic_auto/no-redundancy.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/no-redundancy.rs rename to tests/rustdoc-html/synthetic_auto/no-redundancy.rs diff --git a/tests/rustdoc/synthetic_auto/normalize-auto-trait-80233.rs b/tests/rustdoc-html/synthetic_auto/normalize-auto-trait-80233.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/normalize-auto-trait-80233.rs rename to tests/rustdoc-html/synthetic_auto/normalize-auto-trait-80233.rs diff --git a/tests/rustdoc/synthetic_auto/overflow.rs b/tests/rustdoc-html/synthetic_auto/overflow.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/overflow.rs rename to tests/rustdoc-html/synthetic_auto/overflow.rs diff --git a/tests/rustdoc/synthetic_auto/project.rs b/tests/rustdoc-html/synthetic_auto/project.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/project.rs rename to tests/rustdoc-html/synthetic_auto/project.rs diff --git a/tests/rustdoc/synthetic_auto/self-referential.rs b/tests/rustdoc-html/synthetic_auto/self-referential.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/self-referential.rs rename to tests/rustdoc-html/synthetic_auto/self-referential.rs diff --git a/tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs b/tests/rustdoc-html/synthetic_auto/send-impl-conditional-60726.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs rename to tests/rustdoc-html/synthetic_auto/send-impl-conditional-60726.rs diff --git a/tests/rustdoc/synthetic_auto/static-region.rs b/tests/rustdoc-html/synthetic_auto/static-region.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/static-region.rs rename to tests/rustdoc-html/synthetic_auto/static-region.rs diff --git a/tests/rustdoc/synthetic_auto/supertrait-bounds.rs b/tests/rustdoc-html/synthetic_auto/supertrait-bounds.rs similarity index 100% rename from tests/rustdoc/synthetic_auto/supertrait-bounds.rs rename to tests/rustdoc-html/synthetic_auto/supertrait-bounds.rs diff --git a/tests/rustdoc/tab_title.rs b/tests/rustdoc-html/tab_title.rs similarity index 100% rename from tests/rustdoc/tab_title.rs rename to tests/rustdoc-html/tab_title.rs diff --git a/tests/rustdoc/table-in-docblock.rs b/tests/rustdoc-html/table-in-docblock.rs similarity index 100% rename from tests/rustdoc/table-in-docblock.rs rename to tests/rustdoc-html/table-in-docblock.rs diff --git a/tests/rustdoc/target-feature.rs b/tests/rustdoc-html/target-feature.rs similarity index 100% rename from tests/rustdoc/target-feature.rs rename to tests/rustdoc-html/target-feature.rs diff --git a/tests/rustdoc/task-lists.rs b/tests/rustdoc-html/task-lists.rs similarity index 100% rename from tests/rustdoc/task-lists.rs rename to tests/rustdoc-html/task-lists.rs diff --git a/tests/rustdoc/test-lists.rs b/tests/rustdoc-html/test-lists.rs similarity index 100% rename from tests/rustdoc/test-lists.rs rename to tests/rustdoc-html/test-lists.rs diff --git a/tests/rustdoc/test-parens.rs b/tests/rustdoc-html/test-parens.rs similarity index 100% rename from tests/rustdoc/test-parens.rs rename to tests/rustdoc-html/test-parens.rs diff --git a/tests/rustdoc/test-strikethrough.rs b/tests/rustdoc-html/test-strikethrough.rs similarity index 100% rename from tests/rustdoc/test-strikethrough.rs rename to tests/rustdoc-html/test-strikethrough.rs diff --git a/tests/rustdoc/test_option_check/bar.rs b/tests/rustdoc-html/test_option_check/bar.rs similarity index 100% rename from tests/rustdoc/test_option_check/bar.rs rename to tests/rustdoc-html/test_option_check/bar.rs diff --git a/tests/rustdoc/test_option_check/test.rs b/tests/rustdoc-html/test_option_check/test.rs similarity index 100% rename from tests/rustdoc/test_option_check/test.rs rename to tests/rustdoc-html/test_option_check/test.rs diff --git a/tests/rustdoc/thread-local-src.rs b/tests/rustdoc-html/thread-local-src.rs similarity index 100% rename from tests/rustdoc/thread-local-src.rs rename to tests/rustdoc-html/thread-local-src.rs diff --git a/tests/rustdoc/titles.rs b/tests/rustdoc-html/titles.rs similarity index 100% rename from tests/rustdoc/titles.rs rename to tests/rustdoc-html/titles.rs diff --git a/tests/rustdoc/toggle-item-contents.rs b/tests/rustdoc-html/toggle-item-contents.rs similarity index 100% rename from tests/rustdoc/toggle-item-contents.rs rename to tests/rustdoc-html/toggle-item-contents.rs diff --git a/tests/rustdoc/toggle-method.rs b/tests/rustdoc-html/toggle-method.rs similarity index 100% rename from tests/rustdoc/toggle-method.rs rename to tests/rustdoc-html/toggle-method.rs diff --git a/tests/rustdoc/toggle-trait-fn.rs b/tests/rustdoc-html/toggle-trait-fn.rs similarity index 100% rename from tests/rustdoc/toggle-trait-fn.rs rename to tests/rustdoc-html/toggle-trait-fn.rs diff --git a/tests/rustdoc/trait-aliases.rs b/tests/rustdoc-html/trait-aliases.rs similarity index 100% rename from tests/rustdoc/trait-aliases.rs rename to tests/rustdoc-html/trait-aliases.rs diff --git a/tests/rustdoc/trait-item-info.rs b/tests/rustdoc-html/trait-item-info.rs similarity index 100% rename from tests/rustdoc/trait-item-info.rs rename to tests/rustdoc-html/trait-item-info.rs diff --git a/tests/rustdoc/trait-self-link.rs b/tests/rustdoc-html/trait-self-link.rs similarity index 100% rename from tests/rustdoc/trait-self-link.rs rename to tests/rustdoc-html/trait-self-link.rs diff --git a/tests/rustdoc/trait-src-link.rs b/tests/rustdoc-html/trait-src-link.rs similarity index 100% rename from tests/rustdoc/trait-src-link.rs rename to tests/rustdoc-html/trait-src-link.rs diff --git a/tests/rustdoc/trait-visibility.rs b/tests/rustdoc-html/trait-visibility.rs similarity index 100% rename from tests/rustdoc/trait-visibility.rs rename to tests/rustdoc-html/trait-visibility.rs diff --git a/tests/rustdoc/traits-in-bodies.rs b/tests/rustdoc-html/traits-in-bodies.rs similarity index 100% rename from tests/rustdoc/traits-in-bodies.rs rename to tests/rustdoc-html/traits-in-bodies.rs diff --git a/tests/rustdoc/tuple-struct-fields-doc.rs b/tests/rustdoc-html/tuple-struct-fields-doc.rs similarity index 100% rename from tests/rustdoc/tuple-struct-fields-doc.rs rename to tests/rustdoc-html/tuple-struct-fields-doc.rs diff --git a/tests/rustdoc/tuple-struct-where-clause-34928.rs b/tests/rustdoc-html/tuple-struct-where-clause-34928.rs similarity index 100% rename from tests/rustdoc/tuple-struct-where-clause-34928.rs rename to tests/rustdoc-html/tuple-struct-where-clause-34928.rs diff --git a/tests/rustdoc/tuples.link1_i32.html b/tests/rustdoc-html/tuples.link1_i32.html similarity index 100% rename from tests/rustdoc/tuples.link1_i32.html rename to tests/rustdoc-html/tuples.link1_i32.html diff --git a/tests/rustdoc/tuples.link1_t.html b/tests/rustdoc-html/tuples.link1_t.html similarity index 100% rename from tests/rustdoc/tuples.link1_t.html rename to tests/rustdoc-html/tuples.link1_t.html diff --git a/tests/rustdoc/tuples.link2_i32.html b/tests/rustdoc-html/tuples.link2_i32.html similarity index 100% rename from tests/rustdoc/tuples.link2_i32.html rename to tests/rustdoc-html/tuples.link2_i32.html diff --git a/tests/rustdoc/tuples.link2_t.html b/tests/rustdoc-html/tuples.link2_t.html similarity index 100% rename from tests/rustdoc/tuples.link2_t.html rename to tests/rustdoc-html/tuples.link2_t.html diff --git a/tests/rustdoc/tuples.link2_tu.html b/tests/rustdoc-html/tuples.link2_tu.html similarity index 100% rename from tests/rustdoc/tuples.link2_tu.html rename to tests/rustdoc-html/tuples.link2_tu.html diff --git a/tests/rustdoc/tuples.link_unit.html b/tests/rustdoc-html/tuples.link_unit.html similarity index 100% rename from tests/rustdoc/tuples.link_unit.html rename to tests/rustdoc-html/tuples.link_unit.html diff --git a/tests/rustdoc/tuples.rs b/tests/rustdoc-html/tuples.rs similarity index 100% rename from tests/rustdoc/tuples.rs rename to tests/rustdoc-html/tuples.rs diff --git a/tests/rustdoc/type-alias/auxiliary/parent-crate-115718.rs b/tests/rustdoc-html/type-alias/auxiliary/parent-crate-115718.rs similarity index 100% rename from tests/rustdoc/type-alias/auxiliary/parent-crate-115718.rs rename to tests/rustdoc-html/type-alias/auxiliary/parent-crate-115718.rs diff --git a/tests/rustdoc/type-alias/cross-crate-115718.rs b/tests/rustdoc-html/type-alias/cross-crate-115718.rs similarity index 100% rename from tests/rustdoc/type-alias/cross-crate-115718.rs rename to tests/rustdoc-html/type-alias/cross-crate-115718.rs diff --git a/tests/rustdoc/type-alias/deeply-nested-112515.rs b/tests/rustdoc-html/type-alias/deeply-nested-112515.rs similarity index 100% rename from tests/rustdoc/type-alias/deeply-nested-112515.rs rename to tests/rustdoc-html/type-alias/deeply-nested-112515.rs diff --git a/tests/rustdoc/type-alias/deref-32077.rs b/tests/rustdoc-html/type-alias/deref-32077.rs similarity index 100% rename from tests/rustdoc/type-alias/deref-32077.rs rename to tests/rustdoc-html/type-alias/deref-32077.rs diff --git a/tests/rustdoc/type-alias/impl_trait_in_assoc_type.rs b/tests/rustdoc-html/type-alias/impl_trait_in_assoc_type.rs similarity index 100% rename from tests/rustdoc/type-alias/impl_trait_in_assoc_type.rs rename to tests/rustdoc-html/type-alias/impl_trait_in_assoc_type.rs diff --git a/tests/rustdoc/type-alias/primitive-local-link-121106.rs b/tests/rustdoc-html/type-alias/primitive-local-link-121106.rs similarity index 100% rename from tests/rustdoc/type-alias/primitive-local-link-121106.rs rename to tests/rustdoc-html/type-alias/primitive-local-link-121106.rs diff --git a/tests/rustdoc/type-alias/repr.rs b/tests/rustdoc-html/type-alias/repr.rs similarity index 100% rename from tests/rustdoc/type-alias/repr.rs rename to tests/rustdoc-html/type-alias/repr.rs diff --git a/tests/rustdoc/type-alias/same-crate-115718.rs b/tests/rustdoc-html/type-alias/same-crate-115718.rs similarity index 100% rename from tests/rustdoc/type-alias/same-crate-115718.rs rename to tests/rustdoc-html/type-alias/same-crate-115718.rs diff --git a/tests/rustdoc/type-layout-flag-required.rs b/tests/rustdoc-html/type-layout-flag-required.rs similarity index 100% rename from tests/rustdoc/type-layout-flag-required.rs rename to tests/rustdoc-html/type-layout-flag-required.rs diff --git a/tests/rustdoc/type-layout.rs b/tests/rustdoc-html/type-layout.rs similarity index 89% rename from tests/rustdoc/type-layout.rs rename to tests/rustdoc-html/type-layout.rs index 482b8b597dd3..84d2aa806007 100644 --- a/tests/rustdoc/type-layout.rs +++ b/tests/rustdoc-html/type-layout.rs @@ -64,6 +64,12 @@ pub type GenericTypeAlias = (Generic<(u32, ())>, Generic); //@ hasraw type_layout/type.Edges.html 'Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.' pub type Edges<'a, E> = std::borrow::Cow<'a, [E]>; +pub trait Project { type Assoc; } +// We can't compute layout as the alias stays rigid. A `LayoutError::TooGeneric` is returned. +//@ hasraw type_layout/struct.RigidAlias.html 'Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.' +//@ !hasraw - 'Size: ' +pub struct RigidAlias(<() as Project>::Assoc) where for<'a> (): Project; + //@ !hasraw type_layout/trait.MyTrait.html 'Size: ' pub trait MyTrait {} @@ -92,9 +98,3 @@ pub enum Uninhabited {} //@ hasraw type_layout/struct.Uninhabited2.html 'Size: ' //@ hasraw - '8 bytes (uninhabited)' pub struct Uninhabited2(std::convert::Infallible, u64); - -pub trait Project { type Assoc; } -// We can't compute layout. A `LayoutError::Unknown` is returned. -//@ hasraw type_layout/struct.Unknown.html 'Unable to compute type layout.' -//@ !hasraw - 'Size: ' -pub struct Unknown(<() as Project>::Assoc) where for<'a> (): Project; diff --git a/tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs b/tests/rustdoc-html/typedef-inner-variants-lazy_type_alias.rs similarity index 100% rename from tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs rename to tests/rustdoc-html/typedef-inner-variants-lazy_type_alias.rs diff --git a/tests/rustdoc/typedef-inner-variants.rs b/tests/rustdoc-html/typedef-inner-variants.rs similarity index 100% rename from tests/rustdoc/typedef-inner-variants.rs rename to tests/rustdoc-html/typedef-inner-variants.rs diff --git a/tests/rustdoc/typedef.rs b/tests/rustdoc-html/typedef.rs similarity index 100% rename from tests/rustdoc/typedef.rs rename to tests/rustdoc-html/typedef.rs diff --git a/tests/rustdoc/underscore-import-61592.rs b/tests/rustdoc-html/underscore-import-61592.rs similarity index 100% rename from tests/rustdoc/underscore-import-61592.rs rename to tests/rustdoc-html/underscore-import-61592.rs diff --git a/tests/rustdoc/unindent.md b/tests/rustdoc-html/unindent.md similarity index 100% rename from tests/rustdoc/unindent.md rename to tests/rustdoc-html/unindent.md diff --git a/tests/rustdoc/unindent.rs b/tests/rustdoc-html/unindent.rs similarity index 100% rename from tests/rustdoc/unindent.rs rename to tests/rustdoc-html/unindent.rs diff --git a/tests/rustdoc/union-fields-html.rs b/tests/rustdoc-html/union-fields-html.rs similarity index 100% rename from tests/rustdoc/union-fields-html.rs rename to tests/rustdoc-html/union-fields-html.rs diff --git a/tests/rustdoc/union.rs b/tests/rustdoc-html/union.rs similarity index 100% rename from tests/rustdoc/union.rs rename to tests/rustdoc-html/union.rs diff --git a/tests/rustdoc/unit-return.rs b/tests/rustdoc-html/unit-return.rs similarity index 100% rename from tests/rustdoc/unit-return.rs rename to tests/rustdoc-html/unit-return.rs diff --git a/tests/rustdoc/unsafe-binder.rs b/tests/rustdoc-html/unsafe-binder.rs similarity index 100% rename from tests/rustdoc/unsafe-binder.rs rename to tests/rustdoc-html/unsafe-binder.rs diff --git a/tests/rustdoc/use-attr.rs b/tests/rustdoc-html/use-attr.rs similarity index 100% rename from tests/rustdoc/use-attr.rs rename to tests/rustdoc-html/use-attr.rs diff --git a/tests/rustdoc/useless_lifetime_bound.rs b/tests/rustdoc-html/useless_lifetime_bound.rs similarity index 100% rename from tests/rustdoc/useless_lifetime_bound.rs rename to tests/rustdoc-html/useless_lifetime_bound.rs diff --git a/tests/rustdoc/variadic.rs b/tests/rustdoc-html/variadic.rs similarity index 100% rename from tests/rustdoc/variadic.rs rename to tests/rustdoc-html/variadic.rs diff --git a/tests/rustdoc/viewpath-rename.rs b/tests/rustdoc-html/viewpath-rename.rs similarity index 100% rename from tests/rustdoc/viewpath-rename.rs rename to tests/rustdoc-html/viewpath-rename.rs diff --git a/tests/rustdoc/viewpath-self.rs b/tests/rustdoc-html/viewpath-self.rs similarity index 100% rename from tests/rustdoc/viewpath-self.rs rename to tests/rustdoc-html/viewpath-self.rs diff --git a/tests/rustdoc/visibility.rs b/tests/rustdoc-html/visibility.rs similarity index 100% rename from tests/rustdoc/visibility.rs rename to tests/rustdoc-html/visibility.rs diff --git a/tests/rustdoc/where-clause-order.rs b/tests/rustdoc-html/where-clause-order.rs similarity index 100% rename from tests/rustdoc/where-clause-order.rs rename to tests/rustdoc-html/where-clause-order.rs diff --git a/tests/rustdoc/where-sized.rs b/tests/rustdoc-html/where-sized.rs similarity index 100% rename from tests/rustdoc/where-sized.rs rename to tests/rustdoc-html/where-sized.rs diff --git a/tests/rustdoc/where.SWhere_Echo_impl.html b/tests/rustdoc-html/where.SWhere_Echo_impl.html similarity index 100% rename from tests/rustdoc/where.SWhere_Echo_impl.html rename to tests/rustdoc-html/where.SWhere_Echo_impl.html diff --git a/tests/rustdoc/where.SWhere_Simd_item-decl.html b/tests/rustdoc-html/where.SWhere_Simd_item-decl.html similarity index 100% rename from tests/rustdoc/where.SWhere_Simd_item-decl.html rename to tests/rustdoc-html/where.SWhere_Simd_item-decl.html diff --git a/tests/rustdoc/where.SWhere_TraitWhere_item-decl.html b/tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html similarity index 100% rename from tests/rustdoc/where.SWhere_TraitWhere_item-decl.html rename to tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html diff --git a/tests/rustdoc/where.alpha_trait_decl.html b/tests/rustdoc-html/where.alpha_trait_decl.html similarity index 100% rename from tests/rustdoc/where.alpha_trait_decl.html rename to tests/rustdoc-html/where.alpha_trait_decl.html diff --git a/tests/rustdoc/where.bravo_trait_decl.html b/tests/rustdoc-html/where.bravo_trait_decl.html similarity index 100% rename from tests/rustdoc/where.bravo_trait_decl.html rename to tests/rustdoc-html/where.bravo_trait_decl.html diff --git a/tests/rustdoc/where.charlie_fn_decl.html b/tests/rustdoc-html/where.charlie_fn_decl.html similarity index 100% rename from tests/rustdoc/where.charlie_fn_decl.html rename to tests/rustdoc-html/where.charlie_fn_decl.html diff --git a/tests/rustdoc/where.golf_type_alias_decl.html b/tests/rustdoc-html/where.golf_type_alias_decl.html similarity index 100% rename from tests/rustdoc/where.golf_type_alias_decl.html rename to tests/rustdoc-html/where.golf_type_alias_decl.html diff --git a/tests/rustdoc/where.rs b/tests/rustdoc-html/where.rs similarity index 100% rename from tests/rustdoc/where.rs rename to tests/rustdoc-html/where.rs diff --git a/tests/rustdoc/whitespace-after-where-clause.enum.html b/tests/rustdoc-html/whitespace-after-where-clause.enum.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.enum.html rename to tests/rustdoc-html/whitespace-after-where-clause.enum.html diff --git a/tests/rustdoc/whitespace-after-where-clause.enum2.html b/tests/rustdoc-html/whitespace-after-where-clause.enum2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.enum2.html rename to tests/rustdoc-html/whitespace-after-where-clause.enum2.html diff --git a/tests/rustdoc/whitespace-after-where-clause.rs b/tests/rustdoc-html/whitespace-after-where-clause.rs similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.rs rename to tests/rustdoc-html/whitespace-after-where-clause.rs diff --git a/tests/rustdoc/whitespace-after-where-clause.struct.html b/tests/rustdoc-html/whitespace-after-where-clause.struct.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.struct.html rename to tests/rustdoc-html/whitespace-after-where-clause.struct.html diff --git a/tests/rustdoc/whitespace-after-where-clause.struct2.html b/tests/rustdoc-html/whitespace-after-where-clause.struct2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.struct2.html rename to tests/rustdoc-html/whitespace-after-where-clause.struct2.html diff --git a/tests/rustdoc/whitespace-after-where-clause.trait.html b/tests/rustdoc-html/whitespace-after-where-clause.trait.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.trait.html rename to tests/rustdoc-html/whitespace-after-where-clause.trait.html diff --git a/tests/rustdoc/whitespace-after-where-clause.trait2.html b/tests/rustdoc-html/whitespace-after-where-clause.trait2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.trait2.html rename to tests/rustdoc-html/whitespace-after-where-clause.trait2.html diff --git a/tests/rustdoc/whitespace-after-where-clause.union.html b/tests/rustdoc-html/whitespace-after-where-clause.union.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.union.html rename to tests/rustdoc-html/whitespace-after-where-clause.union.html diff --git a/tests/rustdoc/whitespace-after-where-clause.union2.html b/tests/rustdoc-html/whitespace-after-where-clause.union2.html similarity index 100% rename from tests/rustdoc/whitespace-after-where-clause.union2.html rename to tests/rustdoc-html/whitespace-after-where-clause.union2.html diff --git a/tests/rustdoc/without-redirect.rs b/tests/rustdoc-html/without-redirect.rs similarity index 100% rename from tests/rustdoc/without-redirect.rs rename to tests/rustdoc-html/without-redirect.rs diff --git a/tests/rustdoc/wrapping.rs b/tests/rustdoc-html/wrapping.rs similarity index 100% rename from tests/rustdoc/wrapping.rs rename to tests/rustdoc-html/wrapping.rs diff --git a/tests/rustdoc-js-std/core-transmute.js b/tests/rustdoc-js-std/core-transmute.js index 8c9910a32d7f..b15f398902c3 100644 --- a/tests/rustdoc-js-std/core-transmute.js +++ b/tests/rustdoc-js-std/core-transmute.js @@ -3,9 +3,9 @@ const EXPECTED = [ { 'query': 'generic:T -> generic:U', 'others': [ + { 'path': 'core::mem', 'name': 'transmute' }, { 'path': 'core::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'core::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'core::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/rustdoc-js-std/println-typo.js b/tests/rustdoc-js-std/println-typo.js index a4dd90a44d5b..b91e7883b995 100644 --- a/tests/rustdoc-js-std/println-typo.js +++ b/tests/rustdoc-js-std/println-typo.js @@ -6,7 +6,10 @@ const EXPECTED = { 'query': 'prinltn', 'others': [ { 'path': 'std', 'name': 'println' }, + { 'path': 'std::prelude::v1', 'name': 'println' }, { 'path': 'std', 'name': 'print' }, + { 'path': 'std::prelude::v1', 'name': 'print' }, { 'path': 'std', 'name': 'eprintln' }, + { 'path': 'std::prelude::v1', 'name': 'eprintln' }, ], }; diff --git a/tests/rustdoc-js-std/transmute-fail.js b/tests/rustdoc-js-std/transmute-fail.js index ddfb27619481..459e8dc3f002 100644 --- a/tests/rustdoc-js-std/transmute-fail.js +++ b/tests/rustdoc-js-std/transmute-fail.js @@ -6,9 +6,9 @@ const EXPECTED = [ // should-fail tag and the search query below: 'query': 'generic:T -> generic:T', 'others': [ + { 'path': 'std::mem', 'name': 'transmute' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'std::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/rustdoc-js-std/transmute.js b/tests/rustdoc-js-std/transmute.js index f52e0ab14362..a85b02e29947 100644 --- a/tests/rustdoc-js-std/transmute.js +++ b/tests/rustdoc-js-std/transmute.js @@ -5,9 +5,9 @@ const EXPECTED = [ // should-fail tag and the search query below: 'query': 'generic:T -> generic:U', 'others': [ + { 'path': 'std::mem', 'name': 'transmute' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_as' }, { 'path': 'std::intrinsics::simd', 'name': 'simd_cast' }, - { 'path': 'std::mem', 'name': 'transmute' }, ], }, ]; diff --git a/tests/rustdoc-js-std/unbox-type-result.js b/tests/rustdoc-js-std/unbox-type-result.js index 1f5cba58adf6..e4765d87637c 100644 --- a/tests/rustdoc-js-std/unbox-type-result.js +++ b/tests/rustdoc-js-std/unbox-type-result.js @@ -8,7 +8,6 @@ const EXPECTED = [ query: "File -> Metadata", others: [ { path: "std::fs::File", name: "metadata" }, - { path: "std::fs::File", name: "metadata_at" }, ] }, { diff --git a/tests/rustdoc-js/sort-stability.js b/tests/rustdoc-js/sort-stability.js new file mode 100644 index 000000000000..8c095619a086 --- /dev/null +++ b/tests/rustdoc-js/sort-stability.js @@ -0,0 +1,9 @@ +const EXPECTED = [ + { + 'query': 'foo', + 'others': [ + {"path": "sort_stability::old", "name": "foo"}, + {"path": "sort_stability::new", "name": "foo"}, + ], + }, +]; diff --git a/tests/rustdoc-js/sort-stability.rs b/tests/rustdoc-js/sort-stability.rs new file mode 100644 index 000000000000..68662bb3aab6 --- /dev/null +++ b/tests/rustdoc-js/sort-stability.rs @@ -0,0 +1,16 @@ +#![feature(staged_api)] +#![stable(feature = "foo_lib", since = "1.0.0")] + +#[stable(feature = "old_foo", since = "1.0.1")] +pub mod old { + /// Old, stable foo + #[stable(feature = "old_foo", since = "1.0.1")] + pub fn foo() {} +} + +#[unstable(feature = "new_foo", issue = "none")] +pub mod new { + /// New, unstable foo + #[unstable(feature = "new_foo", issue = "none")] + pub fn foo() {} +} diff --git a/tests/rustdoc-json/reexport/glob_collision.rs b/tests/rustdoc-json/reexport/glob_collision.rs index 48de1b5e7721..dd6eab6517b0 100644 --- a/tests/rustdoc-json/reexport/glob_collision.rs +++ b/tests/rustdoc-json/reexport/glob_collision.rs @@ -1,7 +1,9 @@ // Regression test for https://github.com/rust-lang/rust/issues/100973 +// Update: the rules has changed after #147984, one of the colliding items is now available +// from other crates under a deprecation lint. //@ set m1 = "$.index[?(@.name == 'm1' && @.inner.module)].id" -//@ is "$.index[?(@.name == 'm1')].inner.module.items" [] +//@ is "$.index[?(@.name == 'm1')].inner.module.items" [0] //@ is "$.index[?(@.name == 'm1')].inner.module.is_stripped" true mod m1 { pub fn f() {} diff --git a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs index c4bbcfc2b077..4168a5653dd5 100644 --- a/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs +++ b/tests/rustdoc-ui/associated-constant-not-allowed-102467.rs @@ -2,7 +2,7 @@ // It ensures that the expected error is displayed. #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait T { type A: S = 34>; @@ -11,8 +11,7 @@ trait T { } trait S { - #[type_const] - const C: i32; + type const C: i32; } fn main() {} diff --git a/tests/rustdoc-ui/bad-render-options.rs b/tests/rustdoc-ui/bad-render-options.rs index f2cfd4b76fa8..c85a818511d7 100644 --- a/tests/rustdoc-ui/bad-render-options.rs +++ b/tests/rustdoc-ui/bad-render-options.rs @@ -1,11 +1,30 @@ // regression test for https://github.com/rust-lang/rust/issues/149187 +#![deny(invalid_doc_attributes)] -#![doc(html_favicon_url)] //~ ERROR: `doc(html_favicon_url)` expects a string value [invalid_doc_attributes] -#![doc(html_logo_url)] //~ ERROR: `doc(html_logo_url)` expects a string value [invalid_doc_attributes] -#![doc(html_playground_url)] //~ ERROR: `doc(html_playground_url)` expects a string value [invalid_doc_attributes] -#![doc(issue_tracker_base_url)] //~ ERROR expects a string value -#![doc(html_favicon_url = 1)] //~ ERROR expects a string value -#![doc(html_logo_url = 2)] //~ ERROR expects a string value -#![doc(html_playground_url = 3)] //~ ERROR expects a string value -#![doc(issue_tracker_base_url = 4)] //~ ERROR expects a string value -#![doc(html_no_source = "asdf")] //~ ERROR `doc(html_no_source)` does not accept a value [invalid_doc_attributes] +#![doc(html_favicon_url)] +//~^ ERROR +//~| WARN +#![doc(html_logo_url)] +//~^ ERROR +//~| WARN +#![doc(html_playground_url)] +//~^ ERROR +//~| WARN +#![doc(issue_tracker_base_url)] +//~^ ERROR +//~| WARN +#![doc(html_favicon_url = 1)] +//~^ ERROR +//~| WARN +#![doc(html_logo_url = 2)] +//~^ ERROR +//~| WARN +#![doc(html_playground_url = 3)] +//~^ ERROR +//~| WARN +#![doc(issue_tracker_base_url = 4)] +//~^ ERROR +//~| WARN +#![doc(html_no_source = "asdf")] +//~^ ERROR +//~| WARN diff --git a/tests/rustdoc-ui/bad-render-options.stderr b/tests/rustdoc-ui/bad-render-options.stderr index 9d503363c0bd..dac6bc231c37 100644 --- a/tests/rustdoc-ui/bad-render-options.stderr +++ b/tests/rustdoc-ui/bad-render-options.stderr @@ -1,58 +1,79 @@ -error: `doc(html_favicon_url)` expects a string value - --> $DIR/bad-render-options.rs:3:8 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:4:8 | LL | #![doc(html_favicon_url)] | ^^^^^^^^^^^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/bad-render-options.rs:2:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ -error: `doc(html_logo_url)` expects a string value - --> $DIR/bad-render-options.rs:4:8 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:7:8 | LL | #![doc(html_logo_url)] | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: `doc(html_playground_url)` expects a string value - --> $DIR/bad-render-options.rs:5:8 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:10:8 | LL | #![doc(html_playground_url)] | ^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: `doc(issue_tracker_base_url)` expects a string value - --> $DIR/bad-render-options.rs:6:8 +error: expected this to be of the form `... = "..."` + --> $DIR/bad-render-options.rs:13:8 | LL | #![doc(issue_tracker_base_url)] | ^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: `doc(html_favicon_url)` expects a string value - --> $DIR/bad-render-options.rs:7:8 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:16:27 | LL | #![doc(html_favicon_url = 1)] - | ^^^^^^^^^^^^^^^^^^^^ + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: `doc(html_logo_url)` expects a string value - --> $DIR/bad-render-options.rs:8:8 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:19:24 | LL | #![doc(html_logo_url = 2)] - | ^^^^^^^^^^^^^^^^^ + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: `doc(html_playground_url)` expects a string value - --> $DIR/bad-render-options.rs:9:8 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:22:30 | LL | #![doc(html_playground_url = 3)] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: `doc(issue_tracker_base_url)` expects a string value - --> $DIR/bad-render-options.rs:10:8 +error: malformed `doc` attribute input + --> $DIR/bad-render-options.rs:25:33 | LL | #![doc(issue_tracker_base_url = 4)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: `doc(html_no_source)` does not accept a value - --> $DIR/bad-render-options.rs:11:8 +error: didn't expect any arguments here + --> $DIR/bad-render-options.rs:28:23 | LL | #![doc(html_no_source = "asdf")] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: aborting due to 9 previous errors diff --git a/tests/rustdoc-ui/check-doc-alias-attr-location.stderr b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr index 85c9516236c9..b8e1863ce560 100644 --- a/tests/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/tests/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -1,26 +1,26 @@ error: `#[doc(alias = "...")]` isn't allowed on foreign module - --> $DIR/check-doc-alias-attr-location.rs:7:7 + --> $DIR/check-doc-alias-attr-location.rs:7:15 | LL | #[doc(alias = "foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:10:7 + --> $DIR/check-doc-alias-attr-location.rs:10:15 | LL | #[doc(alias = "bar")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:16:7 + --> $DIR/check-doc-alias-attr-location.rs:16:15 | LL | #[doc(alias = "foobar")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block - --> $DIR/check-doc-alias-attr-location.rs:18:11 + --> $DIR/check-doc-alias-attr-location.rs:18:19 | LL | #[doc(alias = "assoc")] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/rustdoc-ui/check-doc-alias-attr.stderr b/tests/rustdoc-ui/check-doc-alias-attr.stderr index 250568be3333..d9e785ee0f1f 100644 --- a/tests/rustdoc-ui/check-doc-alias-attr.stderr +++ b/tests/rustdoc-ui/check-doc-alias-attr.stderr @@ -4,11 +4,13 @@ error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of s LL | #[doc(alias)] | ^^^^^ -error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` - --> $DIR/check-doc-alias-attr.rs:8:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:8:1 | LL | #[doc(alias = 0)] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 @@ -54,25 +56,27 @@ error: `#[doc(alias = "...")]` attribute cannot have empty value LL | #[doc(alias = "")] | ^^ -error: `#[doc(alias("a"))]` expects string literals - --> $DIR/check-doc-alias-attr.rs:19:13 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:19:1 | LL | #[doc(alias(0))] - | ^ + | ^^^^^^^^^^^^-^^^ + | | + | expected a string literal here -error: '"' character isn't allowed in `#[doc(alias("..."))]` +error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:20:13 | LL | #[doc(alias("\""))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:21:13 | LL | #[doc(alias("\n"))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:22:13 | LL | #[doc(alias(" @@ -80,25 +84,25 @@ LL | #[doc(alias(" LL | | "))] | |_^ -error: '\t' character isn't allowed in `#[doc(alias("..."))]` +error: '\t' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:24:13 | LL | #[doc(alias("\t"))] | ^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:25:13 | LL | #[doc(alias(" hello"))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:26:13 | LL | #[doc(alias("hello "))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` attribute cannot have empty value +error: `#[doc(alias = "...")]` attribute cannot have empty value --> $DIR/check-doc-alias-attr.rs:27:13 | LL | #[doc(alias(""))] @@ -106,3 +110,4 @@ LL | #[doc(alias(""))] error: aborting due to 17 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/rustdoc-ui/deprecated-attrs.rs b/tests/rustdoc-ui/deprecated-attrs.rs index 26aaf0d46808..dcca3114fb7d 100644 --- a/tests/rustdoc-ui/deprecated-attrs.rs +++ b/tests/rustdoc-ui/deprecated-attrs.rs @@ -1,11 +1,13 @@ //@ compile-flags: --passes unknown-pass +#![deny(invalid_doc_attributes)] +//~^ NOTE + #![doc(no_default_passes)] //~^ ERROR unknown `doc` attribute `no_default_passes` //~| NOTE no longer functions //~| NOTE see issue #44136 //~| NOTE `doc(no_default_passes)` is now a no-op -//~| NOTE `#[deny(invalid_doc_attributes)]` on by default #![doc(passes = "collapse-docs unindent-comments")] //~^ ERROR unknown `doc` attribute `passes` //~| NOTE no longer functions diff --git a/tests/rustdoc-ui/deprecated-attrs.stderr b/tests/rustdoc-ui/deprecated-attrs.stderr index 323257f944ce..e32a1eb3370d 100644 --- a/tests/rustdoc-ui/deprecated-attrs.stderr +++ b/tests/rustdoc-ui/deprecated-attrs.stderr @@ -4,29 +4,33 @@ warning: the `passes` flag no longer functions = help: you may want to use --document-private-items error: unknown `doc` attribute `no_default_passes` - --> $DIR/deprecated-attrs.rs:3:8 + --> $DIR/deprecated-attrs.rs:6:8 | LL | #![doc(no_default_passes)] | ^^^^^^^^^^^^^^^^^ no longer functions | = note: `doc` attribute `no_default_passes` no longer functions; see issue #44136 = note: `doc(no_default_passes)` is now a no-op - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/deprecated-attrs.rs:3:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: unknown `doc` attribute `passes` - --> $DIR/deprecated-attrs.rs:9:8 + --> $DIR/deprecated-attrs.rs:11:8 | LL | #![doc(passes = "collapse-docs unindent-comments")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no longer functions + | ^^^^^^ no longer functions | = note: `doc` attribute `passes` no longer functions; see issue #44136 = note: `doc(passes)` is now a no-op error: unknown `doc` attribute `plugins` - --> $DIR/deprecated-attrs.rs:14:8 + --> $DIR/deprecated-attrs.rs:16:8 | LL | #![doc(plugins = "xxx")] - | ^^^^^^^^^^^^^^^ no longer functions + | ^^^^^^^ no longer functions | = note: `doc` attribute `plugins` no longer functions; see issue #44136 and CVE-2018-1000622 = note: `doc(plugins)` is now a no-op diff --git a/tests/rustdoc-ui/doc-alias-assoc-const.stderr b/tests/rustdoc-ui/doc-alias-assoc-const.stderr index cc628c39400b..7566ec840da7 100644 --- a/tests/rustdoc-ui/doc-alias-assoc-const.stderr +++ b/tests/rustdoc-ui/doc-alias-assoc-const.stderr @@ -1,8 +1,8 @@ error: `#[doc(alias = "...")]` isn't allowed on associated constant in trait implementation block - --> $DIR/doc-alias-assoc-const.rs:8:11 + --> $DIR/doc-alias-assoc-const.rs:8:19 | LL | #[doc(alias = "CONST_BAZ")] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doc-alias-crate-level.rs b/tests/rustdoc-ui/doc-alias-crate-level.rs index 70618ac01dfb..9ba7a63d7f10 100644 --- a/tests/rustdoc-ui/doc-alias-crate-level.rs +++ b/tests/rustdoc-ui/doc-alias-crate-level.rs @@ -1,4 +1 @@ #![doc(alias = "crate-level-not-working")] //~ ERROR - -#[doc(alias = "shouldn't work!")] //~ ERROR -pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-alias-crate-level.stderr b/tests/rustdoc-ui/doc-alias-crate-level.stderr index fc8095e03ca9..1742118a67c1 100644 --- a/tests/rustdoc-ui/doc-alias-crate-level.stderr +++ b/tests/rustdoc-ui/doc-alias-crate-level.stderr @@ -1,14 +1,8 @@ -error: '\'' character isn't allowed in `#[doc(alias = "...")]` - --> $DIR/doc-alias-crate-level.rs:3:15 - | -LL | #[doc(alias = "shouldn't work!")] - | ^^^^^^^^^^^^^^^^^ - error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute - --> $DIR/doc-alias-crate-level.rs:1:8 + --> $DIR/doc-alias-crate-level.rs:1:16 | LL | #![doc(alias = "crate-level-not-working")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doc-alias-same-name.stderr b/tests/rustdoc-ui/doc-alias-same-name.stderr index a9da75c0171c..a76ff5ee0b67 100644 --- a/tests/rustdoc-ui/doc-alias-same-name.stderr +++ b/tests/rustdoc-ui/doc-alias-same-name.stderr @@ -1,8 +1,8 @@ -error: `#[doc(alias = "...")]` is the same as the item's name - --> $DIR/doc-alias-same-name.rs:3:7 +error: `#[doc(alias = "Foo"]` is the same as the item's name + --> $DIR/doc-alias-same-name.rs:3:15 | LL | #[doc(alias = "Foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doc-alias.rs b/tests/rustdoc-ui/doc-alias.rs new file mode 100644 index 000000000000..ae2a5b387191 --- /dev/null +++ b/tests/rustdoc-ui/doc-alias.rs @@ -0,0 +1,2 @@ +#[doc(alias = "shouldn't work!")] //~ ERROR +pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-alias.stderr b/tests/rustdoc-ui/doc-alias.stderr new file mode 100644 index 000000000000..1b3cc9426947 --- /dev/null +++ b/tests/rustdoc-ui/doc-alias.stderr @@ -0,0 +1,8 @@ +error: '\'' character isn't allowed in `#[doc(alias = "...")]` + --> $DIR/doc-alias.rs:1:15 + | +LL | #[doc(alias = "shouldn't work!")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doc-cfg-2.rs b/tests/rustdoc-ui/doc-cfg-2.rs new file mode 100644 index 000000000000..f615e96bbc6b --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-2.rs @@ -0,0 +1,19 @@ +#![deny(invalid_doc_attributes)] +#![feature(doc_cfg)] + +#[doc(cfg(foo), cfg(bar))] +//~^ WARN unexpected `cfg` condition name: `foo` +//~| WARN unexpected `cfg` condition name: `bar` +#[doc(auto_cfg(42))] //~ ERROR +#[doc(auto_cfg(hide(true)))] //~ ERROR +#[doc(auto_cfg(hide(42)))] //~ ERROR +#[doc(auto_cfg(hide("a")))] //~ ERROR +#[doc(auto_cfg = 42)] //~ ERROR +#[doc(auto_cfg = "a")] //~ ERROR +// Shouldn't lint +#[doc(auto_cfg(hide(windows)))] +#[doc(auto_cfg(hide(feature = "windows")))] +//~^ WARN unexpected `cfg` condition name: `feature` +#[doc(auto_cfg(hide(foo)))] +//~^ WARN unexpected `cfg` condition name: `foo` +pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg-2.stderr b/tests/rustdoc-ui/doc-cfg-2.stderr new file mode 100644 index 000000000000..a842cbc40288 --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-2.stderr @@ -0,0 +1,82 @@ +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg-2.rs:4:11 + | +LL | #[doc(cfg(foo), cfg(bar))] + | ^^^ + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `bar` + --> $DIR/doc-cfg-2.rs:4:21 + | +LL | #[doc(cfg(foo), cfg(bar))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(bar)` + = note: see for more information about checking conditional configuration + +error: only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` + --> $DIR/doc-cfg-2.rs:7:16 + | +LL | #[doc(auto_cfg(42))] + | ^^ + | +note: the lint level is defined here + --> $DIR/doc-cfg-2.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg-2.rs:8:21 + | +LL | #[doc(auto_cfg(hide(true)))] + | ^^^^ + +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg-2.rs:9:21 + | +LL | #[doc(auto_cfg(hide(42)))] + | ^^ + +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg-2.rs:10:21 + | +LL | #[doc(auto_cfg(hide("a")))] + | ^^^ + +error: expected boolean for `#[doc(auto_cfg = ...)]` + --> $DIR/doc-cfg-2.rs:11:18 + | +LL | #[doc(auto_cfg = 42)] + | ^^ + +error: expected boolean for `#[doc(auto_cfg = ...)]` + --> $DIR/doc-cfg-2.rs:12:18 + | +LL | #[doc(auto_cfg = "a")] + | ^^^ + +warning: unexpected `cfg` condition name: `feature` + --> $DIR/doc-cfg-2.rs:15:21 + | +LL | #[doc(auto_cfg(hide(feature = "windows")))] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(feature, values("windows"))` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `foo` + --> $DIR/doc-cfg-2.rs:17:21 + | +LL | #[doc(auto_cfg(hide(foo)))] + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see for more information about checking conditional configuration + +error: aborting due to 6 previous errors; 4 warnings emitted + diff --git a/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr b/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr index 0878f7edbf48..3f67b85900aa 100644 --- a/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr +++ b/tests/rustdoc-ui/doc-cfg-check-cfg.cfg_empty.stderr @@ -1,8 +1,8 @@ warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg-check-cfg.rs:12:12 + --> $DIR/doc-cfg-check-cfg.rs:15:11 | -LL | #![doc(cfg(foo))] - | ^^^ +LL | #[doc(cfg(foo))] + | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(foo)` = note: see for more information about checking conditional configuration @@ -18,10 +18,10 @@ LL | #[doc(cfg(foo))] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg-check-cfg.rs:15:11 + --> $DIR/doc-cfg-check-cfg.rs:12:12 | -LL | #[doc(cfg(foo))] - | ^^^ +LL | #![doc(cfg(foo))] + | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(foo)` = note: see for more information about checking conditional configuration diff --git a/tests/rustdoc-ui/doc-cfg.rs b/tests/rustdoc-ui/doc-cfg.rs index d72643e23556..abaea9719280 100644 --- a/tests/rustdoc-ui/doc-cfg.rs +++ b/tests/rustdoc-ui/doc-cfg.rs @@ -1,22 +1,10 @@ +#![deny(invalid_doc_attributes)] #![feature(doc_cfg)] #[doc(cfg(), cfg(foo, bar))] //~^ ERROR -//~^^ ERROR -#[doc(cfg(foo), cfg(bar))] -//~^ WARN unexpected `cfg` condition name: `foo` -//~^^ WARN unexpected `cfg` condition name: `bar` +//~| ERROR #[doc(cfg())] //~ ERROR #[doc(cfg(foo, bar))] //~ ERROR -#[doc(auto_cfg(42))] //~ ERROR -#[doc(auto_cfg(hide(true)))] //~ ERROR -#[doc(auto_cfg(hide(42)))] //~ ERROR -#[doc(auto_cfg(hide("a")))] //~ ERROR -#[doc(auto_cfg(hide(foo::bar)))] //~ ERROR -#[doc(auto_cfg = 42)] //~ ERROR -#[doc(auto_cfg = "a")] //~ ERROR -// Shouldn't lint -#[doc(auto_cfg(hide(windows)))] -#[doc(auto_cfg(hide(feature = "windows")))] -#[doc(auto_cfg(hide(foo)))] +#[doc(auto_cfg(hide(foo::bar)))] pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr index 49e8c324facf..fa25a441e9b7 100644 --- a/tests/rustdoc-ui/doc-cfg.stderr +++ b/tests/rustdoc-ui/doc-cfg.stderr @@ -1,90 +1,35 @@ -error: only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` - --> $DIR/doc-cfg.rs:11:7 - | -LL | #[doc(auto_cfg(42))] - | ^^^^^^^^^^^^ - | - = note: `#[deny(invalid_doc_attributes)]` on by default - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:12:21 - | -LL | #[doc(auto_cfg(hide(true)))] - | ^^^^ - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:13:21 - | -LL | #[doc(auto_cfg(hide(42)))] - | ^^ - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:14:21 - | -LL | #[doc(auto_cfg(hide("a")))] - | ^^^ - -error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc-cfg.rs:15:21 - | -LL | #[doc(auto_cfg(hide(foo::bar)))] - | ^^^^^^^^ - -error: expected boolean for `#[doc(auto_cfg = ...)]` - --> $DIR/doc-cfg.rs:16:7 - | -LL | #[doc(auto_cfg = 42)] - | ^^^^^^^^^^^^^ - -error: expected boolean for `#[doc(auto_cfg = ...)]` - --> $DIR/doc-cfg.rs:17:7 - | -LL | #[doc(auto_cfg = "a")] - | ^^^^^^^^^^^^^^ - -warning: unexpected `cfg` condition name: `foo` - --> $DIR/doc-cfg.rs:6:11 - | -LL | #[doc(cfg(foo), cfg(bar))] - | ^^^ - | - = help: expected names are: `FALSE` and `test` and 31 more - = help: to expect this configuration use `--check-cfg=cfg(foo)` - = note: see for more information about checking conditional configuration - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition name: `bar` - --> $DIR/doc-cfg.rs:6:21 - | -LL | #[doc(cfg(foo), cfg(bar))] - | ^^^ - | - = help: to expect this configuration use `--check-cfg=cfg(bar)` - = note: see for more information about checking conditional configuration - -error: `cfg` predicate is not specified - --> $DIR/doc-cfg.rs:3:7 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:4:1 | LL | #[doc(cfg(), cfg(foo, bar))] - | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^--^^^^^^^^^^^^^^^^^ + | | + | expected a single argument here -error: multiple `cfg` predicates are specified - --> $DIR/doc-cfg.rs:3:23 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:4:1 | LL | #[doc(cfg(), cfg(foo, bar))] - | ^^^ + | ^^^^^^^^^^^^^^^^----------^^ + | | + | expected a single argument here -error: `cfg` predicate is not specified - --> $DIR/doc-cfg.rs:9:7 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:7:1 | LL | #[doc(cfg())] - | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^--^^ + | | + | expected a single argument here -error: multiple `cfg` predicates are specified - --> $DIR/doc-cfg.rs:10:16 +error[E0805]: malformed `doc` attribute input + --> $DIR/doc-cfg.rs:8:1 | LL | #[doc(cfg(foo, bar))] - | ^^^ + | ^^^^^^^^^----------^^ + | | + | expected a single argument here -error: aborting due to 11 previous errors; 2 warnings emitted +error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0805`. diff --git a/tests/rustdoc-ui/doc-include-suggestion.rs b/tests/rustdoc-ui/doc-include-suggestion.rs index aff0a24ace86..1295805ae1a0 100644 --- a/tests/rustdoc-ui/doc-include-suggestion.rs +++ b/tests/rustdoc-ui/doc-include-suggestion.rs @@ -1,6 +1,8 @@ +#![deny(invalid_doc_attributes)] +//~^ NOTE + #[doc(include = "external-cross-doc.md")] //~^ ERROR unknown `doc` attribute `include` //~| HELP use `doc = include_str!` instead // FIXME(#85497): make this a deny instead so it's more clear what's happening -//~| NOTE on by default pub struct NeedMoreDocs; diff --git a/tests/rustdoc-ui/doc-include-suggestion.stderr b/tests/rustdoc-ui/doc-include-suggestion.stderr index 1b4b78a8f263..1587984b6e6e 100644 --- a/tests/rustdoc-ui/doc-include-suggestion.stderr +++ b/tests/rustdoc-ui/doc-include-suggestion.stderr @@ -1,10 +1,14 @@ error: unknown `doc` attribute `include` - --> $DIR/doc-include-suggestion.rs:1:7 + --> $DIR/doc-include-suggestion.rs:4:7 | LL | #[doc(include = "external-cross-doc.md")] - | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` + | ^^^^^^^ help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-include-suggestion.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.rs b/tests/rustdoc-ui/doctest/doc-test-attr.rs index 8570252c4493..e664f75a9cf7 100644 --- a/tests/rustdoc-ui/doctest/doc-test-attr.rs +++ b/tests/rustdoc-ui/doctest/doc-test-attr.rs @@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #![doc(test)] diff --git a/tests/rustdoc-ui/doctest/doc-test-attr.stderr b/tests/rustdoc-ui/doctest/doc-test-attr.stderr index 415251cc5e9d..98e7b315ea57 100644 --- a/tests/rustdoc-ui/doctest/doc-test-attr.stderr +++ b/tests/rustdoc-ui/doctest/doc-test-attr.stderr @@ -1,19 +1,23 @@ error: `#[doc(test(...)]` takes a list of attributes - --> $DIR/doc-test-attr.rs:3:8 + --> $DIR/doc-test-attr.rs:4:8 | LL | #![doc(test)] | ^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-test-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: `#[doc(test(...)]` takes a list of attributes - --> $DIR/doc-test-attr.rs:5:8 + --> $DIR/doc-test-attr.rs:6:13 | LL | #![doc(test = "hello")] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: unknown `doc(test)` attribute `a` - --> $DIR/doc-test-attr.rs:7:13 + --> $DIR/doc-test-attr.rs:8:13 | LL | #![doc(test(a))] | ^ diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs new file mode 100644 index 000000000000..9a1e86ade67f --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition: 2024 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this doesn't contains a +// "merged compilation took ..." message. + +/// ```standalone_crate +/// let x = 12; +/// ``` +/// +/// These two doctests should be not be merged, even though this passes `--merge-doctests=yes`. +/// +/// ```standalone_crate +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout new file mode 100644 index 000000000000..24b16ec82f45 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-default-not-override.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/force-merge-default-not-override.rs - Foo (line 14) ... ok +test $DIR/force-merge-default-not-override.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/force-merge-fail.rs b/tests/rustdoc-ui/doctest/force-merge-fail.rs new file mode 100644 index 000000000000..88c36268d072 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-fail.rs @@ -0,0 +1,18 @@ +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL" + +//~? ERROR failed to merge doctests + +/// These two doctests will fail to force-merge, and should give a hard error as a result. +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name() -> u8; } +/// ``` +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name(); } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge-fail.stderr b/tests/rustdoc-ui/doctest/force-merge-fail.stderr new file mode 100644 index 000000000000..b87807dc5ed7 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge-fail.stderr @@ -0,0 +1,6 @@ +doctest_bundle_2018.rs:$LINE:$COL: error: `unmangled_name` redeclared with a different signature: this signature doesn't match the previous declaration +error: aborting due to 1 previous error +error: failed to merge doctests + | + = note: requested explicitly on the command line with `--merge-doctests=yes` + diff --git a/tests/rustdoc-ui/doctest/force-merge.rs b/tests/rustdoc-ui/doctest/force-merge.rs new file mode 100644 index 000000000000..bd2f474f8a56 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=yes -Z unstable-options +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this contains a +// "merged compilation took ..." message. + +/// ``` +/// let x = 12; +/// ``` +/// +/// These two doctests should be force-merged, even though this uses edition 2018. +/// +/// ``` +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-merge.stdout b/tests/rustdoc-ui/doctest/force-merge.stdout new file mode 100644 index 000000000000..94c7909ae0a6 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-merge.stdout @@ -0,0 +1,8 @@ + +running 2 tests +test $DIR/force-merge.rs - Foo (line 14) ... ok +test $DIR/force-merge.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/force-no-merge.rs b/tests/rustdoc-ui/doctest/force-no-merge.rs new file mode 100644 index 000000000000..9ddea5fc2e55 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-no-merge.rs @@ -0,0 +1,24 @@ +//@ edition: 2024 +//@ check-pass +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=no -Z unstable-options +//@ normalize-stderr: ".*doctest_bundle_2018.rs:\d+:\d+" -> "doctest_bundle_2018.rs:$$LINE:$$COL" + +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +/// These two doctests should not force-merge, even though this crate has edition 2024 and the +/// individual doctests are not annotated. +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name() -> u8; } +/// ``` +/// +/// ``` +/// #![deny(clashing_extern_declarations)] +/// unsafe extern "C" { fn unmangled_name(); } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/force-no-merge.stdout b/tests/rustdoc-ui/doctest/force-no-merge.stdout new file mode 100644 index 000000000000..513ff7705497 --- /dev/null +++ b/tests/rustdoc-ui/doctest/force-no-merge.stdout @@ -0,0 +1,7 @@ + +running 2 tests +test $DIR/force-no-merge.rs - Foo (line 15) ... ok +test $DIR/force-no-merge.rs - Foo (line 20) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout index 65989a8ef47c..8c01c6ff5a41 100644 --- a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout +++ b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout @@ -13,8 +13,6 @@ error: macros that expand to items must be delimited with braces or followed by | LL | println!(); | ^^^^^^^^^^ - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL @@ -35,8 +33,6 @@ error: macros that expand to items must be delimited with braces or followed by | LL | println!(); | ^^^^^^^^^^ - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL diff --git a/tests/rustdoc-ui/doctest/merge-doctests-auto.rs b/tests/rustdoc-ui/doctest/merge-doctests-auto.rs new file mode 100644 index 000000000000..2e7d0db7a346 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-auto.rs @@ -0,0 +1,28 @@ +//! `--merge-doctests=auto` should override the edition. + +//@ check-pass +//@ edition: 2018 +//@ compile-flags: --test --test-args=--test-threads=1 --merge-doctests=auto -Z unstable-options + +//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" +//@ normalize-stdout: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL" + +// FIXME: compiletest doesn't support `// RAW` for doctests because the progress messages aren't +// emitted as JSON. Instead the .stderr file tests that this contains a +// "merged compilation took ..." message. + +/// ``` +/// let x = 12; +/// ``` +/// +/// These two doctests should be auto-merged, even though this uses edition 2018. +/// +/// ``` +/// fn main() { +/// println!("owo"); +/// } +/// ``` +pub struct Foo; diff --git a/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout b/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout new file mode 100644 index 000000000000..a051ffd60636 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-auto.stdout @@ -0,0 +1,8 @@ + +running 2 tests +test $DIR/merge-doctests-auto.rs - Foo (line 17) ... ok +test $DIR/merge-doctests-auto.rs - Foo (line 23) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs b/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs new file mode 100644 index 000000000000..cf3a03a901ce --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-invalid.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --merge-doctests=bad-opt -Zunstable-options +//~? ERROR must be a boolean diff --git a/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr b/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr new file mode 100644 index 000000000000..d232c1b59edb --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-invalid.stderr @@ -0,0 +1,2 @@ +error: argument to --merge-doctests must be a boolean (true/false) or 'auto' + diff --git a/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs b/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs new file mode 100644 index 000000000000..496e531659a3 --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-unstable.rs @@ -0,0 +1,2 @@ +//@ compile-flags: --merge-doctests=no +//~? RAW `-Z unstable-options` flag must also be passed diff --git a/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr b/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr new file mode 100644 index 000000000000..e8d75342bc8e --- /dev/null +++ b/tests/rustdoc-ui/doctest/merge-doctests-unstable.stderr @@ -0,0 +1,2 @@ +error: the `-Z unstable-options` flag must also be passed to enable the flag `merge-doctests` + diff --git a/tests/rustdoc-ui/extract-doctests-result.rs b/tests/rustdoc-ui/extract-doctests-result.rs index 88affb6d3331..4869fcd0259b 100644 --- a/tests/rustdoc-ui/extract-doctests-result.rs +++ b/tests/rustdoc-ui/extract-doctests-result.rs @@ -3,6 +3,7 @@ //@ compile-flags:-Z unstable-options --output-format=doctest //@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "[A-Z]:[\\/](?:[^\\/]+[\\/])*?\$DIR" -> "$$DIR" //@ check-pass //! ``` diff --git a/tests/rustdoc-ui/extract-doctests-result.stdout b/tests/rustdoc-ui/extract-doctests-result.stdout index 44e6d33c6626..bb5d2c3e68c6 100644 --- a/tests/rustdoc-ui/extract-doctests-result.stdout +++ b/tests/rustdoc-ui/extract-doctests-result.stdout @@ -1 +1 @@ -{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests-result.rs","line":8,"doctest_attributes":{"original":"","should_panic":false,"no_run":false,"ignore":"None","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nOk(())","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nOk(())","wrapper":{"before":"fn main() { fn _inner() -> core::result::Result<(), impl core::fmt::Debug> {\n","after":"\n} _inner().unwrap() }","returns_result":true}},"name":"$DIR/extract-doctests-result.rs - (line 8)"}]} \ No newline at end of file +{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests-result.rs","line":9,"doctest_attributes":{"original":"","should_panic":false,"no_run":false,"ignore":"None","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nOk(())","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nOk(())","wrapper":{"before":"fn main() { fn _inner() -> core::result::Result<(), impl core::fmt::Debug> {\n","after":"\n} _inner().unwrap() }","returns_result":true}},"name":"$DIR/extract-doctests-result.rs - (line 9)"}]} \ No newline at end of file diff --git a/tests/rustdoc-ui/extract-doctests.rs b/tests/rustdoc-ui/extract-doctests.rs index 06bd35969d0c..e2071f4ec10c 100644 --- a/tests/rustdoc-ui/extract-doctests.rs +++ b/tests/rustdoc-ui/extract-doctests.rs @@ -3,6 +3,7 @@ //@ compile-flags:-Z unstable-options --output-format=doctest //@ normalize-stdout: "tests/rustdoc-ui" -> "$$DIR" +//@ normalize-stdout: "[A-Z]:[\\/](?:[^\\/]+[\\/])*?\$DIR" -> "$$DIR" //@ check-pass //! ```ignore (checking attributes) diff --git a/tests/rustdoc-ui/extract-doctests.stdout b/tests/rustdoc-ui/extract-doctests.stdout index 796ecd82f1c9..4e2acc91f498 100644 --- a/tests/rustdoc-ui/extract-doctests.stdout +++ b/tests/rustdoc-ui/extract-doctests.stdout @@ -1 +1 @@ -{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests.rs","line":8,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nlet y = 14;","wrapper":{"before":"fn main() {\n","after":"\n}","returns_result":false}},"name":"$DIR/extract-doctests.rs - (line 8)"},{"file":"$DIR/extract-doctests.rs","line":13,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":null,"name":"$DIR/extract-doctests.rs - (line 13)"}]} \ No newline at end of file +{"format_version":2,"doctests":[{"file":"$DIR/extract-doctests.rs","line":9,"doctest_attributes":{"original":"ignore (checking attributes)","should_panic":false,"no_run":false,"ignore":"All","rust":true,"test_harness":false,"compile_fail":false,"standalone_crate":false,"error_codes":[],"edition":null,"added_css_classes":[],"unknown":[]},"original_code":"let x = 12;\nlet y = 14;","doctest_code":{"crate_level":"#![allow(unused)]\n","code":"let x = 12;\nlet y = 14;","wrapper":{"before":"fn main() {\n","after":"\n}","returns_result":false}},"name":"$DIR/extract-doctests.rs - (line 9)"},{"file":"$DIR/extract-doctests.rs","line":14,"doctest_attributes":{"original":"edition2018,compile_fail","should_panic":false,"no_run":true,"ignore":"None","rust":true,"test_harness":false,"compile_fail":true,"standalone_crate":false,"error_codes":[],"edition":"2018","added_css_classes":[],"unknown":[]},"original_code":"let","doctest_code":null,"name":"$DIR/extract-doctests.rs - (line 14)"}]} \ No newline at end of file diff --git a/tests/rustdoc-ui/ice-bug-report-url.stderr b/tests/rustdoc-ui/ice-bug-report-url.stderr index b6eb8a1792df..bc46b226a703 100644 --- a/tests/rustdoc-ui/ice-bug-report-url.stderr +++ b/tests/rustdoc-ui/ice-bug-report-url.stderr @@ -9,7 +9,7 @@ LL | fn wrong() aborting due to `-Z treat-err-as-bug=1` stack backtrace: -error: the compiler unexpectedly panicked. this is a bug. +error: the compiler unexpectedly panicked. This is a bug note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md diff --git a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs new file mode 100644 index 000000000000..91447e5fa166 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.rs @@ -0,0 +1,33 @@ +// This test ensures that the intra-doc link from reexported deprecated attribute note +// are resolved where they are declared. + +#![deny(rustdoc::broken_intra_doc_links)] + +#[doc(inline)] +pub use bar::sql_function_proc as sql_function; + +pub fn define_sql_function() {} + +pub mod bar { + #[deprecated(note = "Use [`define_sql_function`] instead")] + //~^ ERROR: unresolved link + //~| ERROR: unresolved link + pub fn sql_function_proc() {} +} + +// From here, this is a regression test for . +pub use fuzz_test_helpers::*; + +/// A type referenced in the deprecation note. +pub struct Env; + +impl Env { + pub fn try_invoke(&self) {} +} + +mod fuzz_test_helpers { + #[deprecated(note = "use [Env::try_invoke] instead")] + //~^ ERROR: unresolved link + //~| ERROR: unresolved link + pub fn fuzz_catch_panic() {} +} diff --git a/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr new file mode 100644 index 000000000000..cb7a5f0c6e02 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated-note-from-reexported.stderr @@ -0,0 +1,59 @@ +error: unresolved link to `define_sql_function` + --> $DIR/deprecated-note-from-reexported.rs:12:25 + | +LL | #[deprecated(note = "Use [`define_sql_function`] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + Use [`define_sql_function`] instead + ^^^^^^^^^^^^^^^^^^^^^ + = note: no item named `define_sql_function` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +note: the lint level is defined here + --> $DIR/deprecated-note-from-reexported.rs:4:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `Env::try_invoke` + --> $DIR/deprecated-note-from-reexported.rs:29:25 + | +LL | #[deprecated(note = "use [Env::try_invoke] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + use [Env::try_invoke] instead + ^^^^^^^^^^^^^^^ + = note: no item named `Env` in scope + +error: unresolved link to `define_sql_function` + --> $DIR/deprecated-note-from-reexported.rs:12:25 + | +LL | #[deprecated(note = "Use [`define_sql_function`] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + Use [`define_sql_function`] instead + ^^^^^^^^^^^^^^^^^^^^^ + = note: no item named `define_sql_function` in scope + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: unresolved link to `Env::try_invoke` + --> $DIR/deprecated-note-from-reexported.rs:29:25 + | +LL | #[deprecated(note = "use [Env::try_invoke] instead")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + use [Env::try_invoke] instead + ^^^^^^^^^^^^^^^ + = note: no item named `Env` in scope + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/deprecated.rs b/tests/rustdoc-ui/intra-doc/deprecated.rs new file mode 100644 index 000000000000..37c27dcde598 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated.rs @@ -0,0 +1,10 @@ +#![deny(rustdoc::broken_intra_doc_links)] + +#[deprecated = "[broken cross-reference](TypeAlias::hoge)"] //~ ERROR +pub struct A; + +#[deprecated(since = "0.0.0", note = "[broken cross-reference](TypeAlias::hoge)")] //~ ERROR +pub struct B1; + +#[deprecated(note = "[broken cross-reference](TypeAlias::hoge)", since = "0.0.0")] //~ ERROR +pub struct B2; diff --git a/tests/rustdoc-ui/intra-doc/deprecated.stderr b/tests/rustdoc-ui/intra-doc/deprecated.stderr new file mode 100644 index 000000000000..85290c334626 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/deprecated.stderr @@ -0,0 +1,43 @@ +error: unresolved link to `TypeAlias::hoge` + --> $DIR/deprecated.rs:3:16 + | +LL | #[deprecated = "[broken cross-reference](TypeAlias::hoge)"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [broken cross-reference](TypeAlias::hoge) + ^^^^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope +note: the lint level is defined here + --> $DIR/deprecated.rs:1:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `TypeAlias::hoge` + --> $DIR/deprecated.rs:6:38 + | +LL | #[deprecated(since = "0.0.0", note = "[broken cross-reference](TypeAlias::hoge)")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [broken cross-reference](TypeAlias::hoge) + ^^^^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope + +error: unresolved link to `TypeAlias::hoge` + --> $DIR/deprecated.rs:9:21 + | +LL | #[deprecated(note = "[broken cross-reference](TypeAlias::hoge)", since = "0.0.0")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [broken cross-reference](TypeAlias::hoge) + ^^^^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope + +error: aborting due to 3 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs index c71e5bee12ea..290b087916c2 100644 --- a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.rs @@ -1,6 +1,6 @@ // Regression test for issue #95879. -use unresolved_crate::module::Name; //~ ERROR failed to resolve +use unresolved_crate::module::Name; //~ ERROR cannot find /// [Name] pub struct S; diff --git a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr index dcdd230c25a1..cbbf7a7f23e7 100644 --- a/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr +++ b/tests/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `unresolved_crate` +error[E0433]: cannot find module or crate `unresolved_crate` in the crate root --> $DIR/unresolved-import-recovery.rs:3:5 | LL | use unresolved_crate::module::Name; diff --git a/tests/rustdoc-ui/invalid-cfg.rs b/tests/rustdoc-ui/invalid-cfg.rs index 7e54aeea1def..4d00edc0c7c2 100644 --- a/tests/rustdoc-ui/invalid-cfg.rs +++ b/tests/rustdoc-ui/invalid-cfg.rs @@ -1,21 +1,21 @@ #![feature(doc_cfg)] -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input pub struct S {} // We check it also fails on private items. -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input struct X {} // We check it also fails on hidden items. -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input #[doc(hidden)] pub struct Y {} // We check it also fails on hidden AND private items. -#[doc(cfg = "x")] //~ ERROR not followed by parentheses -#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(cfg = "x")] //~ ERROR malformed `doc` attribute input +#[doc(cfg(x, y))] //~ ERROR malformed `doc` attribute input #[doc(hidden)] struct Z {} diff --git a/tests/rustdoc-ui/invalid-cfg.stderr b/tests/rustdoc-ui/invalid-cfg.stderr index 455626e07bd5..539611070969 100644 --- a/tests/rustdoc-ui/invalid-cfg.stderr +++ b/tests/rustdoc-ui/invalid-cfg.stderr @@ -1,50 +1,68 @@ -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:2:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:2:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:3:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:3:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:7:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:7:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:8:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:8:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:12:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:12:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:13:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:13:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here -error: `cfg` is not followed by parentheses - --> $DIR/invalid-cfg.rs:18:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:18:1 | LL | #[doc(cfg = "x")] - | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + | ^^^^^^^^^^-----^^ + | | + | expected this to be a list -error: multiple `cfg` predicates are specified - --> $DIR/invalid-cfg.rs:19:14 +error[E0805]: malformed `doc` attribute input + --> $DIR/invalid-cfg.rs:19:1 | LL | #[doc(cfg(x, y))] - | ^ + | ^^^^^^^^^------^^ + | | + | expected a single argument here error: aborting due to 8 previous errors +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/rustdoc-ui/issues/issue-61732.rs b/tests/rustdoc-ui/issues/issue-61732.rs index d5d9ad5e4637..b375298ea40e 100644 --- a/tests/rustdoc-ui/issues/issue-61732.rs +++ b/tests/rustdoc-ui/issues/issue-61732.rs @@ -1,4 +1,4 @@ // This previously triggered an ICE. pub(in crate::r#mod) fn main() {} -//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `r#mod` +//~^ ERROR cannot find module or crate `r#mod` in `crate` diff --git a/tests/rustdoc-ui/issues/issue-61732.stderr b/tests/rustdoc-ui/issues/issue-61732.stderr index c4e6997ab74d..49d5bfc9a2f0 100644 --- a/tests/rustdoc-ui/issues/issue-61732.stderr +++ b/tests/rustdoc-ui/issues/issue-61732.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `r#mod` +error[E0433]: cannot find module or crate `r#mod` in `crate` --> $DIR/issue-61732.rs:3:15 | LL | pub(in crate::r#mod) fn main() {} diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout index c0cd454e8f3a..e7b8a1dccf80 100644 --- a/tests/rustdoc-ui/issues/issue-91713.stdout +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -1,5 +1,4 @@ Available passes for running rustdoc: - check-doc-cfg - checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs check_doc_test_visibility - run various visibility-related lints on doctests propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items strip-aliased-non-local - strips all non-local private aliased items from the output @@ -15,7 +14,6 @@ calculate-doc-coverage - counts the number of items with and without documentati Default passes for rustdoc: collect-trait-impls check_doc_test_visibility - check-doc-cfg strip-aliased-non-local propagate-doc-cfg strip-hidden (when not --document-hidden-items) diff --git a/tests/rustdoc-ui/lints/doc-attr-2.rs b/tests/rustdoc-ui/lints/doc-attr-2.rs new file mode 100644 index 000000000000..9802fb5d95a5 --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-attr-2.rs @@ -0,0 +1,12 @@ +#![deny(invalid_doc_attributes)] +#![doc(as_ptr)] +//~^ ERROR unknown `doc` attribute `as_ptr` + +#[doc(as_ptr)] +//~^ ERROR unknown `doc` attribute `as_ptr` +pub fn foo() {} + +#[doc(foo::bar, crate::bar::baz = "bye")] +//~^ ERROR unknown `doc` attribute `foo::bar` +//~| ERROR unknown `doc` attribute `crate::bar::baz` +fn bar() {} diff --git a/tests/rustdoc-ui/lints/doc-attr-2.stderr b/tests/rustdoc-ui/lints/doc-attr-2.stderr new file mode 100644 index 000000000000..f96eab1aba61 --- /dev/null +++ b/tests/rustdoc-ui/lints/doc-attr-2.stderr @@ -0,0 +1,32 @@ +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr-2.rs:5:7 + | +LL | #[doc(as_ptr)] + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/doc-attr-2.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown `doc` attribute `foo::bar` + --> $DIR/doc-attr-2.rs:9:7 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^ + +error: unknown `doc` attribute `crate::bar::baz` + --> $DIR/doc-attr-2.rs:9:17 + | +LL | #[doc(foo::bar, crate::bar::baz = "bye")] + | ^^^^^^^^^^^^^^^ + +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr-2.rs:2:8 + | +LL | #![doc(as_ptr)] + | ^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc-ui/lints/doc-attr.rs b/tests/rustdoc-ui/lints/doc-attr.rs index 666aeb55cbec..46d56e7f5962 100644 --- a/tests/rustdoc-ui/lints/doc-attr.rs +++ b/tests/rustdoc-ui/lints/doc-attr.rs @@ -1,17 +1,12 @@ #![crate_type = "lib"] -#![doc(as_ptr)] -//~^ ERROR unknown `doc` attribute - -#[doc(as_ptr)] -//~^ ERROR unknown `doc` attribute -pub fn foo() {} +#![deny(invalid_doc_attributes)] #[doc(123)] -//~^ ERROR invalid `doc` attribute +//~^ ERROR +//~| WARN #[doc("hello", "bar")] -//~^ ERROR invalid `doc` attribute -//~| ERROR invalid `doc` attribute -#[doc(foo::bar, crate::bar::baz = "bye")] -//~^ ERROR unknown `doc` attribute -//~| ERROR unknown `doc` attribute +//~^ ERROR +//~| ERROR +//~| WARN +//~| WARN fn bar() {} diff --git a/tests/rustdoc-ui/lints/doc-attr.stderr b/tests/rustdoc-ui/lints/doc-attr.stderr index 091ffc20d465..263b068e092d 100644 --- a/tests/rustdoc-ui/lints/doc-attr.stderr +++ b/tests/rustdoc-ui/lints/doc-attr.stderr @@ -1,46 +1,31 @@ -error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:5:7 - | -LL | #[doc(as_ptr)] - | ^^^^^^ - | - = note: `#[deny(invalid_doc_attributes)]` on by default - -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:9:7 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:4:7 | LL | #[doc(123)] | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/doc-attr.rs:2:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:7 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:7:7 | LL | #[doc("hello", "bar")] | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:16 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:7:16 | LL | #[doc("hello", "bar")] | ^^^^^ - -error: unknown `doc` attribute `foo::bar` - --> $DIR/doc-attr.rs:14:7 | -LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: unknown `doc` attribute `crate::bar::baz` - --> $DIR/doc-attr.rs:14:17 - | -LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:2:8 - | -LL | #![doc(as_ptr)] - | ^^^^^^ - -error: aborting due to 7 previous errors +error: aborting due to 3 previous errors diff --git a/tests/rustdoc-ui/lints/doc-spotlight.fixed b/tests/rustdoc-ui/lints/doc-spotlight.fixed index 0f8f11a9430e..98b0fac87898 100644 --- a/tests/rustdoc-ui/lints/doc-spotlight.fixed +++ b/tests/rustdoc-ui/lints/doc-spotlight.fixed @@ -1,5 +1,6 @@ //@ run-rustfix #![feature(doc_notable_trait)] +#![deny(invalid_doc_attributes)] #[doc(notable_trait)] //~^ ERROR unknown `doc` attribute `spotlight` diff --git a/tests/rustdoc-ui/lints/doc-spotlight.rs b/tests/rustdoc-ui/lints/doc-spotlight.rs index c1f90dd442b2..a0d874bdcb21 100644 --- a/tests/rustdoc-ui/lints/doc-spotlight.rs +++ b/tests/rustdoc-ui/lints/doc-spotlight.rs @@ -1,5 +1,6 @@ //@ run-rustfix #![feature(doc_notable_trait)] +#![deny(invalid_doc_attributes)] #[doc(spotlight)] //~^ ERROR unknown `doc` attribute `spotlight` diff --git a/tests/rustdoc-ui/lints/doc-spotlight.stderr b/tests/rustdoc-ui/lints/doc-spotlight.stderr index 9682a3c0c8be..8c6f9738bdc0 100644 --- a/tests/rustdoc-ui/lints/doc-spotlight.stderr +++ b/tests/rustdoc-ui/lints/doc-spotlight.stderr @@ -1,12 +1,16 @@ error: unknown `doc` attribute `spotlight` - --> $DIR/doc-spotlight.rs:4:7 + --> $DIR/doc-spotlight.rs:5:7 | LL | #[doc(spotlight)] | ^^^^^^^^^ help: use `notable_trait` instead | = note: `doc(spotlight)` was renamed to `doc(notable_trait)` = note: `doc(spotlight)` is now a no-op - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-spotlight.rs:3:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.rs b/tests/rustdoc-ui/lints/doc_cfg_hide.rs index 397b21393e5c..6c190f9befac 100644 --- a/tests/rustdoc-ui/lints/doc_cfg_hide.rs +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.rs @@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![feature(doc_cfg)] #![doc(auto_cfg(hide = "test"))] //~ ERROR #![doc(auto_cfg(hide))] //~ ERROR diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr index c63c8d607fa0..a5ec8fdf5d34 100644 --- a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr @@ -1,19 +1,23 @@ error: `#![doc(auto_cfg(hide(...)))]` expects a list of items - --> $DIR/doc_cfg_hide.rs:2:8 + --> $DIR/doc_cfg_hide.rs:3:17 | LL | #![doc(auto_cfg(hide = "test"))] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc_cfg_hide.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: `#![doc(auto_cfg(hide(...)))]` expects a list of items - --> $DIR/doc_cfg_hide.rs:3:8 + --> $DIR/doc_cfg_hide.rs:4:17 | LL | #![doc(auto_cfg(hide))] - | ^^^^^^^^^^^^^^ + | ^^^^ error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items - --> $DIR/doc_cfg_hide.rs:4:22 + --> $DIR/doc_cfg_hide.rs:5:22 | LL | #![doc(auto_cfg(hide(not(windows))))] | ^^^^^^^^^^^^ diff --git a/tests/rustdoc-ui/lints/duplicated-attr.rs b/tests/rustdoc-ui/lints/duplicated-attr.rs new file mode 100644 index 000000000000..b89908d700f4 --- /dev/null +++ b/tests/rustdoc-ui/lints/duplicated-attr.rs @@ -0,0 +1,6 @@ +#![deny(invalid_doc_attributes)] +#![expect(unused_attributes)] +#![doc(test(no_crate_inject))] +#![doc(test(no_crate_inject))] +//~^ ERROR +//~| WARN diff --git a/tests/rustdoc-ui/lints/duplicated-attr.stderr b/tests/rustdoc-ui/lints/duplicated-attr.stderr new file mode 100644 index 000000000000..3682710bb54a --- /dev/null +++ b/tests/rustdoc-ui/lints/duplicated-attr.stderr @@ -0,0 +1,20 @@ +error: unused attribute + --> $DIR/duplicated-attr.rs:4:13 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/duplicated-attr.rs:3:13 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/duplicated-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs b/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs new file mode 100644 index 000000000000..afb0a5987deb --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-crate-level-lint.rs @@ -0,0 +1,14 @@ +#![deny(invalid_doc_attributes)] +#![crate_type = "lib"] + +#[doc(test(no_crate_inject))] +//~^ ERROR can only be applied at the crate level + +pub mod bar { + #![doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + + #[doc(test(no_crate_inject))] + //~^ ERROR can only be applied at the crate level + fn foo() {} +} diff --git a/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr b/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr new file mode 100644 index 000000000000..7569cf575e51 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-crate-level-lint.stderr @@ -0,0 +1,31 @@ +error: this attribute can only be applied at the crate level + --> $DIR/invalid-crate-level-lint.rs:4:12 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + | + = note: read for more information +note: the lint level is defined here + --> $DIR/invalid-crate-level-lint.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: this attribute can only be applied at the crate level + --> $DIR/invalid-crate-level-lint.rs:8:17 + | +LL | #![doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + | + = note: read for more information + +error: this attribute can only be applied at the crate level + --> $DIR/invalid-crate-level-lint.rs:11:16 + | +LL | #[doc(test(no_crate_inject))] + | ^^^^^^^^^^^^^^^ + | + = note: read for more information + +error: aborting due to 3 previous errors + diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-2.rs b/tests/rustdoc-ui/lints/invalid-doc-attr-2.rs new file mode 100644 index 000000000000..de99d5a9e078 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-2.rs @@ -0,0 +1,7 @@ +#![deny(invalid_doc_attributes)] + +#![doc("other attribute")] +//~^ ERROR +//~| WARN +#![doc] +//~^ ERROR diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-2.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr-2.stderr new file mode 100644 index 000000000000..2457352bb342 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-2.stderr @@ -0,0 +1,21 @@ +error: expected this to be of the form `... = "..."` + --> $DIR/invalid-doc-attr-2.rs:3:8 + | +LL | #![doc("other attribute")] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/invalid-doc-attr-2.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: valid forms for the attribute are `#![doc = "string"]`, `#![doc(alias)]`, `#![doc(attribute)]`, `#![doc(auto_cfg)]`, `#![doc(cfg)]`, `#![doc(fake_variadic)]`, `#![doc(hidden)]`, `#![doc(html_favicon_url)]`, `#![doc(html_logo_url)]`, `#![doc(html_no_source)]`, `#![doc(html_playground_url)]`, `#![doc(html_root_url)]`, `#![doc(include)]`, `#![doc(inline)]`, `#![doc(issue_tracker_base_url)]`, `#![doc(keyword)]`, `#![doc(masked)]`, `#![doc(no_default_passes)]`, `#![doc(no_inline)]`, `#![doc(notable_trait)]`, `#![doc(passes)]`, `#![doc(plugins)]`, `#![doc(rust_logo)]`, `#![doc(search_unbox)]`, `#![doc(spotlight)]`, and `#![doc(test)]` + --> $DIR/invalid-doc-attr-2.rs:6:1 + | +LL | #![doc] + | ^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-3.rs b/tests/rustdoc-ui/lints/invalid-doc-attr-3.rs new file mode 100644 index 000000000000..1d2e4445140a --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-3.rs @@ -0,0 +1,22 @@ +#![deny(invalid_doc_attributes)] + +#![doc(test(no_crate_inject = 1))] +//~^ ERROR +//~| WARN +#![doc(test(attr = 1))] +//~^ ERROR +//~| WARN + +#[doc(hidden = true)] +//~^ ERROR +//~| WARN +#[doc(hidden("or you will be fired"))] +//~^ ERROR +//~| WARN +#[doc(hidden = "handled transparently by codegen")] +//~^ ERROR +//~| WARN +#[doc = 1] +//~^ ERROR +//~| WARN +pub struct X; diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr-3.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr-3.stderr new file mode 100644 index 000000000000..9cec930174ce --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-doc-attr-3.stderr @@ -0,0 +1,55 @@ +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:10:14 + | +LL | #[doc(hidden = true)] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/invalid-doc-attr-3.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:13:13 + | +LL | #[doc(hidden("or you will be fired"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:16:14 + | +LL | #[doc(hidden = "handled transparently by codegen")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: malformed `doc` attribute input + --> $DIR/invalid-doc-attr-3.rs:19:9 + | +LL | #[doc = 1] + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: didn't expect any arguments here + --> $DIR/invalid-doc-attr-3.rs:3:29 + | +LL | #![doc(test(no_crate_inject = 1))] + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: malformed `doc` attribute input + --> $DIR/invalid-doc-attr-3.rs:6:1 + | +LL | #![doc(test(attr = 1))] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: aborting due to 6 previous errors + diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.rs b/tests/rustdoc-ui/lints/invalid-doc-attr.rs index e1cc08ca2427..60c215222d7f 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.rs +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.rs @@ -1,23 +1,15 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #![feature(doc_masked)] #![doc(masked)] //~^ ERROR this attribute can only be applied to an `extern crate` item -#[doc(test(no_crate_inject))] -//~^ ERROR can only be applied at the crate level -//~| HELP to apply to the crate, use an inner attribute -//~| SUGGESTION ! #[doc(inline)] //~^ ERROR can only be applied to a `use` item pub fn foo() {} pub mod bar { - #![doc(test(no_crate_inject))] - //~^ ERROR can only be applied at the crate level - - #[doc(test(no_crate_inject))] - //~^ ERROR can only be applied at the crate level #[doc(inline)] //~^ ERROR can only be applied to a `use` item pub fn baz() {} diff --git a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr index 7621999a8ca5..2e9b9f0a8cfb 100644 --- a/tests/rustdoc-ui/lints/invalid-doc-attr.stderr +++ b/tests/rustdoc-ui/lints/invalid-doc-attr.stderr @@ -1,18 +1,5 @@ -error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:7:7 - | -LL | #[doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: read for more information - = note: `#[deny(invalid_doc_attributes)]` on by default -help: to apply to the crate, use an inner attribute - | -LL | #![doc(test(no_crate_inject))] - | + - error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:11:7 + --> $DIR/invalid-doc-attr.rs:8:7 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items @@ -21,17 +8,14 @@ LL | pub fn foo() {} | ------------ not a `use` item | = note: read for more information - -error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:16:12 +note: the lint level is defined here + --> $DIR/invalid-doc-attr.rs:1:9 | -LL | #![doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: read for more information +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: conflicting doc inlining attributes - --> $DIR/invalid-doc-attr.rs:26:7 + --> $DIR/invalid-doc-attr.rs:18:7 | LL | #[doc(inline)] | ^^^^^^ this attribute... @@ -41,7 +25,7 @@ LL | #[doc(no_inline)] = help: remove one of the conflicting attributes error: this attribute can only be applied to an `extern crate` item - --> $DIR/invalid-doc-attr.rs:32:7 + --> $DIR/invalid-doc-attr.rs:24:7 | LL | #[doc(masked)] | ^^^^^^ only applicable on `extern crate` items @@ -52,7 +36,7 @@ LL | pub struct Masked; = note: read for more information error: this attribute cannot be applied to an `extern crate self` item - --> $DIR/invalid-doc-attr.rs:36:7 + --> $DIR/invalid-doc-attr.rs:28:7 | LL | #[doc(masked)] | ^^^^^^ not applicable on `extern crate self` items @@ -61,23 +45,22 @@ LL | pub extern crate self as reexport; | --------------------------------- `extern crate self` defined here error: this attribute can only be applied to an `extern crate` item - --> $DIR/invalid-doc-attr.rs:4:8 + --> $DIR/invalid-doc-attr.rs:5:8 | -LL | #![doc(masked)] - | ^^^^^^ only applicable on `extern crate` items +LL | / #![deny(invalid_doc_attributes)] +LL | | #![crate_type = "lib"] +LL | | #![feature(doc_masked)] +LL | | +LL | | #![doc(masked)] + | | ^^^^^^ only applicable on `extern crate` items +... | +LL | | pub extern crate self as reexport; + | |__________________________________- not an `extern crate` item | = note: read for more information -error: this attribute can only be applied at the crate level - --> $DIR/invalid-doc-attr.rs:19:11 - | -LL | #[doc(test(no_crate_inject))] - | ^^^^^^^^^^^^^^^^^^^^^ - | - = note: read for more information - error: this attribute can only be applied to a `use` item - --> $DIR/invalid-doc-attr.rs:21:11 + --> $DIR/invalid-doc-attr.rs:13:11 | LL | #[doc(inline)] | ^^^^^^ only applicable on `use` items @@ -87,5 +70,5 @@ LL | pub fn baz() {} | = note: read for more information -error: aborting due to 9 previous errors +error: aborting due to 6 previous errors diff --git a/tests/rustdoc/display-hidden-items.rs b/tests/rustdoc/display-hidden-items.rs deleted file mode 100644 index 8b0854d1ade8..000000000000 --- a/tests/rustdoc/display-hidden-items.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Test to ensure that the `--document-hidden-items` option is working as expected. -//@ compile-flags: -Z unstable-options --document-hidden-items -// ignore-tidy-linelength - -#![crate_name = "foo"] - -//@ has 'foo/index.html' -//@ has - '//dt/span[@title="Hidden item"]' '👻' - -//@ has - '//*[@id="reexport.hidden_reexport"]/code' '#[doc(hidden)] pub use hidden::inside_hidden as hidden_reexport;' -#[doc(hidden)] -pub use hidden::inside_hidden as hidden_reexport; - -//@ has - '//dt/a[@class="trait"]' 'TraitHidden' -//@ has 'foo/trait.TraitHidden.html' -//@ has - '//code' '#[doc(hidden)] pub trait TraitHidden' -#[doc(hidden)] -pub trait TraitHidden {} - -//@ has 'foo/index.html' '//dt/a[@class="trait"]' 'Trait' -pub trait Trait { - //@ has 'foo/trait.Trait.html' - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' - #[doc(hidden)] - const BAR: u32 = 0; - - //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' 'fn foo()' - #[doc(hidden)] - fn foo() {} -} - -//@ has 'foo/index.html' '//dt/a[@class="struct"]' 'Struct' -//@ has 'foo/struct.Struct.html' -pub struct Struct { - //@ has - '//*[@id="structfield.a"]/code' 'a: u32' - #[doc(hidden)] - pub a: u32, -} - -impl Struct { - //@ has - '//*[@id="method.new"]/*[@class="code-header"]' 'pub fn new() -> Self' - #[doc(hidden)] - pub fn new() -> Self { Self { a: 0 } } -} - -impl Trait for Struct { - //@ has - '//*[@id="associatedconstant.BAR"]/*[@class="code-header"]' '#[doc(hidden)] const BAR: u32 = 0' - //@ has - '//*[@id="method.foo"]/*[@class="code-header"]' '#[doc(hidden)] fn foo()' -} -//@ has - '//*[@id="impl-TraitHidden-for-Struct"]/*[@class="code-header"]' 'impl TraitHidden for Struct' -impl TraitHidden for Struct {} - -//@ has 'foo/index.html' '//dt/a[@class="enum"]' 'HiddenEnum' -//@ has 'foo/enum.HiddenEnum.html' -//@ has - '//code' '#[doc(hidden)] pub enum HiddenEnum' -#[doc(hidden)] -pub enum HiddenEnum { - A, -} - -//@ has 'foo/index.html' '//dt/a[@class="enum"]' 'Enum' -pub enum Enum { - //@ has 'foo/enum.Enum.html' '//*[@id="variant.A"]/*[@class="code-header"]' 'A' - #[doc(hidden)] - A, -} - -//@ has 'foo/index.html' '//dt/a[@class="mod"]' 'hidden' -#[doc(hidden)] -pub mod hidden { - //@ has 'foo/hidden/index.html' - //@ has - '//dt/a[@class="fn"]' 'inside_hidden' - //@ has 'foo/hidden/fn.inside_hidden.html' - pub fn inside_hidden() {} -} diff --git a/tests/rustdoc/empty-section.rs b/tests/rustdoc/empty-section.rs deleted file mode 100644 index 71ebc66d6953..000000000000 --- a/tests/rustdoc/empty-section.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![crate_name = "foo"] -#![feature(negative_impls, freeze_impls, freeze)] - -pub struct Foo; - -//@ has foo/struct.Foo.html -//@ !hasraw - 'Auto Trait Implementations' -impl !Send for Foo {} -impl !Sync for Foo {} -impl !std::marker::Freeze for Foo {} -impl !std::marker::Unpin for Foo {} -impl !std::panic::RefUnwindSafe for Foo {} -impl !std::panic::UnwindSafe for Foo {} diff --git a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs b/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs deleted file mode 100644 index f6c03d189b5e..000000000000 --- a/tests/rustdoc/inline_cross/auxiliary/assoc-const-equality.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] - -pub fn accept(_: impl Trait) {} - -pub trait Trait { - #[type_const] - const K: i32; -} diff --git a/tests/rustdoc/synthetic_auto/basic.rs b/tests/rustdoc/synthetic_auto/basic.rs deleted file mode 100644 index 9daf8963997a..000000000000 --- a/tests/rustdoc/synthetic_auto/basic.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ has basic/struct.Foo.html -//@ has - '//h3[@class="code-header"]' 'impl Send for Foowhere T: Send' -//@ has - '//h3[@class="code-header"]' 'impl Sync for Foowhere T: Sync' -//@ count - '//*[@id="implementations-list"]//*[@class="impl"]' 0 -//@ count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6 -pub struct Foo { - field: T, -} diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 48f328f4fad3..c15c2dea4c19 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -29,10 +29,6 @@ use rustc_session::config::OutputFilenames; struct TheBackend; impl CodegenBackend for TheBackend { - fn locale_resource(&self) -> &'static str { - "" - } - fn name(&self) -> &'static str { "the-backend" } diff --git a/tests/ui-fulldeps/explain_highlighter.rs b/tests/ui-fulldeps/explain_highlighter.rs new file mode 100644 index 000000000000..337f31738a76 --- /dev/null +++ b/tests/ui-fulldeps/explain_highlighter.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ check-run-results + +#![feature(rustc_private)] +use std::io::Write; +extern crate rustc_driver; +extern crate rustc_driver_impl; + +use rustc_driver_impl::highlighter::highlight; + +const TEST_INPUT: &str = " +struct Foo; + +fn baz(x: i32) { + // A function +} + +fn main() { + let foo = Foo; + foo.bar(); +} +"; + +fn main() { + let mut buf = Vec::new(); + highlight(TEST_INPUT, &mut buf).unwrap(); + let mut stdout = std::io::stdout(); + stdout.write_all(&buf).unwrap(); +} diff --git a/tests/ui-fulldeps/explain_highlighter.run.stdout b/tests/ui-fulldeps/explain_highlighter.run.stdout new file mode 100644 index 000000000000..f54021c68bb9 --- /dev/null +++ b/tests/ui-fulldeps/explain_highlighter.run.stdout @@ -0,0 +1,12 @@ + +struct Foo; + +fn baz(x: i32) { + // A function +} + +fn main() { + let foo = Foo; + foo.bar(); +} + \ No newline at end of file diff --git a/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl b/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl deleted file mode 100644 index 9407c5170450..000000000000 --- a/tests/ui-fulldeps/fluent-messages/duplicate-a-b.ftl +++ /dev/null @@ -1 +0,0 @@ -a_b_key = Value diff --git a/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl b/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl deleted file mode 100644 index 9407c5170450..000000000000 --- a/tests/ui-fulldeps/fluent-messages/duplicate-a.ftl +++ /dev/null @@ -1 +0,0 @@ -a_b_key = Value diff --git a/tests/ui-fulldeps/fluent-messages/duplicate.ftl b/tests/ui-fulldeps/fluent-messages/duplicate.ftl deleted file mode 100644 index 871550b231a3..000000000000 --- a/tests/ui-fulldeps/fluent-messages/duplicate.ftl +++ /dev/null @@ -1,3 +0,0 @@ -no_crate_a_b_key = Value - -no_crate_a_b_key = Another Value diff --git a/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl deleted file mode 100644 index e28852ea0050..000000000000 --- a/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_bad_escape = don't use \n, \', or \" diff --git a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl deleted file mode 100644 index 3088b1f8dc83..000000000000 --- a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl +++ /dev/null @@ -1,2 +0,0 @@ -no_crate_some_slug = hi - .label-has-hyphens = test diff --git a/tests/ui-fulldeps/fluent-messages/many-lines.ftl b/tests/ui-fulldeps/fluent-messages/many-lines.ftl deleted file mode 100644 index 43660ebeacdc..000000000000 --- a/tests/ui-fulldeps/fluent-messages/many-lines.ftl +++ /dev/null @@ -1,11 +0,0 @@ -no_crate_foo = foo - -# This file tests error reporting for -# fluent files with many lines. -# The error message should point to the correct line number -# and include no more context than necessary. - -no_crate_bar = - -no_crate_baz = - baz diff --git a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl deleted file mode 100644 index 0a64e3894bd5..000000000000 --- a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl +++ /dev/null @@ -1,2 +0,0 @@ -with-hyphens = 1234 -no-crate_foo = abcd diff --git a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl deleted file mode 100644 index 4c6514a97700..000000000000 --- a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_missing_message_ref = {message} diff --git a/tests/ui-fulldeps/fluent-messages/missing-message.ftl b/tests/ui-fulldeps/fluent-messages/missing-message.ftl deleted file mode 100644 index 61f56fd4d57b..000000000000 --- a/tests/ui-fulldeps/fluent-messages/missing-message.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_missing_message = diff --git a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl deleted file mode 100644 index a64c85094f1d..000000000000 --- a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_this-slug-has-hyphens = hi diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs deleted file mode 100644 index c1f5fe730c76..000000000000 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ /dev/null @@ -1,87 +0,0 @@ -//@ normalize-stderr: "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" - -#![feature(rustc_private)] -#![crate_type = "lib"] -extern crate rustc_errors; -extern crate rustc_fluent_macro; - -/// Copy of the relevant `DiagMessage` variant constructed by `fluent_messages` as it -/// expects `crate::DiagMessage` to exist. -pub enum DiagMessage { - FluentIdentifier(std::borrow::Cow<'static, str>, Option>), -} - -/// Copy of the relevant `SubdiagMessage` variant constructed by `fluent_messages` as it -/// expects `crate::SubdiagMessage` to exist. -pub enum SubdiagMessage { - FluentAttr(std::borrow::Cow<'static, str>), -} - -mod missing_absolute { - rustc_fluent_macro::fluent_messages! { "/definitely_does_not_exist.ftl" } - //~^ ERROR could not open Fluent resource -} - -mod missing_relative { - rustc_fluent_macro::fluent_messages! { "../definitely_does_not_exist.ftl" } - //~^ ERROR could not open Fluent resource -} - -mod missing_message { - rustc_fluent_macro::fluent_messages! { "./missing-message.ftl" } - //~^ ERROR could not parse Fluent resource -} - -mod duplicate { - rustc_fluent_macro::fluent_messages! { "./duplicate.ftl" } - //~^ ERROR overrides existing message: `no_crate_a_b_key` -} - -mod slug_with_hyphens { - rustc_fluent_macro::fluent_messages! { "./slug-with-hyphens.ftl" } - //~^ ERROR name `no_crate_this-slug-has-hyphens` contains a '-' character -} - -mod label_with_hyphens { - rustc_fluent_macro::fluent_messages! { "./label-with-hyphens.ftl" } - //~^ ERROR attribute `label-has-hyphens` contains a '-' character -} - -mod valid { - rustc_fluent_macro::fluent_messages! { "./valid.ftl" } - - mod test_generated { - use super::{fluent_generated::no_crate_key, DEFAULT_LOCALE_RESOURCE}; - } -} - -mod missing_crate_name { - rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - //~^ ERROR name `no-crate_foo` contains a '-' character - //~| ERROR name `with-hyphens` contains a '-' character - //~| ERROR name `with-hyphens` does not start with the crate name - - mod test_generated { - use super::{ - fluent_generated::{no_crate_foo, with_hyphens}, - DEFAULT_LOCALE_RESOURCE, - }; - } -} - -mod missing_message_ref { - rustc_fluent_macro::fluent_messages! { "./missing-message-ref.ftl" } - //~^ ERROR referenced message `message` does not exist -} - -mod bad_escape { - rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - //~^ ERROR invalid escape `\n` - //~| ERROR invalid escape `\"` - //~| ERROR invalid escape `\'` -} - -mod many_lines { - rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" } - //~^ ERROR could not parse Fluent resource -} diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr deleted file mode 100644 index 0b3bb14ce513..000000000000 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ /dev/null @@ -1,122 +0,0 @@ -error: could not open Fluent resource: os-specific message - --> $DIR/test.rs:21:44 - | -LL | rustc_fluent_macro::fluent_messages! { "/definitely_does_not_exist.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: could not open Fluent resource: os-specific message - --> $DIR/test.rs:26:44 - | -LL | rustc_fluent_macro::fluent_messages! { "../definitely_does_not_exist.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: could not parse Fluent resource - --> $DIR/test.rs:31:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-message.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: see additional errors emitted - -error: expected a message field for "no_crate_missing_message" - --> ./missing-message.ftl:1:1 - | -1 | no_crate_missing_message = - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - -error: overrides existing message: `no_crate_a_b_key` - --> $DIR/test.rs:36:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./duplicate.ftl" } - | ^^^^^^^^^^^^^^^^^ - -error: name `no_crate_this-slug-has-hyphens` contains a '-' character - --> $DIR/test.rs:41:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./slug-with-hyphens.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: attribute `label-has-hyphens` contains a '-' character - --> $DIR/test.rs:46:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./label-with-hyphens.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: name `with-hyphens` contains a '-' character - --> $DIR/test.rs:59:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: name `with-hyphens` does not start with the crate name - --> $DIR/test.rs:59:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: prepend `no_crate_` to the slug name: `no_crate_with_hyphens` - -error: name `no-crate_foo` contains a '-' character - --> $DIR/test.rs:59:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-crate-name.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: replace any '-'s with '_'s - -error: referenced message `message` does not exist (in message `no_crate_missing_message_ref`) - --> $DIR/test.rs:73:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./missing-message-ref.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: you may have meant to use a variable reference (`{$message}`) - -error: invalid escape `\n` in Fluent resource - --> $DIR/test.rs:78:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: Fluent does not interpret these escape sequences () - -error: invalid escape `\"` in Fluent resource - --> $DIR/test.rs:78:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: Fluent does not interpret these escape sequences () - -error: invalid escape `\'` in Fluent resource - --> $DIR/test.rs:78:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" } - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: Fluent does not interpret these escape sequences () - -error: could not parse Fluent resource - --> $DIR/test.rs:85:44 - | -LL | rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" } - | ^^^^^^^^^^^^^^^^^^ - | - = help: see additional errors emitted - -error: expected a message field for "no_crate_bar" - --> ./many-lines.ftl:8:1 - | -8 | no_crate_bar = - | ^^^^^^^^^^^^^^ - | - -error: aborting due to 14 previous errors - diff --git a/tests/ui-fulldeps/fluent-messages/valid.ftl b/tests/ui-fulldeps/fluent-messages/valid.ftl deleted file mode 100644 index 598473adb680..000000000000 --- a/tests/ui-fulldeps/fluent-messages/valid.ftl +++ /dev/null @@ -1 +0,0 @@ -no_crate_key = Valid! diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.rs b/tests/ui-fulldeps/hash-stable-is-unstable.rs index 7f62b6044104..a3dfd7e85ba6 100644 --- a/tests/ui-fulldeps/hash-stable-is-unstable.rs +++ b/tests/ui-fulldeps/hash-stable-is-unstable.rs @@ -7,7 +7,7 @@ extern crate rustc_macros; //~^ ERROR use of unstable library feature `rustc_private` //~| NOTE: see issue #27812 for more information //~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -extern crate rustc_query_system; +extern crate rustc_middle; //~^ ERROR use of unstable library feature `rustc_private` //~| NOTE: see issue #27812 for more information //~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.stderr b/tests/ui-fulldeps/hash-stable-is-unstable.stderr index e7740d744b4f..7c69e8f5e631 100644 --- a/tests/ui-fulldeps/hash-stable-is-unstable.stderr +++ b/tests/ui-fulldeps/hash-stable-is-unstable.stderr @@ -21,8 +21,8 @@ LL | extern crate rustc_macros; error[E0658]: use of unstable library feature `rustc_private`: this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? --> $DIR/hash-stable-is-unstable.rs:10:1 | -LL | extern crate rustc_query_system; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | extern crate rustc_middle; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #27812 for more information = help: add `#![feature(rustc_private)]` to the crate attributes to enable diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.ftl b/tests/ui-fulldeps/internal-lints/diagnostics.ftl deleted file mode 100644 index cb2d476d815d..000000000000 --- a/tests/ui-fulldeps/internal-lints/diagnostics.ftl +++ /dev/null @@ -1,5 +0,0 @@ -no_crate_example = this is an example message used in testing - .note = with a note - .help = with a help - .suggestion = with a suggestion - .label = with a label diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs deleted file mode 100644 index 1238fefd5bc0..000000000000 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ /dev/null @@ -1,125 +0,0 @@ -//@ compile-flags: -Z unstable-options -//@ ignore-stage1 - -#![crate_type = "lib"] -#![feature(rustc_attrs)] -#![feature(rustc_private)] -#![deny(rustc::untranslatable_diagnostic)] -#![deny(rustc::diagnostic_outside_of_impl)] - -extern crate rustc_errors; -extern crate rustc_fluent_macro; -extern crate rustc_macros; -extern crate rustc_session; -extern crate rustc_span; - -use rustc_errors::{ - Diag, DiagCtxtHandle, DiagInner, DiagMessage, Diagnostic, EmissionGuarantee, Level, - LintDiagnostic, SubdiagMessage, Subdiagnostic, -}; -use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_span::Span; - -rustc_fluent_macro::fluent_messages! { "./diagnostics.ftl" } - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct DeriveDiagnostic { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[note(no_crate_example)] -struct Note { - #[primary_span] - span: Span, -} - -pub struct UntranslatableInDiagnostic; - -impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UntranslatableInDiagnostic { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - Diag::new(dcx, level, "untranslatable diagnostic") - //~^ ERROR diagnostics should be created using translatable messages - } -} - -pub struct TranslatableInDiagnostic; - -impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for TranslatableInDiagnostic { - fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - Diag::new(dcx, level, crate::fluent_generated::no_crate_example) - } -} - -pub struct UntranslatableInAddtoDiag; - -impl Subdiagnostic for UntranslatableInAddtoDiag { - fn add_to_diag( - self, - diag: &mut Diag<'_, G>, - ) { - diag.note("untranslatable diagnostic"); - //~^ ERROR diagnostics should be created using translatable messages - } -} - -pub struct TranslatableInAddtoDiag; - -impl Subdiagnostic for TranslatableInAddtoDiag { - fn add_to_diag( - self, - diag: &mut Diag<'_, G>, - ) { - diag.note(crate::fluent_generated::no_crate_note); - } -} - -pub struct UntranslatableInLintDiagnostic; - -impl<'a> LintDiagnostic<'a, ()> for UntranslatableInLintDiagnostic { - fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.note("untranslatable diagnostic"); - //~^ ERROR diagnostics should be created using translatable messages - } -} - -pub struct TranslatableInLintDiagnostic; - -impl<'a> LintDiagnostic<'a, ()> for TranslatableInLintDiagnostic { - fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) { - diag.note(crate::fluent_generated::no_crate_note); - } -} - -pub fn make_diagnostics<'a>(dcx: DiagCtxtHandle<'a>) { - let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); - //~^ ERROR diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - - let _diag = dcx.struct_err("untranslatable diagnostic"); - //~^ ERROR diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - //~^^ ERROR diagnostics should be created using translatable messages -} - -// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted for -// `diagnostic_outside_of_impl`. -#[rustc_lint_diagnostics] -pub fn skipped_because_of_annotation<'a>(dcx: DiagCtxtHandle<'a>) { - #[allow(rustc::untranslatable_diagnostic)] - let _diag = dcx.struct_err("untranslatable diagnostic"); // okay! -} - -// Check that multiple translatable params are allowed in a single function (at one point they -// weren't). -fn f(_x: impl Into, _y: impl Into) {} -fn g() { - f(crate::fluent_generated::no_crate_example, crate::fluent_generated::no_crate_example); - f("untranslatable diagnostic", crate::fluent_generated::no_crate_example); - //~^ ERROR diagnostics should be created using translatable messages - f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic"); - //~^ ERROR diagnostics should be created using translatable messages - f("untranslatable diagnostic", "untranslatable diagnostic"); - //~^ ERROR diagnostics should be created using translatable messages - //~^^ ERROR diagnostics should be created using translatable messages -} diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr deleted file mode 100644 index b260c4b7afef..000000000000 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ /dev/null @@ -1,74 +0,0 @@ -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:43:31 - | -LL | Diag::new(dcx, level, "untranslatable diagnostic") - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/diagnostics.rs:7:9 - | -LL | #![deny(rustc::untranslatable_diagnostic)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:63:19 - | -LL | diag.note("untranslatable diagnostic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:83:19 - | -LL | diag.note("untranslatable diagnostic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - --> $DIR/diagnostics.rs:97:21 - | -LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example); - | ^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/diagnostics.rs:8:9 - | -LL | #![deny(rustc::diagnostic_outside_of_impl)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls - --> $DIR/diagnostics.rs:100:21 - | -LL | let _diag = dcx.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ - -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:100:32 - | -LL | let _diag = dcx.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:118:7 - | -LL | f("untranslatable diagnostic", crate::fluent_generated::no_crate_example); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:120:50 - | -LL | f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:122:7 - | -LL | f("untranslatable diagnostic", "untranslatable diagnostic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:122:36 - | -LL | f("untranslatable diagnostic", "untranslatable diagnostic"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 10 previous errors - diff --git a/tests/ui-fulldeps/lexer/unicode-version.rs b/tests/ui-fulldeps/lexer/unicode-version.rs index cd02b952895c..a924f9241649 100644 --- a/tests/ui-fulldeps/lexer/unicode-version.rs +++ b/tests/ui-fulldeps/lexer/unicode-version.rs @@ -12,7 +12,6 @@ #![feature(rustc_private)] extern crate rustc_driver; -extern crate rustc_lexer; extern crate rustc_parse; fn main() { @@ -22,6 +21,5 @@ fn main() { it should also be updated in the reference at \ https://github.com/rust-lang/reference/blob/HEAD/src/identifiers.md." ); - println!("Unicode XID version is: {:?}", rustc_lexer::UNICODE_XID_VERSION); - println!("Unicode normalization version is: {:?}", rustc_parse::UNICODE_NORMALIZATION_VERSION); + println!("Unicode version used in rustc_parse is: {:?}", rustc_parse::UNICODE_VERSION); } diff --git a/tests/ui-fulldeps/lexer/unicode-version.run.stdout b/tests/ui-fulldeps/lexer/unicode-version.run.stdout index f32c8365cdf3..327b08997034 100644 --- a/tests/ui-fulldeps/lexer/unicode-version.run.stdout +++ b/tests/ui-fulldeps/lexer/unicode-version.run.stdout @@ -1,4 +1,3 @@ Checking if Unicode version changed. If the Unicode version changes are intentional, it should also be updated in the reference at https://github.com/rust-lang/reference/blob/HEAD/src/identifiers.md. -Unicode XID version is: (16, 0, 0) -Unicode normalization version is: (16, 0, 0) +Unicode version used in rustc_parse is: (17, 0, 0) diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs index 86f2d5f5954a..806d395a90ad 100644 --- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -29,7 +29,7 @@ pub fn main() { } fn parse() { - let psess = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]); + let psess = ParseSess::new(); let path = Path::new(file!()); let path = path.canonicalize().unwrap(); diff --git a/tests/ui-fulldeps/obtain-borrowck.rs b/tests/ui-fulldeps/obtain-borrowck.rs index 08213fd75880..46ed23b58ac9 100644 --- a/tests/ui-fulldeps/obtain-borrowck.rs +++ b/tests/ui-fulldeps/obtain-borrowck.rs @@ -28,6 +28,7 @@ extern crate rustc_session; use std::cell::RefCell; use std::collections::HashMap; +use std::process::ExitCode; use std::thread_local; use rustc_borrowck::consumers::{self, BodyWithBorrowckFacts, ConsumerOptions}; @@ -37,21 +38,20 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_interface::Config; use rustc_interface::interface::Compiler; -use rustc_middle::query::queries::mir_borrowck::ProvidedValue; +use rustc_middle::queries::mir_borrowck::ProvidedValue; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; -fn main() { - let exit_code = rustc_driver::catch_with_exit_code(move || { +fn main() -> ExitCode { + rustc_driver::catch_with_exit_code(move || { let mut rustc_args: Vec<_> = std::env::args().collect(); // We must pass -Zpolonius so that the borrowck information is computed. rustc_args.push("-Zpolonius".to_owned()); let mut callbacks = CompilerCalls::default(); // Call the Rust compiler with our callbacks. rustc_driver::run_compiler(&rustc_args, &mut callbacks); - }); - std::process::exit(exit_code); + }) } #[derive(Default)] @@ -114,7 +114,7 @@ impl rustc_driver::Callbacks for CompilerCalls { } fn override_queries(_session: &Session, local: &mut Providers) { - local.mir_borrowck = mir_borrowck; + local.queries.mir_borrowck = mir_borrowck; } // Since mir_borrowck does not have access to any other state, we need to use a @@ -142,8 +142,8 @@ fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProvidedValue<'t } }); let mut providers = Providers::default(); - rustc_borrowck::provide(&mut providers); - let original_mir_borrowck = providers.mir_borrowck; + rustc_borrowck::provide(&mut providers.queries); + let original_mir_borrowck = providers.queries.mir_borrowck; original_mir_borrowck(tcx, def_id) } diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index 08ded2aee53d..8d7425186680 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -219,7 +219,7 @@ fn main() { } fn run() { - let psess = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]); + let psess = ParseSess::new(); iter_exprs(2, &mut |mut e| { // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, diff --git a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs index 72b5cfb90630..85ee87155a7a 100644 --- a/tests/ui-fulldeps/pprust-parenthesis-insertion.rs +++ b/tests/ui-fulldeps/pprust-parenthesis-insertion.rs @@ -196,7 +196,7 @@ fn main() -> ExitCode { }; rustc_span::create_default_session_globals_then(|| { - let psess = &ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE]); + let psess = &ParseSess::new(); for &source_code in EXPRS { let Some(expr) = parse_expr(psess, source_code) else { diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index 241d9e7efbd7..bd92cc6218f1 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -64,7 +64,6 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path output_dir: None, ice_file: None, file_loader: None, - locale_resources: Vec::new(), lint_caps: Default::default(), psess_created: None, hash_untracked_state: None, @@ -72,7 +71,6 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path override_queries: None, extra_symbols: Vec::new(), make_codegen_backend: None, - registry: rustc_driver::diagnostics_registry(), using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES, }; diff --git a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr index 15e2cf66f8f8..4a6ca56bf329 100644 --- a/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr +++ b/tests/ui-fulldeps/rustc-dev-remap.only-remap.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf LL | type Result = NotAValidResultType; | ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `VisitorResult` is not implemented for `NotAValidResultType` +help: the nightly-only, unstable trait `VisitorResult` is not implemented for `NotAValidResultType` --> $DIR/rustc-dev-remap.rs:LL:COL | LL | struct NotAValidResultType; @@ -18,6 +18,9 @@ help: the following other types implement trait `VisitorResult` = note: `ControlFlow` note: required by a bound in `rustc_ast::visit::Visitor::Result` --> /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL + ::: /rustc-dev/xyz/compiler/rustc_ast/src/visit.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr index b9276974c465..18dffdb2cf79 100644 --- a/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr +++ b/tests/ui-fulldeps/rustc-dev-remap.remap-unremap.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `NotAValidResultType: VisitorResult` is not satisf LL | type Result = NotAValidResultType; | ^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `VisitorResult` is not implemented for `NotAValidResultType` +help: the nightly-only, unstable trait `VisitorResult` is not implemented for `NotAValidResultType` --> $DIR/rustc-dev-remap.rs:LL:COL | LL | struct NotAValidResultType; @@ -20,8 +20,11 @@ LL | impl VisitorResult for ControlFlow { note: required by a bound in `rustc_ast::visit::Visitor::Result` --> $COMPILER_DIR_REAL/rustc_ast/src/visit.rs:LL:COL | +LL | type Result: VisitorResult = (); + | ^^^^^^^^^^^^^ required by this bound in `Visitor::Result` +... LL | common_visitor_and_walkers!(Visitor<'a>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Visitor::Result` + | ---------------------------------------- in this macro invocation = note: this error originates in the macro `common_visitor_and_walkers` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui-fulldeps/rustc_public/check_abi.rs b/tests/ui-fulldeps/rustc_public/check_abi.rs index 57c8377ea367..8e97b773db56 100644 --- a/tests/ui-fulldeps/rustc_public/check_abi.rs +++ b/tests/ui-fulldeps/rustc_public/check_abi.rs @@ -6,13 +6,12 @@ //@ ignore-remote #![feature(rustc_private)] -#![feature(assert_matches)] #![feature(ascii_char, ascii_char_variants)] -extern crate rustc_hir; -extern crate rustc_middle; extern crate rustc_driver; +extern crate rustc_hir; extern crate rustc_interface; +extern crate rustc_middle; #[macro_use] extern crate rustc_public; @@ -25,7 +24,7 @@ use rustc_public::mir::mono::Instance; use rustc_public::target::MachineInfo; use rustc_public::ty::{AdtDef, RigidTy, Ty, TyKind}; use rustc_public::{CrateDef, CrateItem, CrateItems, ItemKind}; -use std::assert_matches::assert_matches; +use std::assert_matches; use std::collections::HashSet; use std::convert::TryFrom; use std::io::Write; @@ -39,7 +38,7 @@ fn test_stable_mir() -> ControlFlow<()> { let items = rustc_public::all_local_items(); // Test fn_abi - let target_fn = *get_item(&items, (ItemKind::Fn, "fn_abi")).unwrap(); + let target_fn = *get_item(&items, (ItemKind::Fn, "input::fn_abi")).unwrap(); let instance = Instance::try_from(target_fn).unwrap(); let fn_abi = instance.fn_abi().unwrap(); assert_eq!(fn_abi.conv, CallConvention::Rust); @@ -51,11 +50,11 @@ fn test_stable_mir() -> ControlFlow<()> { check_result(&fn_abi.ret); // Test variadic function. - let variadic_fn = *get_item(&items, (ItemKind::Fn, "variadic_fn")).unwrap(); + let variadic_fn = *get_item(&items, (ItemKind::Fn, "input::variadic_fn")).unwrap(); check_variadic(variadic_fn); // Extract function pointers. - let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "fn_ptr_holder")).unwrap(); + let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "input::fn_ptr_holder")).unwrap(); let fn_ptr_holder_instance = Instance::try_from(fn_ptr_holder).unwrap(); let body = fn_ptr_holder_instance.body().unwrap(); let args = body.arg_locals(); diff --git a/tests/ui-fulldeps/rustc_public/check_allocation.rs b/tests/ui-fulldeps/rustc_public/check_allocation.rs index 70e4ee3fe347..8f3b9693382b 100644 --- a/tests/ui-fulldeps/rustc_public/check_allocation.rs +++ b/tests/ui-fulldeps/rustc_public/check_allocation.rs @@ -8,7 +8,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] #![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; @@ -20,7 +19,7 @@ extern crate rustc_interface; extern crate rustc_public; use std::ascii::Char; -use std::assert_matches::assert_matches; +use std::assert_matches; use std::cmp::{max, min}; use std::collections::HashMap; use std::ffi::CStr; @@ -40,11 +39,11 @@ const CRATE_NAME: &str = "input"; fn test_stable_mir() -> ControlFlow<()> { // Find items in the local crate. let items = rustc_public::all_local_items(); - check_foo(*get_item(&items, (ItemKind::Static, "FOO")).unwrap()); - check_bar(*get_item(&items, (ItemKind::Static, "BAR")).unwrap()); - check_len(*get_item(&items, (ItemKind::Static, "LEN")).unwrap()); - check_cstr(*get_item(&items, (ItemKind::Static, "C_STR")).unwrap()); - check_other_consts(*get_item(&items, (ItemKind::Fn, "other_consts")).unwrap()); + check_foo(*get_item(&items, (ItemKind::Static, "input::FOO")).unwrap()); + check_bar(*get_item(&items, (ItemKind::Static, "input::BAR")).unwrap()); + check_len(*get_item(&items, (ItemKind::Static, "input::LEN")).unwrap()); + check_cstr(*get_item(&items, (ItemKind::Static, "input::C_STR")).unwrap()); + check_other_consts(*get_item(&items, (ItemKind::Fn, "input::other_consts")).unwrap()); ControlFlow::Continue(()) } diff --git a/tests/ui-fulldeps/rustc_public/check_assoc_items.rs b/tests/ui-fulldeps/rustc_public/check_assoc_items.rs index 1557991f8cab..ee0efd083588 100644 --- a/tests/ui-fulldeps/rustc_public/check_assoc_items.rs +++ b/tests/ui-fulldeps/rustc_public/check_assoc_items.rs @@ -8,7 +8,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -77,7 +76,7 @@ fn test_assoc_items() -> ControlFlow<()> { /// Note that order doesn't matter. fn check_items(items: &[T], expected: &[&str]) { let expected: HashSet<_> = expected.iter().map(|s| s.to_string()).collect(); - let item_names: HashSet<_> = items.iter().map(|item| item.name()).collect(); + let item_names: HashSet<_> = items.iter().map(|item| item.trimmed_name()).collect(); assert_eq!(item_names, expected); } diff --git a/tests/ui-fulldeps/rustc_public/check_attribute.rs b/tests/ui-fulldeps/rustc_public/check_attribute.rs index 0c34ac4dfe95..393ff4c63c5a 100644 --- a/tests/ui-fulldeps/rustc_public/check_attribute.rs +++ b/tests/ui-fulldeps/rustc_public/check_attribute.rs @@ -38,16 +38,13 @@ fn test_tool(items: &CrateItems) { assert_eq!(rustfmt_attrs[0].as_str(), "#[rustfmt::skip]\n"); let clippy_fn = *get_item(&items, "complex_fn").unwrap(); - let clippy_attrs = clippy_fn.tool_attrs(&["clippy".to_string(), - "cyclomatic_complexity".to_string()]); + let clippy_attrs = + clippy_fn.tool_attrs(&["clippy".to_string(), "cyclomatic_complexity".to_string()]); assert_eq!(clippy_attrs[0].as_str(), "#[clippy::cyclomatic_complexity = \"100\"]\n"); } -fn get_item<'a>( - items: &'a CrateItems, - name: &str, -) -> Option<&'a rustc_public::CrateItem> { - items.iter().find(|crate_item| crate_item.name() == name) +fn get_item<'a>(items: &'a CrateItems, name: &str) -> Option<&'a rustc_public::CrateItem> { + items.iter().find(|crate_item| crate_item.trimmed_name() == name) } /// This test will generate and analyze a dummy crate using the stable mir. diff --git a/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs b/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs index 725b538b0fe5..f988452fd52b 100644 --- a/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs +++ b/tests/ui-fulldeps/rustc_public/check_coroutine_body.rs @@ -7,7 +7,6 @@ //@ edition: 2024 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -29,11 +28,7 @@ fn test_coroutine_body() -> ControlFlow<()> { if let Some(body) = crate_items.iter().find_map(|item| { let item_ty = item.ty(); if let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &item_ty.kind() { - if def.0.name() == "gbc::{closure#0}".to_string() { - def.body() - } else { - None - } + if def.0.trimmed_name() == "gbc::{closure#0}".to_string() { def.body() } else { None } } else { None } @@ -51,26 +46,23 @@ fn check_coroutine_body(body: Body) { let local_3 = &body.locals()[3].ty; let local_4 = &body.locals()[4].ty; - let TyKind::RigidTy(RigidTy::Adt(def, ..)) = &ret_ty.kind() - else { + let TyKind::RigidTy(RigidTy::Adt(def, ..)) = &ret_ty.kind() else { panic!("Expected RigidTy::Adt, got: {:#?}", ret_ty); }; assert_eq!("std::task::Poll", def.0.name()); - let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_3.kind() - else { + let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_3.kind() else { panic!("Expected RigidTy::Coroutine, got: {:#?}", local_3); }; - assert_eq!("gbc::{closure#0}::{closure#0}", def.0.name()); + assert_eq!("crate_coroutine_body::gbc::{closure#0}::{closure#0}", def.0.name()); - let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_4.kind() - else { + let TyKind::RigidTy(RigidTy::Coroutine(def, ..)) = &local_4.kind() else { panic!("Expected RigidTy::Coroutine, got: {:#?}", local_4); }; - assert_eq!("gbc::{closure#0}::{closure#0}", def.0.name()); + assert_eq!("crate_coroutine_body::gbc::{closure#0}::{closure#0}", def.0.name()); } fn main() { diff --git a/tests/ui-fulldeps/rustc_public/check_crate_defs.rs b/tests/ui-fulldeps/rustc_public/check_crate_defs.rs index 3ca8b66e58dc..2b6a2ff8199c 100644 --- a/tests/ui-fulldeps/rustc_public/check_crate_defs.rs +++ b/tests/ui-fulldeps/rustc_public/check_crate_defs.rs @@ -6,7 +6,6 @@ //@ ignore-remote #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_hir; extern crate rustc_middle; @@ -27,17 +26,20 @@ const CRATE_NAME: &str = "crate_defs"; fn test_stable_mir() -> ControlFlow<()> { // Find items in the local crate. let local = rustc_public::local_crate(); - check_items(&local.statics(), &["PRIVATE_STATIC", "dummy::PUBLIC_STATIC"]); + check_items( + &local.statics(), + &["crate_defs::PRIVATE_STATIC", "crate_defs::dummy::PUBLIC_STATIC"], + ); check_items( &local.fn_defs(), &[ - "top_level", - "dummy::public_fn", - "dummy::private_fn", - "dummy::PrivateStruct::new", - "::drop", - "DummyTrait::method", - "::method", + "crate_defs::top_level", + "crate_defs::dummy::public_fn", + "crate_defs::dummy::private_fn", + "crate_defs::dummy::PrivateStruct::new", + "::drop", + "crate_defs::DummyTrait::method", + "::method", ], ); diff --git a/tests/ui-fulldeps/rustc_public/check_def_parent.rs b/tests/ui-fulldeps/rustc_public/check_def_parent.rs index 192ad471de33..7f633a627b19 100644 --- a/tests/ui-fulldeps/rustc_public/check_def_parent.rs +++ b/tests/ui-fulldeps/rustc_public/check_def_parent.rs @@ -47,44 +47,47 @@ fn test_stable_mir() -> ControlFlow<()> { let krate = rustc_public::local_crate(); for it in rustc_public::all_local_items() { match &*it.0.name() { - "wrapper_mod::CONST_ITEM" => { + "input::wrapper_mod::CONST_ITEM" => { set_once(&mut const_item, it.0); } - "wrapper_mod::STATIC_ITEM" => { + "input::wrapper_mod::STATIC_ITEM" => { set_once(&mut static_item, it.0); } - "::trait_method" => { + "::trait_method" => { set_once(&mut trait_method, it.0); } - "::trait_method::trait_method_helper" => { + "::trait_method::trait_method_helper" => + { set_once(&mut trait_method_helper, it.0); } - "wrapper_mod::MyStruct::inherent_method" => { + "input::wrapper_mod::MyStruct::inherent_method" => { set_once(&mut inherent_method, it.0); } - "wrapper_mod::MyStruct::inherent_method::inherent_method_helper" => { + "input::wrapper_mod::MyStruct::inherent_method::inherent_method_helper" => { set_once(&mut inherent_method_helper, it.0); } - "main" => { + "input::main" => { set_once(&mut main, it.0); } - "wrapper_mod::MyStruct" => { + "input::wrapper_mod::MyStruct" => { set_once(&mut mystruct_ctor, it.0); mystruct_ctor_ty = Some(it.ty()); } - _ => (), + name => panic!("Unexpected item: `{name}`"), } } for it in krate.trait_decls() { match &*it.0.name() { - "wrapper_mod::MyTrait" => set_once(&mut trait_decl, it.0), + "input::wrapper_mod::MyTrait" => set_once(&mut trait_decl, it.0), _ => (), } } for it in krate.trait_impls() { match &*it.0.name() { - "" => set_once(&mut trait_impl, it.0), - _ => (), + "" => { + set_once(&mut trait_impl, it.0) + } + name => panic!("Unexpected trait impl: `{name}`"), } } @@ -106,9 +109,10 @@ fn test_stable_mir() -> ControlFlow<()> { let inherent_impl = inherent_method.parent().unwrap(); let wrapper_mod = const_item.parent().unwrap(); let crate_root = wrapper_mod.parent().unwrap(); - assert_eq!(&*wrapper_mod.name(), "wrapper_mod"); + assert_eq!(&*wrapper_mod.name(), "input::wrapper_mod"); // Check that each def-id has the correct parent + assert_eq!(crate_root.name(), "input"); assert_eq!(crate_root.parent(), None); assert_eq!(inherent_impl.parent(), Some(wrapper_mod)); assert_eq!(const_item.parent(), Some(wrapper_mod)); diff --git a/tests/ui-fulldeps/rustc_public/check_def_ty.rs b/tests/ui-fulldeps/rustc_public/check_def_ty.rs index 4a45bb6daa5f..19ea731834b7 100644 --- a/tests/ui-fulldeps/rustc_public/check_def_ty.rs +++ b/tests/ui-fulldeps/rustc_public/check_def_ty.rs @@ -8,16 +8,18 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_public; +extern crate rustc_public_bridge; -use rustc_public::ty::{Ty, ForeignItemKind}; +use rustc_public::ty::VariantIdx; +use rustc_public::ty::{ForeignItemKind, RigidTy, Ty}; use rustc_public::*; +use rustc_public_bridge::IndexedVal; use std::io::Write; use std::ops::ControlFlow; @@ -29,11 +31,19 @@ fn test_def_tys() -> ControlFlow<()> { for item in &items { // Type from crate items. let ty = item.ty(); - match item.name().as_str() { + match item.trimmed_name().as_str() { "STATIC_STR" => assert!(ty.kind().is_ref()), "CONST_U32" => assert!(ty.kind().is_integral()), - "main" => { check_fn_def(ty) } - _ => unreachable!("Unexpected item: `{item:?}`") + "NONE" => { + let RigidTy::Adt(adt, _) = *ty.kind().rigid().unwrap() else { panic!() }; + // Definition names include the entire path. + assert_eq!(adt.name(), "std::option::Option"); + // Variant name only includes the actual variant name. + // I know, probably not the best name schema. o.O + assert_eq!(adt.variant(VariantIdx::to_val(0)).unwrap().name(), "None"); + } + "main" => check_fn_def(ty), + _ => unreachable!("Unexpected item: `{item:?}`"), } } @@ -42,7 +52,7 @@ fn test_def_tys() -> ControlFlow<()> { // Type from foreign items. let ty = item.ty(); let item_kind = item.kind(); - let name = item.name(); + let name = item.trimmed_name(); match item_kind { ForeignItemKind::Fn(fn_def) => { assert_eq!(&name, "extern_fn"); @@ -54,7 +64,7 @@ fn test_def_tys() -> ControlFlow<()> { assert_eq!(ty, def.ty()); assert!(ty.kind().is_integral()) } - _ => unreachable!("Unexpected kind: {item_kind:?}") + _ => unreachable!("Unexpected kind: {item_kind:?}"), }; } @@ -92,6 +102,7 @@ fn generate_input(path: &str) -> std::io::Result<()> { r#" static STATIC_STR: &str = "foo"; const CONST_U32: u32 = 0u32; + static NONE: Option = Option::None; fn main() {{ let _c = core::char::from_u32(99); diff --git a/tests/ui-fulldeps/rustc_public/check_defs.rs b/tests/ui-fulldeps/rustc_public/check_defs.rs index 0c45859a132a..f3e27cdeb604 100644 --- a/tests/ui-fulldeps/rustc_public/check_defs.rs +++ b/tests/ui-fulldeps/rustc_public/check_defs.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -15,11 +14,11 @@ extern crate rustc_driver; extern crate rustc_interface; extern crate rustc_public; -use std::assert_matches::assert_matches; -use mir::{mono::Instance, TerminatorKind::*}; +use mir::{TerminatorKind::*, mono::Instance}; use rustc_public::mir::mono::InstanceKind; -use rustc_public::ty::{RigidTy, TyKind, Ty, UintTy}; +use rustc_public::ty::{RigidTy, Ty, TyKind, UintTy}; use rustc_public::*; +use std::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -29,7 +28,7 @@ const CRATE_NAME: &str = "input"; fn test_stable_mir() -> ControlFlow<()> { let entry = rustc_public::entry_fn().unwrap(); let main_fn = Instance::try_from(entry).unwrap(); - assert_eq!(main_fn.name(), "main"); + assert_eq!(main_fn.name(), "input::main"); assert_eq!(main_fn.trimmed_name(), "main"); let instances = get_instances(main_fn.body().unwrap()); @@ -65,10 +64,8 @@ fn test_fn(instance: Instance, expected_trimmed: &str, expected_qualified: &str, fn extract_elem_ty(ty: Ty) -> Ty { match ty.kind() { - TyKind::RigidTy(RigidTy::Adt(_, args)) => { - *args.0[0].expect_ty() - } - _ => unreachable!("Expected Vec ADT, but found: {ty:?}") + TyKind::RigidTy(RigidTy::Adt(_, args)) => *args.0[0].expect_ty(), + _ => unreachable!("Expected Vec ADT, but found: {ty:?}"), } } @@ -89,19 +86,19 @@ fn test_vec_new(instance: mir::mono::Instance) { /// Inspect the instance body fn get_instances(body: mir::Body) -> Vec { - body.blocks.iter().filter_map(|bb| { - match &bb.terminator.kind { + body.blocks + .iter() + .filter_map(|bb| match &bb.terminator.kind { Call { func, .. } => { - let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else { unreachable! - () }; + let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else { + unreachable!() + }; let RigidTy::FnDef(def, args) = ty else { unreachable!() }; Instance::resolve(def, &args).ok() } - _ => { - None - } - } - }).collect::>() + _ => None, + }) + .collect::>() } /// This test will generate and analyze a dummy crate using the stable mir. diff --git a/tests/ui-fulldeps/rustc_public/check_foreign.rs b/tests/ui-fulldeps/rustc_public/check_foreign.rs index 78b62594c618..4670fd409b8f 100644 --- a/tests/ui-fulldeps/rustc_public/check_foreign.rs +++ b/tests/ui-fulldeps/rustc_public/check_foreign.rs @@ -7,20 +7,19 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; extern crate rustc_driver; extern crate rustc_interface; -extern crate rustc_span; extern crate rustc_public; +extern crate rustc_span; use rustc_public::{ ty::{Abi, ForeignItemKind}, *, }; -use std::assert_matches::assert_matches; +use std::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -40,7 +39,7 @@ fn test_foreign() -> ControlFlow<()> { assert_eq!(c_items.len(), 3); for item in c_items { let kind = item.kind(); - match item.name().as_str() { + match item.trimmed_name().as_str() { "foo" => assert_matches!(kind, ForeignItemKind::Fn(..)), "bar" => assert_matches!(kind, ForeignItemKind::Static(..)), "Baz" => assert_matches!(kind, ForeignItemKind::Type(..)), diff --git a/tests/ui-fulldeps/rustc_public/check_instance.rs b/tests/ui-fulldeps/rustc_public/check_instance.rs index fd7523963fa9..defea9d2f54b 100644 --- a/tests/ui-fulldeps/rustc_public/check_instance.rs +++ b/tests/ui-fulldeps/rustc_public/check_instance.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_intrinsics.rs b/tests/ui-fulldeps/rustc_public/check_intrinsics.rs index f722f0bbd718..0cbb9659182a 100644 --- a/tests/ui-fulldeps/rustc_public/check_intrinsics.rs +++ b/tests/ui-fulldeps/rustc_public/check_intrinsics.rs @@ -10,7 +10,6 @@ //@ ignore-remote #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; extern crate rustc_hir; @@ -24,7 +23,7 @@ use rustc_public::mir::mono::{Instance, InstanceKind}; use rustc_public::mir::visit::{Location, MirVisitor}; use rustc_public::mir::{LocalDecl, Terminator, TerminatorKind}; use rustc_public::ty::{FnDef, GenericArgs, RigidTy, TyKind}; -use std::assert_matches::assert_matches; +use std::assert_matches; use std::convert::TryFrom; use std::io::Write; use std::ops::ControlFlow; diff --git a/tests/ui-fulldeps/rustc_public/check_item_kind.rs b/tests/ui-fulldeps/rustc_public/check_item_kind.rs index b759628f1a42..b75ac70d86e3 100644 --- a/tests/ui-fulldeps/rustc_public/check_item_kind.rs +++ b/tests/ui-fulldeps/rustc_public/check_item_kind.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -27,7 +26,7 @@ fn test_item_kind() -> ControlFlow<()> { assert_eq!(items.len(), 4); // Constructor item. for item in items { - let expected_kind = match item.name().as_str() { + let expected_kind = match item.trimmed_name().as_str() { "Dummy" => ItemKind::Ctor(CtorKind::Fn), "dummy" => ItemKind::Fn, "unit" => ItemKind::Fn, diff --git a/tests/ui-fulldeps/rustc_public/check_trait_queries.rs b/tests/ui-fulldeps/rustc_public/check_trait_queries.rs index 0dd13044fcce..44b7275a3df6 100644 --- a/tests/ui-fulldeps/rustc_public/check_trait_queries.rs +++ b/tests/ui-fulldeps/rustc_public/check_trait_queries.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -28,19 +27,20 @@ fn test_traits() -> ControlFlow<()> { let local_crate = rustc_public::local_crate(); let local_traits = local_crate.trait_decls(); assert_eq!(local_traits.len(), 1, "Expected `Max` trait, but found {:?}", local_traits); - assert_eq!(&local_traits[0].name(), "Max"); + assert_eq!(&local_traits[0].trimmed_name(), "Max"); let local_impls = local_crate.trait_impls(); - let impl_names = local_impls.iter().map(|trait_impl| trait_impl.name()).collect::>(); + let impl_names = + local_impls.iter().map(|trait_impl| trait_impl.trimmed_name()).collect::>(); assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ""); - assert_impl(&impl_names, ">"); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ""); + assert_impl(&impl_names, ">"); assert_impl(&impl_names, ""); - assert_impl(&impl_names, " for u64>"); + assert_impl(&impl_names, " for u64>"); let all_traits = rustc_public::all_trait_decls(); assert!(all_traits.len() > local_traits.len()); diff --git a/tests/ui-fulldeps/rustc_public/check_transform.rs b/tests/ui-fulldeps/rustc_public/check_transform.rs index b30d98c3b26f..f8aa40e47446 100644 --- a/tests/ui-fulldeps/rustc_public/check_transform.rs +++ b/tests/ui-fulldeps/rustc_public/check_transform.rs @@ -6,7 +6,6 @@ //@ ignore-remote #![feature(rustc_private)] -#![feature(assert_matches)] #![feature(ascii_char, ascii_char_variants)] extern crate rustc_hir; @@ -34,7 +33,7 @@ fn test_transform() -> ControlFlow<()> { let items = rustc_public::all_local_items(); // Test fn_abi - let target_fn = *get_item(&items, (ItemKind::Fn, "dummy")).unwrap(); + let target_fn = *get_item(&items, (ItemKind::Fn, "input::dummy")).unwrap(); let instance = Instance::try_from(target_fn).unwrap(); let body = instance.body().unwrap(); check_msg(&body, "oops"); @@ -69,6 +68,7 @@ fn check_msg(body: &Body, expected: &str) { }) .unwrap() } + Operand::RuntimeChecks(_) => panic!("unexpected runtime checks"), }; let ConstantKind::Allocated(alloc) = msg_const.const_.kind() else { unreachable!() diff --git a/tests/ui-fulldeps/rustc_public/check_ty_fold.rs b/tests/ui-fulldeps/rustc_public/check_ty_fold.rs index 93cd30493440..9ac7f14570e5 100644 --- a/tests/ui-fulldeps/rustc_public/check_ty_fold.rs +++ b/tests/ui-fulldeps/rustc_public/check_ty_fold.rs @@ -8,7 +8,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/check_variant.rs b/tests/ui-fulldeps/rustc_public/check_variant.rs index 9ed16f2357c0..54ae8b8f83b9 100644 --- a/tests/ui-fulldeps/rustc_public/check_variant.rs +++ b/tests/ui-fulldeps/rustc_public/check_variant.rs @@ -8,7 +8,6 @@ //@ edition: 2024 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -97,7 +96,7 @@ fn check_adt_poly2() { } fn get_fn(name: &str) -> CrateItem { - rustc_public::all_local_items().into_iter().find(|it| it.name().eq(name)).unwrap() + rustc_public::all_local_items().into_iter().find(|it| it.trimmed_name().eq(name)).unwrap() } fn check_statement_is_aggregate_assign( diff --git a/tests/ui-fulldeps/rustc_public/closure-generic-body.rs b/tests/ui-fulldeps/rustc_public/closure-generic-body.rs index e5f910fbda11..a328bc396c54 100644 --- a/tests/ui-fulldeps/rustc_public/closure-generic-body.rs +++ b/tests/ui-fulldeps/rustc_public/closure-generic-body.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -52,7 +51,7 @@ fn check_incr_closure_body(body: Body) { panic!("expected FnDef"); }; - assert_eq!(def_id.name(), "id"); + assert_eq!(def_id.trimmed_name(), "id"); } fn main() { diff --git a/tests/ui-fulldeps/rustc_public/closure_body.rs b/tests/ui-fulldeps/rustc_public/closure_body.rs index f5f9f23ad126..880d7dde34b6 100644 --- a/tests/ui-fulldeps/rustc_public/closure_body.rs +++ b/tests/ui-fulldeps/rustc_public/closure_body.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; @@ -52,7 +51,7 @@ fn check_incr_closure_body(body: Body) { panic!("expected FnDef"); }; - assert_eq!(def_id.name(), "incr"); + assert_eq!(def_id.name(), "crate_closure_body::incr"); } fn main() { diff --git a/tests/ui-fulldeps/rustc_public/compilation-result.rs b/tests/ui-fulldeps/rustc_public/compilation-result.rs index d33e602e8191..351ca2c8295f 100644 --- a/tests/ui-fulldeps/rustc_public/compilation-result.rs +++ b/tests/ui-fulldeps/rustc_public/compilation-result.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/rustc_public/crate-info.rs b/tests/ui-fulldeps/rustc_public/crate-info.rs index 19082d7394ab..3729aa7609b5 100644 --- a/tests/ui-fulldeps/rustc_public/crate-info.rs +++ b/tests/ui-fulldeps/rustc_public/crate-info.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_hir; extern crate rustc_middle; @@ -22,7 +21,7 @@ use rustc_public::ItemKind; use rustc_public::crate_def::CrateDef; use rustc_public::mir::mono::Instance; use rustc_public::ty::{RigidTy, TyKind}; -use std::assert_matches::assert_matches; +use std::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -38,12 +37,12 @@ fn test_stable_mir() -> ControlFlow<()> { // Find items in the local crate. let items = rustc_public::all_local_items(); - assert!(get_item(&items, (DefKind::Fn, "foo::bar")).is_some()); + assert!(get_item(&items, (DefKind::Fn, "input::foo::bar")).is_some()); // Find the `std` crate and assert that there is only one of it. assert!(rustc_public::find_crates("std").len() == 1); - let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap(); + let bar = get_item(&items, (DefKind::Fn, "input::bar")).unwrap(); let body = bar.expect_body(); assert_eq!(body.locals().len(), 2); assert_eq!(body.blocks.len(), 1); @@ -58,7 +57,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap(); + let foo_bar = get_item(&items, (DefKind::Fn, "input::foo_bar")).unwrap(); let body = foo_bar.expect_body(); assert_eq!(body.locals().len(), 5); assert_eq!(body.blocks.len(), 4); @@ -68,7 +67,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let types = get_item(&items, (DefKind::Fn, "types")).unwrap(); + let types = get_item(&items, (DefKind::Fn, "input::types")).unwrap(); let body = types.expect_body(); assert_eq!(body.locals().len(), 6); assert_matches!( @@ -85,15 +84,15 @@ fn test_stable_mir() -> ControlFlow<()> { ); assert_matches!( body.locals()[3].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Int(rustc_public::ty::IntTy::I32) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Int( + rustc_public::ty::IntTy::I32 + )) ); assert_matches!( body.locals()[4].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Uint(rustc_public::ty::UintTy::U64) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Uint( + rustc_public::ty::UintTy::U64 + )) ); assert_matches!( body.locals()[5].ty.kind(), @@ -102,7 +101,7 @@ fn test_stable_mir() -> ControlFlow<()> { )) ); - let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap(); + let drop = get_item(&items, (DefKind::Fn, "input::drop")).unwrap(); let body = drop.expect_body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -111,7 +110,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap(); + let assert = get_item(&items, (DefKind::Fn, "input::assert")).unwrap(); let body = assert.expect_body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -120,7 +119,7 @@ fn test_stable_mir() -> ControlFlow<()> { other => panic!("{other:?}"), } - let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap(); + let monomorphic = get_item(&items, (DefKind::Fn, "input::monomorphic")).unwrap(); let instance = Instance::try_from(monomorphic.clone()).unwrap(); for block in instance.body().unwrap().blocks { match &block.terminator.kind { @@ -140,11 +139,11 @@ fn test_stable_mir() -> ControlFlow<()> { } } - let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap(); + let foo_const = get_item(&items, (DefKind::Const, "input::FOO")).unwrap(); // Ensure we don't panic trying to get the body of a constant. foo_const.expect_body(); - let locals_fn = get_item(&items, (DefKind::Fn, "locals")).unwrap(); + let locals_fn = get_item(&items, (DefKind::Fn, "input::locals")).unwrap(); let body = locals_fn.expect_body(); assert_eq!(body.locals().len(), 4); assert_matches!( @@ -154,15 +153,15 @@ fn test_stable_mir() -> ControlFlow<()> { assert_eq!(body.arg_locals().len(), 2); assert_matches!( body.arg_locals()[0].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Int(rustc_public::ty::IntTy::I32) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Int( + rustc_public::ty::IntTy::I32 + )) ); assert_matches!( body.arg_locals()[1].ty.kind(), - rustc_public::ty::TyKind::RigidTy( - rustc_public::ty::RigidTy::Uint(rustc_public::ty::UintTy::U64) - ) + rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Uint( + rustc_public::ty::UintTy::U64 + )) ); assert_eq!(body.inner_locals().len(), 1); // If conditions have an extra inner local to hold their results diff --git a/tests/ui-fulldeps/rustc_public/projections.rs b/tests/ui-fulldeps/rustc_public/projections.rs index e0213b4253c7..e864bb9648db 100644 --- a/tests/ui-fulldeps/rustc_public/projections.rs +++ b/tests/ui-fulldeps/rustc_public/projections.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_hir; extern crate rustc_middle; @@ -21,7 +20,7 @@ use rustc_public::ItemKind; use rustc_public::crate_def::CrateDef; use rustc_public::mir::{ProjectionElem, Rvalue, StatementKind}; use rustc_public::ty::{RigidTy, TyKind, UintTy}; -use std::assert_matches::assert_matches; +use std::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -136,7 +135,9 @@ fn get_item<'a>( items: &'a rustc_public::CrateItems, item: (ItemKind, &str), ) -> Option<&'a rustc_public::CrateItem> { - items.iter().find(|crate_item| crate_item.kind() == item.0 && crate_item.name() == item.1) + items + .iter() + .find(|crate_item| crate_item.kind() == item.0 && crate_item.trimmed_name() == item.1) } /// This test will generate and analyze a dummy crate using the stable mir. diff --git a/tests/ui-fulldeps/rustc_public/smir_internal.rs b/tests/ui-fulldeps/rustc_public/smir_internal.rs index b74bdfe4eb19..98335da19dbd 100644 --- a/tests/ui-fulldeps/rustc_public/smir_internal.rs +++ b/tests/ui-fulldeps/rustc_public/smir_internal.rs @@ -8,7 +8,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_driver; extern crate rustc_interface; diff --git a/tests/ui-fulldeps/rustc_public/smir_serde.rs b/tests/ui-fulldeps/rustc_public/smir_serde.rs index 972bc5efe206..6a345023de17 100644 --- a/tests/ui-fulldeps/rustc_public/smir_serde.rs +++ b/tests/ui-fulldeps/rustc_public/smir_serde.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_driver; diff --git a/tests/ui-fulldeps/rustc_public/smir_visitor.rs b/tests/ui-fulldeps/rustc_public/smir_visitor.rs index 9438f46a59b5..1ea2ab6f560f 100644 --- a/tests/ui-fulldeps/rustc_public/smir_visitor.rs +++ b/tests/ui-fulldeps/rustc_public/smir_visitor.rs @@ -7,7 +7,6 @@ //@ edition: 2021 #![feature(rustc_private)] -#![feature(assert_matches)] extern crate rustc_middle; diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs index 37f78a7777c4..c1146de0fef1 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.rs @@ -14,21 +14,19 @@ #![crate_type = "lib"] extern crate rustc_errors; -extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; +extern crate core; -use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; +use rustc_errors::{Applicability, DiagMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - struct NotIntoDiagArg; #[derive(Diagnostic)] -#[diag(no_crate_example)] +#[diag("example message")] struct Test { #[primary_span] span: Span, @@ -38,7 +36,7 @@ struct Test { } #[derive(Subdiagnostic)] -#[label(no_crate_example)] +#[label("example message")] struct SubTest { #[primary_span] span: Span, diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr index 8b6c4b181c0f..2d90b2a96b01 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-doc-comment-field.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive-doc-comment-field.rs:36:10 + --> $DIR/diagnostic-derive-doc-comment-field.rs:34:10 | LL | #[derive(Diagnostic)] | ---------- required by a bound introduced by this call @@ -7,18 +7,21 @@ LL | #[derive(Diagnostic)] LL | arg: NotIntoDiagArg, | ^^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` - --> $DIR/diagnostic-derive-doc-comment-field.rs:28:1 +help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` + --> $DIR/diagnostic-derive-doc-comment-field.rs:26:1 | LL | struct NotIntoDiagArg; | ^^^^^^^^^^^^^^^^^^^^^ = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `NotIntoDiagArg: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive-doc-comment-field.rs:46:10 + --> $DIR/diagnostic-derive-doc-comment-field.rs:44:10 | LL | #[derive(Subdiagnostic)] | ------------- required by a bound introduced by this call @@ -26,14 +29,17 @@ LL | #[derive(Subdiagnostic)] LL | arg: NotIntoDiagArg, | ^^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` - --> $DIR/diagnostic-derive-doc-comment-field.rs:28:1 +help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `NotIntoDiagArg` + --> $DIR/diagnostic-derive-doc-comment-field.rs:26:1 | LL | struct NotIntoDiagArg; | ^^^^^^^^^^^^^^^^^^^^^ = help: normalized in stderr note: required by a bound in `Diag::<'a, G>::arg` --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs new file mode 100644 index 000000000000..759a9412f769 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.rs @@ -0,0 +1,784 @@ +//@ check-fail +// Tests error conditions for specifying diagnostics using #[derive(Diagnostic)] +// This test specifically tests diagnostic derives involving the inline fluent syntax. + +//@ normalize-stderr: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" +//@ normalize-stderr: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" + +// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, +// changing the output of this test. Since Diagnostic is strictly internal to the compiler +// the test is just ignored on stable and beta: +//@ ignore-stage1 +//@ ignore-beta +//@ ignore-stable + +#![feature(rustc_private)] +#![crate_type = "lib"] + +extern crate rustc_span; +use rustc_span::symbol::Ident; +use rustc_span::Span; + +extern crate rustc_macros; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; + +extern crate rustc_middle; +use rustc_middle::ty::Ty; + +extern crate rustc_errors; +use rustc_errors::{Applicability, DiagMessage, ErrCode, MultiSpan}; + +extern crate rustc_session; + +extern crate core; + +// E0123 and E0456 are no longer used, so we define our own constants here just for this test. +const E0123: ErrCode = ErrCode::from_u32(0123); +const E0456: ErrCode = ErrCode::from_u32(0456); + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct Hello {} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +//~^ ERROR unsupported type attribute for diagnostic derive enum +enum DiagnosticOnEnum { + Foo, + //~^ ERROR diagnostic message not specified + Bar, + //~^ ERROR diagnostic message not specified +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[diag = "E0123"] +//~^ ERROR expected parentheses: #[diag(...)] +struct WrongStructAttrStyle {} + +#[derive(Diagnostic)] +#[nonsense("this is an example message", code = E0123)] +//~^ ERROR `#[nonsense(...)]` is not a valid attribute +//~^^ ERROR diagnostic message not specified +//~^^^ ERROR cannot find attribute `nonsense` in this scope +struct InvalidStructAttr {} + +#[derive(Diagnostic)] +#[diag(code = E0123)] +//~^ ERROR diagnostic message not specified +struct InvalidLitNestedAttr {} + +#[derive(Diagnostic)] +#[diag(nonsense("foo"), code = E0123, slug = "foo")] +//~^ ERROR derive(Diagnostic): diagnostic message not specified +struct InvalidNestedStructAttr1 {} + +#[derive(Diagnostic)] +#[diag(nonsense = "...", code = E0123, slug = "foo")] +//~^ ERROR diagnostic message not specified +struct InvalidNestedStructAttr2 {} + +#[derive(Diagnostic)] +#[diag(nonsense = 4, code = E0123, slug = "foo")] +//~^ ERROR diagnostic message not specified +struct InvalidNestedStructAttr3 {} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123, slug = "foo")] +//~^ ERROR unknown argument +struct InvalidNestedStructAttr4 {} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct WrongPlaceField { + #[suggestion = "bar"] + //~^ ERROR `#[suggestion = ...]` is not a valid attribute + sp: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[diag("this is an example message", code = E0456)] +//~^ ERROR specified multiple times +struct DiagSpecifiedTwice {} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123, code = E0456)] +//~^ ERROR specified multiple times +struct CodeSpecifiedTwice {} + +#[derive(Diagnostic)] +#[diag("this is an example message", no_crate::example, code = E0123)] +//~^ ERROR diagnostic message must be the first argument +struct SlugSpecifiedTwice {} + +#[derive(Diagnostic)] +struct KindNotProvided {} //~ ERROR diagnostic message not specified + +#[derive(Diagnostic)] +#[diag(code = E0123)] +//~^ ERROR diagnostic message not specified +struct SlugNotProvided {} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct CodeNotProvided {} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct MessageWrongType { + #[primary_span] + //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` + foo: String, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct InvalidPathFieldAttr { + #[nonsense] + //~^ ERROR `#[nonsense]` is not a valid attribute + //~| ERROR cannot find attribute `nonsense` in this scope + foo: String, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ErrorWithField { + name: String, + #[label("with a label")] + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ErrorWithMessageAppliedToField { + #[label("with a label")] + //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + name: String, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ErrorWithNonexistentField { + #[suggestion("with a suggestion", code = "{name}")] + //~^ ERROR `name` doesn't refer to a field on this type + suggestion: (Span, Applicability), +} + +#[derive(Diagnostic)] +//~^ ERROR invalid format string: expected `}` +#[diag("this is an example message", code = E0123)] +struct ErrorMissingClosingBrace { + #[suggestion("with a suggestion", code = "{name")] + suggestion: (Span, Applicability), + name: String, + val: usize, +} + +#[derive(Diagnostic)] +//~^ ERROR invalid format string: unmatched `}` +#[diag("this is an example message", code = E0123)] +struct ErrorMissingOpeningBrace { + #[suggestion("with a suggestion", code = "name}")] + suggestion: (Span, Applicability), + name: String, + val: usize, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct LabelOnSpan { + #[label("with a label")] + sp: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct LabelOnNonSpan { + #[label("with a label")] + //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + id: u32, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct Suggest { + #[suggestion("with a suggestion", code = "This is the suggested code")] + #[suggestion("with a suggestion", code = "This is the suggested code", style = "normal")] + #[suggestion("with a suggestion", code = "This is the suggested code", style = "short")] + #[suggestion("with a suggestion", code = "This is the suggested code", style = "hidden")] + #[suggestion("with a suggestion", code = "This is the suggested code", style = "verbose")] + suggestion: (Span, Applicability), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithoutCode { + #[suggestion("with a suggestion")] + //~^ ERROR suggestion without `code = "..."` + suggestion: (Span, Applicability), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithBadKey { + #[suggestion("with a suggestion", nonsense = "bar")] + //~^ ERROR invalid nested attribute + //~| ERROR suggestion without `code = "..."` + suggestion: (Span, Applicability), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithShorthandMsg { + #[suggestion("with a suggestion", msg = "bar")] + //~^ ERROR invalid nested attribute + //~| ERROR suggestion without `code = "..."` + suggestion: (Span, Applicability), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithoutMsg { + #[suggestion("with a suggestion", code = "bar")] + suggestion: (Span, Applicability), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithTypesSwapped { + #[suggestion("with a suggestion", code = "This is suggested code")] + suggestion: (Applicability, Span), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithWrongTypeApplicabilityOnly { + #[suggestion("with a suggestion", code = "This is suggested code")] + //~^ ERROR wrong field type for suggestion + suggestion: Applicability, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithSpanOnly { + #[suggestion("with a suggestion", code = "This is suggested code")] + suggestion: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithDuplicateSpanAndApplicability { + #[suggestion("with a suggestion", code = "This is suggested code")] + suggestion: (Span, Span, Applicability), + //~^ ERROR specified multiple times +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct SuggestWithDuplicateApplicabilityAndSpan { + #[suggestion("with a suggestion", code = "This is suggested code")] + suggestion: (Applicability, Applicability, Span), + //~^ ERROR specified multiple times +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct WrongKindOfAnnotation { + #[label = "bar"] + //~^ ERROR `#[label = ...]` is not a valid attribute + z: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct OptionsInErrors { + #[label("with a label")] + label: Option, + #[suggestion("with a suggestion", code = "...")] + opt_sugg: Option<(Span, Applicability)>, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct MoveOutOfBorrowError<'tcx> { + name: Ident, + ty: Ty<'tcx>, + #[primary_span] + #[label("with a label")] + span: Span, + #[label("with a label")] + other_span: Span, + #[suggestion("with a suggestion", code = "{name}.clone()")] + opt_sugg: Option<(Span, Applicability)>, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ErrorWithLifetime<'a> { + #[label("with a label")] + span: Span, + name: &'a str, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ArgFieldWithoutSkip { + #[primary_span] + span: Span, + other: Hello, + //~^ ERROR the trait bound `Hello: IntoDiagArg` is not satisfied +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ArgFieldWithSkip { + #[primary_span] + span: Span, + // `Hello` does not implement `IntoDiagArg` so this would result in an error if + // not for `#[skip_arg]`. + #[skip_arg] + other: Hello, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ErrorWithSpannedNote { + #[note("with a note")] + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[note("with a note")] +struct ErrorWithNote { + val: String, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ErrorWithSpannedHelpCustom { + #[help("with a help")] + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[help("with a help")] +struct ErrorWithHelp { + val: String, +} + +#[derive(Diagnostic)] +#[help("with a help")] +#[diag("this is an example message", code = E0123)] +struct ErrorWithHelpWrongOrder { + val: String, +} + +#[derive(Diagnostic)] +#[note("with a note")] +#[diag("this is an example message", code = E0123)] +struct ErrorWithNoteWrongOrder { + val: String, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ApplicabilityInBoth { + #[suggestion("with a suggestion", code = "...", applicability = "maybe-incorrect")] + //~^ ERROR specified multiple times + suggestion: (Span, Applicability), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct InvalidApplicability { + #[suggestion("with a suggestion", code = "...", applicability = "batman")] + //~^ ERROR invalid applicability + suggestion: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ValidApplicability { + #[suggestion("with a suggestion", code = "...", applicability = "maybe-incorrect")] + suggestion: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct NoApplicability { + #[suggestion("with a suggestion", code = "...")] + suggestion: Span, +} + +#[derive(Subdiagnostic)] +#[note("this is an example message")] +struct Note; + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct Subdiagnostic { + #[subdiagnostic] + note: Note, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct VecField { + #[primary_span] + #[label("with a label")] + spans: Vec, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct UnitField { + #[primary_span] + spans: Span, + #[help("with a help")] + bar: (), +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct OptUnitField { + #[primary_span] + spans: Span, + #[help("with a help")] + foo: Option<()>, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct BoolField { + #[primary_span] + spans: Span, + #[help("with a help")] + foo: bool, + #[help("with a help")] + //~^ ERROR the `#[help(...)]` attribute can only be applied to fields of type + // only allow plain 'bool' fields + bar: Option, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct LabelWithTrailingPath { + #[label("with a label", foo)] + //~^ ERROR derive(Diagnostic): no nested attribute expected here + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct LabelWithTrailingMessage { + #[label("with a label", "and another one?")] + //~^ ERROR derive(Diagnostic): a diagnostic message must be the first argument to the attribute + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct LabelWithTrailingNameValue { + #[label("with a label", foo = "...")] + //~^ ERROR no nested attribute expected here + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct LabelWithTrailingList { + #[label("with a label", foo("..."))] + //~^ ERROR no nested attribute expected here + span: Span, +} + +#[derive(LintDiagnostic)] +#[diag("this is an example message")] +struct LintsGood {} + +#[derive(LintDiagnostic)] +#[diag("this is an example message")] +struct PrimarySpanOnLint { + #[primary_span] + //~^ ERROR `#[primary_span]` is not a valid attribute + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct ErrorWithMultiSpan { + #[primary_span] + span: MultiSpan, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[warning("with a warning")] +struct ErrorWithWarn { + val: String, +} + +#[derive(Diagnostic)] +#[error("this is an example message", code = E0123)] +//~^ ERROR `#[error(...)]` is not a valid attribute +//~| ERROR diagnostic message not specified +//~| ERROR cannot find attribute `error` in this scope +struct ErrorAttribute {} + +#[derive(Diagnostic)] +#[warn_("this is an example message", code = E0123)] +//~^ ERROR `#[warn_(...)]` is not a valid attribute +//~| ERROR diagnostic message not specified +//~| ERROR cannot find attribute `warn_` in this scope +struct WarnAttribute {} + +#[derive(Diagnostic)] +#[lint("this is an example message", code = E0123)] +//~^ ERROR `#[lint(...)]` is not a valid attribute +//~| ERROR diagnostic message not specified +//~| ERROR cannot find attribute `lint` in this scope +struct LintAttributeOnSessionDiag {} + +#[derive(LintDiagnostic)] +#[lint("this is an example message", code = E0123)] +//~^ ERROR `#[lint(...)]` is not a valid attribute +//~| ERROR diagnostic message not specified +//~| ERROR cannot find attribute `lint` in this scope +struct LintAttributeOnLintDiag {} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct DuplicatedSuggestionCode { + #[suggestion("with a suggestion", code = "...", code = ",,,")] + //~^ ERROR specified multiple times + suggestion: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct InvalidTypeInSuggestionTuple { + #[suggestion("with a suggestion", code = "...")] + suggestion: (Span, usize), + //~^ ERROR wrong types for suggestion +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct MissingApplicabilityInSuggestionTuple { + #[suggestion("with a suggestion", code = "...")] + suggestion: (Span,), + //~^ ERROR wrong types for suggestion +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct MissingCodeInSuggestion { + #[suggestion("with a suggestion")] + //~^ ERROR suggestion without `code = "..."` + suggestion: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[multipart_suggestion("with a suggestion")] +//~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute +//~| ERROR cannot find attribute `multipart_suggestion` in this scope +#[multipart_suggestion()] +//~^ ERROR cannot find attribute `multipart_suggestion` in this scope +//~| ERROR `#[multipart_suggestion(...)]` is not a valid attribute +struct MultipartSuggestion { + #[multipart_suggestion("with a suggestion")] + //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute + //~| ERROR cannot find attribute `multipart_suggestion` in this scope + suggestion: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[suggestion("with a suggestion", code = "...")] +//~^ ERROR `#[suggestion(...)]` is not a valid attribute +struct SuggestionOnStruct { + #[primary_span] + suggestion: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +#[label] +//~^ ERROR `#[label]` is not a valid attribute +struct LabelOnStruct { + #[primary_span] + suggestion: Span, +} + +#[derive(Diagnostic)] +enum ExampleEnum { + #[diag("this is an example message")] + Foo { + #[primary_span] + sp: Span, + #[note("with a note")] + note_sp: Span, + }, + #[diag("this is an example message")] + Bar { + #[primary_span] + sp: Span, + }, + #[diag("this is an example message")] + Baz, +} + +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct RawIdentDiagnosticArg { + pub r#type: String, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SubdiagnosticBad { + #[subdiagnostic(bad)] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + note: Note, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SubdiagnosticBadStr { + #[subdiagnostic = "bad"] + //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute + note: Note, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SubdiagnosticBadTwice { + #[subdiagnostic(bad, bad)] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + note: Note, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SubdiagnosticBadLitStr { + #[subdiagnostic("bad")] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + note: Note, +} + +#[derive(LintDiagnostic)] +#[diag("this is an example message")] +struct SubdiagnosticEagerLint { + #[subdiagnostic(eager)] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + note: Note, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SubdiagnosticEagerFormerlyCorrect { + #[subdiagnostic(eager)] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + note: Note, +} + +// Check that formatting of `correct` in suggestion doesn't move the binding for that field, making +// the `arg` call a compile error; and that isn't worked around by moving the `arg` call +// after the `span_suggestion` call - which breaks eager translation. + +#[derive(Subdiagnostic)] +#[suggestion("example message", applicability = "machine-applicable", code = "{correct}")] +pub(crate) struct SubdiagnosticWithSuggestion { + #[primary_span] + span: Span, + invalid: String, + correct: String, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SubdiagnosticEagerSuggestion { + #[subdiagnostic(eager)] + //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute + sub: SubdiagnosticWithSuggestion, +} + +/// with a doc comment on the type.. +#[derive(Diagnostic)] +#[diag("this is an example message", code = E0123)] +struct WithDocComment { + /// ..and the field + #[primary_span] + span: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SuggestionsGood { + #[suggestion("with a suggestion", code("foo", "bar"))] + sub: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SuggestionsSingleItem { + #[suggestion("with a suggestion", code("foo"))] + sub: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SuggestionsNoItem { + #[suggestion("with a suggestion", code())] + //~^ ERROR expected at least one string literal for `code(...)` + sub: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SuggestionsInvalidItem { + #[suggestion("with a suggestion", code(foo))] + //~^ ERROR `code(...)` must contain only string literals + //~| ERROR unexpected token, expected `)` + sub: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SuggestionsInvalidLiteral { + #[suggestion("with a suggestion", code = 3)] + //~^ ERROR expected string literal + sub: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SuggestionStyleGood { + #[suggestion("with a suggestion", code = "", style = "hidden")] + sub: Span, +} + +#[derive(Diagnostic)] +#[diag("this is an example message")] +struct SuggestionOnVec { + #[suggestion("with a suggestion", code = "")] + //~^ ERROR `#[suggestion(...)]` is not a valid attribute + sub: Vec, +} + +#[derive(Diagnostic)] +#[diag("exists: {$sub}")] +struct VariableExists { + sub: String, +} + +#[derive(Diagnostic)] +#[diag("does not exist: {$nosub}")] +//~^ ERROR Variable `nosub` not found in diagnostic +struct VariableDoesNotExist { + sub: String, +} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr new file mode 100644 index 000000000000..b32235c02b07 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive-inline.stderr @@ -0,0 +1,641 @@ +error: derive(Diagnostic): unsupported type attribute for diagnostic derive enum + --> $DIR/diagnostic-derive-inline.rs:44:1 + | +LL | #[diag("this is an example message", code = E0123)] + | ^ + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:47:5 + | +LL | Foo, + | ^^^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:49:5 + | +LL | Bar, + | ^^^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: expected parentheses: #[diag(...)] + --> $DIR/diagnostic-derive-inline.rs:55:8 + | +LL | #[diag = "E0123"] + | ^ + +error: derive(Diagnostic): `#[nonsense(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:60:1 + | +LL | #[nonsense("this is an example message", code = E0123)] + | ^ + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:60:1 + | +LL | #[nonsense("this is an example message", code = E0123)] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:67:1 + | +LL | #[diag(code = E0123)] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:72:1 + | +LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:77:1 + | +LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:82:1 + | +LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): unknown argument + --> $DIR/diagnostic-derive-inline.rs:87:52 + | +LL | #[diag("this is an example message", code = E0123, slug = "foo")] + | ^^^^ + | + = note: only the `code` parameter is valid after the message + +error: derive(Diagnostic): `#[suggestion = ...]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:94:5 + | +LL | #[suggestion = "bar"] + | ^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/diagnostic-derive-inline.rs:101:38 + | +LL | #[diag("this is an example message", code = E0456)] + | ^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive-inline.rs:100:38 + | +LL | #[diag("this is an example message", code = E0123)] + | ^^^^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/diagnostic-derive-inline.rs:106:52 + | +LL | #[diag("this is an example message", code = E0123, code = E0456)] + | ^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive-inline.rs:106:38 + | +LL | #[diag("this is an example message", code = E0123, code = E0456)] + | ^^^^ + +error: derive(Diagnostic): diagnostic message must be the first argument + --> $DIR/diagnostic-derive-inline.rs:111:38 + | +LL | #[diag("this is an example message", no_crate::example, code = E0123)] + | ^^^^^^^^ + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:116:1 + | +LL | struct KindNotProvided {} + | ^^^^^^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:119:1 + | +LL | #[diag(code = E0123)] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` + --> $DIR/diagnostic-derive-inline.rs:130:5 + | +LL | #[primary_span] + | ^ + +error: derive(Diagnostic): `#[nonsense]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:138:5 + | +LL | #[nonsense] + | ^ + +error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + --> $DIR/diagnostic-derive-inline.rs:155:5 + | +LL | #[label("with a label")] + | ^ + +error: derive(Diagnostic): `name` doesn't refer to a field on this type + --> $DIR/diagnostic-derive-inline.rs:163:46 + | +LL | #[suggestion("with a suggestion", code = "{name}")] + | ^^^^^^^^ + +error: invalid format string: expected `}` but string was terminated + --> $DIR/diagnostic-derive-inline.rs:168:10 + | +LL | #[derive(Diagnostic)] + | ^^^^^^^^^^ expected `}` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: invalid format string: unmatched `}` found + --> $DIR/diagnostic-derive-inline.rs:178:10 + | +LL | #[derive(Diagnostic)] + | ^^^^^^^^^^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + --> $DIR/diagnostic-derive-inline.rs:198:5 + | +LL | #[label("with a label")] + | ^ + +error: derive(Diagnostic): suggestion without `code = "..."` + --> $DIR/diagnostic-derive-inline.rs:217:5 + | +LL | #[suggestion("with a suggestion")] + | ^ + +error: derive(Diagnostic): invalid nested attribute + --> $DIR/diagnostic-derive-inline.rs:225:39 + | +LL | #[suggestion("with a suggestion", nonsense = "bar")] + | ^^^^^^^^ + | + = help: only `style`, `code` and `applicability` are valid nested attributes + +error: derive(Diagnostic): suggestion without `code = "..."` + --> $DIR/diagnostic-derive-inline.rs:225:5 + | +LL | #[suggestion("with a suggestion", nonsense = "bar")] + | ^ + +error: derive(Diagnostic): invalid nested attribute + --> $DIR/diagnostic-derive-inline.rs:234:39 + | +LL | #[suggestion("with a suggestion", msg = "bar")] + | ^^^ + | + = help: only `style`, `code` and `applicability` are valid nested attributes + +error: derive(Diagnostic): suggestion without `code = "..."` + --> $DIR/diagnostic-derive-inline.rs:234:5 + | +LL | #[suggestion("with a suggestion", msg = "bar")] + | ^ + +error: derive(Diagnostic): wrong field type for suggestion + --> $DIR/diagnostic-derive-inline.rs:257:5 + | +LL | #[suggestion("with a suggestion", code = "This is suggested code")] + | ^ + | + = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/diagnostic-derive-inline.rs:273:24 + | +LL | suggestion: (Span, Span, Applicability), + | ^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive-inline.rs:273:18 + | +LL | suggestion: (Span, Span, Applicability), + | ^^^^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/diagnostic-derive-inline.rs:281:33 + | +LL | suggestion: (Applicability, Applicability, Span), + | ^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive-inline.rs:281:18 + | +LL | suggestion: (Applicability, Applicability, Span), + | ^^^^^^^^^^^^^ + +error: derive(Diagnostic): `#[label = ...]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:288:5 + | +LL | #[label = "bar"] + | ^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/diagnostic-derive-inline.rs:389:5 + | +LL | #[suggestion("with a suggestion", code = "...", applicability = "maybe-incorrect")] + | ^ + | +note: previously specified here + --> $DIR/diagnostic-derive-inline.rs:391:24 + | +LL | suggestion: (Span, Applicability), + | ^^^^^^^^^^^^^ + +error: derive(Diagnostic): invalid applicability + --> $DIR/diagnostic-derive-inline.rs:397:69 + | +LL | #[suggestion("with a suggestion", code = "...", applicability = "batman")] + | ^^^^^^^^ + +error: derive(Diagnostic): the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()` + --> $DIR/diagnostic-derive-inline.rs:460:5 + | +LL | #[help("with a help")] + | ^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/diagnostic-derive-inline.rs:469:29 + | +LL | #[label("with a label", foo)] + | ^^^ + +error: derive(Diagnostic): a diagnostic message must be the first argument to the attribute + --> $DIR/diagnostic-derive-inline.rs:477:29 + | +LL | #[label("with a label", "and another one?")] + | ^^^^^^^^^^^^^^^^^^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/diagnostic-derive-inline.rs:485:29 + | +LL | #[label("with a label", foo = "...")] + | ^^^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/diagnostic-derive-inline.rs:493:29 + | +LL | #[label("with a label", foo("..."))] + | ^^^ + +error: derive(Diagnostic): `#[primary_span]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:505:5 + | +LL | #[primary_span] + | ^ + | + = help: the `primary_span` field attribute is not valid for lint diagnostics + +error: derive(Diagnostic): `#[error(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:525:1 + | +LL | #[error("this is an example message", code = E0123)] + | ^ + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:525:1 + | +LL | #[error("this is an example message", code = E0123)] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): `#[warn_(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:532:1 + | +LL | #[warn_("this is an example message", code = E0123)] + | ^ + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:532:1 + | +LL | #[warn_("this is an example message", code = E0123)] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:539:1 + | +LL | #[lint("this is an example message", code = E0123)] + | ^ + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:539:1 + | +LL | #[lint("this is an example message", code = E0123)] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:546:1 + | +LL | #[lint("this is an example message", code = E0123)] + | ^ + +error: derive(Diagnostic): diagnostic message not specified + --> $DIR/diagnostic-derive-inline.rs:546:1 + | +LL | #[lint("this is an example message", code = E0123)] + | ^ + | + = help: specify the message as the first argument to the `#[diag(...)]` attribute, such as `#[diag("Example error")]` + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/diagnostic-derive-inline.rs:555:53 + | +LL | #[suggestion("with a suggestion", code = "...", code = ",,,")] + | ^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive-inline.rs:555:39 + | +LL | #[suggestion("with a suggestion", code = "...", code = ",,,")] + | ^^^^ + +error: derive(Diagnostic): wrong types for suggestion + --> $DIR/diagnostic-derive-inline.rs:564:24 + | +LL | suggestion: (Span, usize), + | ^^^^^ + | + = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` + +error: derive(Diagnostic): wrong types for suggestion + --> $DIR/diagnostic-derive-inline.rs:572:17 + | +LL | suggestion: (Span,), + | ^^^^^^^ + | + = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` + +error: derive(Diagnostic): suggestion without `code = "..."` + --> $DIR/diagnostic-derive-inline.rs:579:5 + | +LL | #[suggestion("with a suggestion")] + | ^ + +error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:586:1 + | +LL | #[multipart_suggestion("with a suggestion")] + | ^ + | + = help: consider creating a `Subdiagnostic` instead + +error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:589:1 + | +LL | #[multipart_suggestion()] + | ^ + | + = help: consider creating a `Subdiagnostic` instead + +error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:593:5 + | +LL | #[multipart_suggestion("with a suggestion")] + | ^ + | + = help: consider creating a `Subdiagnostic` instead + +error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:601:1 + | +LL | #[suggestion("with a suggestion", code = "...")] + | ^ + | + = help: `#[label]` and `#[suggestion]` can only be applied to fields + +error: derive(Diagnostic): `#[label]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:610:1 + | +LL | #[label] + | ^ + | + = help: subdiagnostic message is missing + +error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:644:5 + | +LL | #[subdiagnostic(bad)] + | ^ + +error: derive(Diagnostic): `#[subdiagnostic = ...]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:652:5 + | +LL | #[subdiagnostic = "bad"] + | ^ + +error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:660:5 + | +LL | #[subdiagnostic(bad, bad)] + | ^ + +error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:668:5 + | +LL | #[subdiagnostic("bad")] + | ^ + +error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:676:5 + | +LL | #[subdiagnostic(eager)] + | ^ + +error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:684:5 + | +LL | #[subdiagnostic(eager)] + | ^ + +error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:705:5 + | +LL | #[subdiagnostic(eager)] + | ^ + +error: derive(Diagnostic): expected at least one string literal for `code(...)` + --> $DIR/diagnostic-derive-inline.rs:736:44 + | +LL | #[suggestion("with a suggestion", code())] + | ^ + +error: derive(Diagnostic): `code(...)` must contain only string literals + --> $DIR/diagnostic-derive-inline.rs:744:44 + | +LL | #[suggestion("with a suggestion", code(foo))] + | ^^^ + +error: unexpected token, expected `)` + --> $DIR/diagnostic-derive-inline.rs:744:44 + | +LL | #[suggestion("with a suggestion", code(foo))] + | ^^^ + +error: expected string literal + --> $DIR/diagnostic-derive-inline.rs:753:46 + | +LL | #[suggestion("with a suggestion", code = 3)] + | ^ + +error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute + --> $DIR/diagnostic-derive-inline.rs:768:5 + | +LL | #[suggestion("with a suggestion", code = "")] + | ^ + | + = note: `#[suggestion(...)]` applied to `Vec` field is ambiguous + = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]` + = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` + +error: derive(Diagnostic): Variable `nosub` not found in diagnostic + --> $DIR/diagnostic-derive-inline.rs:780:8 + | +LL | #[diag("does not exist: {$nosub}")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: Available fields: "sub" + +error: cannot find attribute `nonsense` in this scope + --> $DIR/diagnostic-derive-inline.rs:60:3 + | +LL | #[nonsense("this is an example message", code = E0123)] + | ^^^^^^^^ + +error: cannot find attribute `nonsense` in this scope + --> $DIR/diagnostic-derive-inline.rs:138:7 + | +LL | #[nonsense] + | ^^^^^^^^ + +error: cannot find attribute `error` in this scope + --> $DIR/diagnostic-derive-inline.rs:525:3 + | +LL | #[error("this is an example message", code = E0123)] + | ^^^^^ + | +help: `error` is an attribute that can be used by the derive macro `Error`, you might be missing a `derive` attribute + | +LL + #[derive(Error)] +LL | struct ErrorAttribute {} + | + +error: cannot find attribute `warn_` in this scope + --> $DIR/diagnostic-derive-inline.rs:532:3 + | +LL | #[warn_("this is an example message", code = E0123)] + | ^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[warn_("this is an example message", code = E0123)] +LL + #[warn("this is an example message", code = E0123)] + | + +error: cannot find attribute `lint` in this scope + --> $DIR/diagnostic-derive-inline.rs:539:3 + | +LL | #[lint("this is an example message", code = E0123)] + | ^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[lint("this is an example message", code = E0123)] +LL + #[link("this is an example message", code = E0123)] + | + +error: cannot find attribute `lint` in this scope + --> $DIR/diagnostic-derive-inline.rs:546:3 + | +LL | #[lint("this is an example message", code = E0123)] + | ^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[lint("this is an example message", code = E0123)] +LL + #[link("this is an example message", code = E0123)] + | + +error: cannot find attribute `multipart_suggestion` in this scope + --> $DIR/diagnostic-derive-inline.rs:586:3 + | +LL | #[multipart_suggestion("with a suggestion")] + | ^^^^^^^^^^^^^^^^^^^^ + | +help: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute + | +LL + #[derive(Subdiagnostic)] +LL | struct MultipartSuggestion { + | + +error: cannot find attribute `multipart_suggestion` in this scope + --> $DIR/diagnostic-derive-inline.rs:589:3 + | +LL | #[multipart_suggestion()] + | ^^^^^^^^^^^^^^^^^^^^ + | +help: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute + | +LL + #[derive(Subdiagnostic)] +LL | struct MultipartSuggestion { + | + +error: cannot find attribute `multipart_suggestion` in this scope + --> $DIR/diagnostic-derive-inline.rs:593:7 + | +LL | #[multipart_suggestion("with a suggestion")] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute + +error[E0277]: the trait bound `Hello: IntoDiagArg` is not satisfied + --> $DIR/diagnostic-derive-inline.rs:329:12 + | +LL | #[derive(Diagnostic)] + | ---------- required by a bound introduced by this call +... +LL | other: Hello, + | ^^^^^ unsatisfied trait bound + | +help: the nightly-only, unstable trait `IntoDiagArg` is not implemented for `Hello` + --> $DIR/diagnostic-derive-inline.rs:41:1 + | +LL | struct Hello {} + | ^^^^^^^^^^^^ + = help: normalized in stderr +note: required by a bound in `Diag::<'a, G>::arg` + --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + ::: $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC + | + = note: in this macro invocation + = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 81 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs deleted file mode 100644 index fa2d037064d2..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ /dev/null @@ -1,829 +0,0 @@ -//@ check-fail -// Tests error conditions for specifying diagnostics using #[derive(Diagnostic)] -//@ normalize-stderr: "the following other types implement trait `IntoDiagArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr" -//@ normalize-stderr: "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC" - -// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, -// changing the output of this test. Since Diagnostic is strictly internal to the compiler -// the test is just ignored on stable and beta: -//@ ignore-stage1 -//@ ignore-beta -//@ ignore-stable - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_span; -use rustc_span::symbol::Ident; -use rustc_span::Span; - -extern crate rustc_fluent_macro; -extern crate rustc_macros; -use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; - -extern crate rustc_middle; -use rustc_middle::ty::Ty; - -extern crate rustc_errors; -use rustc_errors::{Applicability, DiagMessage, ErrCode, MultiSpan, SubdiagMessage}; - -extern crate rustc_session; - -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - -// E0123 and E0456 are no longer used, so we define our own constants here just for this test. -const E0123: ErrCode = ErrCode::from_u32(0123); -const E0456: ErrCode = ErrCode::from_u32(0456); - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct Hello {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct HelloWarn {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -//~^ ERROR unsupported type attribute for diagnostic derive enum -enum DiagnosticOnEnum { - Foo, - //~^ ERROR diagnostic slug not specified - Bar, - //~^ ERROR diagnostic slug not specified -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[diag = "E0123"] -//~^ ERROR failed to resolve: you might be missing crate `core` -struct WrongStructAttrStyle {} - -#[derive(Diagnostic)] -#[nonsense(no_crate_example, code = E0123)] -//~^ ERROR `#[nonsense(...)]` is not a valid attribute -//~^^ ERROR diagnostic slug not specified -//~^^^ ERROR cannot find attribute `nonsense` in this scope -struct InvalidStructAttr {} - -#[derive(Diagnostic)] -#[diag(code = E0123)] -//~^ ERROR diagnostic slug not specified -struct InvalidLitNestedAttr {} - -#[derive(Diagnostic)] -#[diag(nonsense, code = E0123)] -//~^ ERROR cannot find value `nonsense` in module `crate::fluent_generated` -struct InvalidNestedStructAttr {} - -#[derive(Diagnostic)] -#[diag(nonsense("foo"), code = E0123, slug = "foo")] -//~^ ERROR diagnostic slug must be the first argument -//~| ERROR diagnostic slug not specified -struct InvalidNestedStructAttr1 {} - -#[derive(Diagnostic)] -#[diag(nonsense = "...", code = E0123, slug = "foo")] -//~^ ERROR unknown argument -//~| ERROR diagnostic slug not specified -struct InvalidNestedStructAttr2 {} - -#[derive(Diagnostic)] -#[diag(nonsense = 4, code = E0123, slug = "foo")] -//~^ ERROR unknown argument -//~| ERROR diagnostic slug not specified -struct InvalidNestedStructAttr3 {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123, slug = "foo")] -//~^ ERROR unknown argument -struct InvalidNestedStructAttr4 {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct WrongPlaceField { - #[suggestion = "bar"] - //~^ ERROR `#[suggestion = ...]` is not a valid attribute - sp: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[diag(no_crate_example, code = E0456)] -//~^ ERROR specified multiple times -//~^^ ERROR specified multiple times -struct DiagSpecifiedTwice {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123, code = E0456)] -//~^ ERROR specified multiple times -struct CodeSpecifiedTwice {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, no_crate::example, code = E0123)] -//~^ ERROR diagnostic slug must be the first argument -struct SlugSpecifiedTwice {} - -#[derive(Diagnostic)] -struct KindNotProvided {} //~ ERROR diagnostic slug not specified - -#[derive(Diagnostic)] -#[diag(code = E0123)] -//~^ ERROR diagnostic slug not specified -struct SlugNotProvided {} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct CodeNotProvided {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MessageWrongType { - #[primary_span] - //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - foo: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct InvalidPathFieldAttr { - #[nonsense] - //~^ ERROR `#[nonsense]` is not a valid attribute - //~^^ ERROR cannot find attribute `nonsense` in this scope - foo: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithField { - name: String, - #[label(no_crate_label)] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithMessageAppliedToField { - #[label(no_crate_label)] - //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - name: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithNonexistentField { - #[suggestion(no_crate_suggestion, code = "{name}")] - //~^ ERROR `name` doesn't refer to a field on this type - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -//~^ ERROR invalid format string: expected `}` -#[diag(no_crate_example, code = E0123)] -struct ErrorMissingClosingBrace { - #[suggestion(no_crate_suggestion, code = "{name")] - suggestion: (Span, Applicability), - name: String, - val: usize, -} - -#[derive(Diagnostic)] -//~^ ERROR invalid format string: unmatched `}` -#[diag(no_crate_example, code = E0123)] -struct ErrorMissingOpeningBrace { - #[suggestion(no_crate_suggestion, code = "name}")] - suggestion: (Span, Applicability), - name: String, - val: usize, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelOnSpan { - #[label(no_crate_label)] - sp: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelOnNonSpan { - #[label(no_crate_label)] - //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - id: u32, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct Suggest { - #[suggestion(no_crate_suggestion, code = "This is the suggested code")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "normal")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "short")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "hidden")] - #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "verbose")] - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithoutCode { - #[suggestion(no_crate_suggestion)] - //~^ ERROR suggestion without `code = "..."` - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithBadKey { - #[suggestion(nonsense = "bar")] - //~^ ERROR invalid nested attribute - //~| ERROR suggestion without `code = "..."` - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithShorthandMsg { - #[suggestion(msg = "bar")] - //~^ ERROR invalid nested attribute - //~| ERROR suggestion without `code = "..."` - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithoutMsg { - #[suggestion(code = "bar")] - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithTypesSwapped { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: (Applicability, Span), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithWrongTypeApplicabilityOnly { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - //~^ ERROR wrong field type for suggestion - suggestion: Applicability, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithSpanOnly { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithDuplicateSpanAndApplicability { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: (Span, Span, Applicability), - //~^ ERROR specified multiple times -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct SuggestWithDuplicateApplicabilityAndSpan { - #[suggestion(no_crate_suggestion, code = "This is suggested code")] - suggestion: (Applicability, Applicability, Span), - //~^ ERROR specified multiple times -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct WrongKindOfAnnotation { - #[label = "bar"] - //~^ ERROR `#[label = ...]` is not a valid attribute - z: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct OptionsInErrors { - #[label(no_crate_label)] - label: Option, - #[suggestion(no_crate_suggestion, code = "...")] - opt_sugg: Option<(Span, Applicability)>, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MoveOutOfBorrowError<'tcx> { - name: Ident, - ty: Ty<'tcx>, - #[primary_span] - #[label(no_crate_label)] - span: Span, - #[label(no_crate_label)] - other_span: Span, - #[suggestion(no_crate_suggestion, code = "{name}.clone()")] - opt_sugg: Option<(Span, Applicability)>, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithLifetime<'a> { - #[label(no_crate_label)] - span: Span, - name: &'a str, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithDefaultLabelAttr<'a> { - #[label] - span: Span, - name: &'a str, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ArgFieldWithoutSkip { - #[primary_span] - span: Span, - other: Hello, - //~^ ERROR the trait bound `Hello: IntoDiagArg` is not satisfied -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ArgFieldWithSkip { - #[primary_span] - span: Span, - // `Hello` does not implement `IntoDiagArg` so this would result in an error if - // not for `#[skip_arg]`. - #[skip_arg] - other: Hello, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedNote { - #[note] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedNoteCustom { - #[note(no_crate_note)] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[note] -struct ErrorWithNote { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[note(no_crate_note)] -struct ErrorWithNoteCustom { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedHelp { - #[help] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithSpannedHelpCustom { - #[help(no_crate_help)] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[help] -struct ErrorWithHelp { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[help(no_crate_help)] -struct ErrorWithHelpCustom { - val: String, -} - -#[derive(Diagnostic)] -#[help] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithHelpWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[help(no_crate_help)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithHelpCustomWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[note] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithNoteWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[note(no_crate_note)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithNoteCustomWrongOrder { - val: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ApplicabilityInBoth { - #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] - //~^ ERROR specified multiple times - suggestion: (Span, Applicability), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct InvalidApplicability { - #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] - //~^ ERROR invalid applicability - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ValidApplicability { - #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct NoApplicability { - #[suggestion(no_crate_suggestion, code = "...")] - suggestion: Span, -} - -#[derive(Subdiagnostic)] -#[note(no_crate_example)] -struct Note; - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct Subdiagnostic { - #[subdiagnostic] - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct VecField { - #[primary_span] - #[label] - spans: Vec, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct UnitField { - #[primary_span] - spans: Span, - #[help] - foo: (), - #[help(no_crate_help)] - bar: (), -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct OptUnitField { - #[primary_span] - spans: Span, - #[help] - foo: Option<()>, - #[help(no_crate_help)] - bar: Option<()>, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct BoolField { - #[primary_span] - spans: Span, - #[help] - foo: bool, - #[help(no_crate_help)] - //~^ ERROR the `#[help(...)]` attribute can only be applied to fields of type - // only allow plain 'bool' fields - bar: Option, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelWithTrailingPath { - #[label(no_crate_label, foo)] - //~^ ERROR a diagnostic slug must be the first argument to the attribute - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelWithTrailingNameValue { - #[label(no_crate_label, foo = "...")] - //~^ ERROR only `no_span` is a valid nested attribute - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct LabelWithTrailingList { - #[label(no_crate_label, foo("..."))] - //~^ ERROR only `no_span` is a valid nested attribute - span: Span, -} - -#[derive(LintDiagnostic)] -#[diag(no_crate_example)] -struct LintsGood {} - -#[derive(LintDiagnostic)] -#[diag(no_crate_example)] -struct PrimarySpanOnLint { - #[primary_span] - //~^ ERROR `#[primary_span]` is not a valid attribute - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct ErrorWithMultiSpan { - #[primary_span] - span: MultiSpan, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[warning] -struct ErrorWithWarn { - val: String, -} - -#[derive(Diagnostic)] -#[error(no_crate_example, code = E0123)] -//~^ ERROR `#[error(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `error` in this scope -struct ErrorAttribute {} - -#[derive(Diagnostic)] -#[warn_(no_crate_example, code = E0123)] -//~^ ERROR `#[warn_(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `warn_` in this scope -struct WarnAttribute {} - -#[derive(Diagnostic)] -#[lint(no_crate_example, code = E0123)] -//~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `lint` in this scope -struct LintAttributeOnSessionDiag {} - -#[derive(LintDiagnostic)] -#[lint(no_crate_example, code = E0123)] -//~^ ERROR `#[lint(...)]` is not a valid attribute -//~| ERROR diagnostic slug not specified -//~| ERROR cannot find attribute `lint` in this scope -struct LintAttributeOnLintDiag {} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct DuplicatedSuggestionCode { - #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] - //~^ ERROR specified multiple times - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct InvalidTypeInSuggestionTuple { - #[suggestion(no_crate_suggestion, code = "...")] - suggestion: (Span, usize), - //~^ ERROR wrong types for suggestion -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MissingApplicabilityInSuggestionTuple { - #[suggestion(no_crate_suggestion, code = "...")] - suggestion: (Span,), - //~^ ERROR wrong types for suggestion -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct MissingCodeInSuggestion { - #[suggestion(no_crate_suggestion)] - //~^ ERROR suggestion without `code = "..."` - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[multipart_suggestion(no_crate_suggestion)] -//~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute -//~| ERROR cannot find attribute `multipart_suggestion` in this scope -#[multipart_suggestion()] -//~^ ERROR cannot find attribute `multipart_suggestion` in this scope -//~| ERROR `#[multipart_suggestion(...)]` is not a valid attribute -struct MultipartSuggestion { - #[multipart_suggestion(no_crate_suggestion)] - //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute - //~| ERROR cannot find attribute `multipart_suggestion` in this scope - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[suggestion(no_crate_suggestion, code = "...")] -//~^ ERROR `#[suggestion(...)]` is not a valid attribute -struct SuggestionOnStruct { - #[primary_span] - suggestion: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -#[label] -//~^ ERROR `#[label]` is not a valid attribute -struct LabelOnStruct { - #[primary_span] - suggestion: Span, -} - -#[derive(Diagnostic)] -enum ExampleEnum { - #[diag(no_crate_example)] - Foo { - #[primary_span] - sp: Span, - #[note] - note_sp: Span, - }, - #[diag(no_crate_example)] - Bar { - #[primary_span] - sp: Span, - }, - #[diag(no_crate_example)] - Baz, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct RawIdentDiagnosticArg { - pub r#type: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBad { - #[subdiagnostic(bad)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBadStr { - #[subdiagnostic = "bad"] - //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBadTwice { - #[subdiagnostic(bad, bad)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticBadLitStr { - #[subdiagnostic("bad")] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(LintDiagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticEagerLint { - #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticEagerFormerlyCorrect { - #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - note: Note, -} - -// Check that formatting of `correct` in suggestion doesn't move the binding for that field, making -// the `arg` call a compile error; and that isn't worked around by moving the `arg` call -// after the `span_suggestion` call - which breaks eager translation. - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, applicability = "machine-applicable", code = "{correct}")] -pub(crate) struct SubdiagnosticWithSuggestion { - #[primary_span] - span: Span, - invalid: String, - correct: String, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SubdiagnosticEagerSuggestion { - #[subdiagnostic(eager)] - //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute - sub: SubdiagnosticWithSuggestion, -} - -/// with a doc comment on the type.. -#[derive(Diagnostic)] -#[diag(no_crate_example, code = E0123)] -struct WithDocComment { - /// ..and the field - #[primary_span] - span: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsGood { - #[suggestion(code("foo", "bar"))] - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsSingleItem { - #[suggestion(code("foo"))] - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsNoItem { - #[suggestion(code())] - //~^ ERROR expected at least one string literal for `code(...)` - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionsInvalidItem { - #[suggestion(code(foo))] - //~^ ERROR `code(...)` must contain only string literals - //~| ERROR failed to resolve: you might be missing crate `core` - sub: Span, -} - -#[derive(Diagnostic)] //~ ERROR cannot find value `__code_34` in this scope -#[diag(no_crate_example)] -struct SuggestionsInvalidLiteral { - #[suggestion(code = 3)] - //~^ ERROR failed to resolve: you might be missing crate `core` - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionStyleGood { - #[suggestion(code = "", style = "hidden")] - sub: Span, -} - -#[derive(Diagnostic)] -#[diag(no_crate_example)] -struct SuggestionOnVec { - #[suggestion(no_crate_suggestion, code = "")] - //~^ ERROR `#[suggestion(...)]` is not a valid attribute - sub: Vec, -} diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr deleted file mode 100644 index 59b48e9f0ecc..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ /dev/null @@ -1,655 +0,0 @@ -error: derive(Diagnostic): unsupported type attribute for diagnostic derive enum - --> $DIR/diagnostic-derive.rs:47:1 - | -LL | #[diag(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:50:5 - | -LL | Foo, - | ^^^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:52:5 - | -LL | Bar, - | ^^^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): `#[nonsense(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:63:1 - | -LL | #[nonsense(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:63:1 - | -LL | #[nonsense(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:70:1 - | -LL | #[diag(code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:80:16 - | -LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:80:1 - | -LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive.rs:86:8 - | -LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] - | ^^^^^^^^ - | - = note: only the `code` parameter is valid after the slug - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:86:1 - | -LL | #[diag(nonsense = "...", code = E0123, slug = "foo")] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive.rs:92:8 - | -LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] - | ^^^^^^^^ - | - = note: only the `code` parameter is valid after the slug - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:92:1 - | -LL | #[diag(nonsense = 4, code = E0123, slug = "foo")] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): unknown argument - --> $DIR/diagnostic-derive.rs:98:40 - | -LL | #[diag(no_crate_example, code = E0123, slug = "foo")] - | ^^^^ - | - = note: only the `code` parameter is valid after the slug - -error: derive(Diagnostic): `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:105:5 - | -LL | #[suggestion = "bar"] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:112:8 - | -LL | #[diag(no_crate_example, code = E0456)] - | ^^^^^^^^^^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:111:8 - | -LL | #[diag(no_crate_example, code = E0123)] - | ^^^^^^^^^^^^^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:112:26 - | -LL | #[diag(no_crate_example, code = E0456)] - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:111:26 - | -LL | #[diag(no_crate_example, code = E0123)] - | ^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:118:40 - | -LL | #[diag(no_crate_example, code = E0123, code = E0456)] - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:118:26 - | -LL | #[diag(no_crate_example, code = E0123, code = E0456)] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:123:43 - | -LL | #[diag(no_crate_example, no_crate::example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:128:1 - | -LL | struct KindNotProvided {} - | ^^^^^^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:131:1 - | -LL | #[diag(code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:142:5 - | -LL | #[primary_span] - | ^ - -error: derive(Diagnostic): `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:150:5 - | -LL | #[nonsense] - | ^ - -error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:167:5 - | -LL | #[label(no_crate_label)] - | ^ - -error: derive(Diagnostic): `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:175:46 - | -LL | #[suggestion(no_crate_suggestion, code = "{name}")] - | ^^^^^^^^ - -error: invalid format string: expected `}` but string was terminated - --> $DIR/diagnostic-derive.rs:180:10 - | -LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ expected `}` in format string - | - = note: if you intended to print `{`, you can escape it using `{{` - = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:190:10 - | -LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ unmatched `}` in format string - | - = note: if you intended to print `}`, you can escape it using `}}` - = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: derive(Diagnostic): the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:210:5 - | -LL | #[label(no_crate_label)] - | ^ - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:229:5 - | -LL | #[suggestion(no_crate_suggestion)] - | ^ - -error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive.rs:237:18 - | -LL | #[suggestion(nonsense = "bar")] - | ^^^^^^^^ - | - = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:237:5 - | -LL | #[suggestion(nonsense = "bar")] - | ^ - -error: derive(Diagnostic): invalid nested attribute - --> $DIR/diagnostic-derive.rs:246:18 - | -LL | #[suggestion(msg = "bar")] - | ^^^ - | - = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:246:5 - | -LL | #[suggestion(msg = "bar")] - | ^ - -error: derive(Diagnostic): wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:269:5 - | -LL | #[suggestion(no_crate_suggestion, code = "This is suggested code")] - | ^ - | - = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:285:24 - | -LL | suggestion: (Span, Span, Applicability), - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:285:18 - | -LL | suggestion: (Span, Span, Applicability), - | ^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:293:33 - | -LL | suggestion: (Applicability, Applicability, Span), - | ^^^^^^^^^^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:293:18 - | -LL | suggestion: (Applicability, Applicability, Span), - | ^^^^^^^^^^^^^ - -error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:300:5 - | -LL | #[label = "bar"] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:451:5 - | -LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] - | ^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:453:24 - | -LL | suggestion: (Span, Applicability), - | ^^^^^^^^^^^^^ - -error: derive(Diagnostic): invalid applicability - --> $DIR/diagnostic-derive.rs:459:69 - | -LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] - | ^^^^^^^^ - -error: derive(Diagnostic): the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()` - --> $DIR/diagnostic-derive.rs:526:5 - | -LL | #[help(no_crate_help)] - | ^ - -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/diagnostic-derive.rs:535:32 - | -LL | #[label(no_crate_label, foo)] - | ^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/diagnostic-derive.rs:543:29 - | -LL | #[label(no_crate_label, foo = "...")] - | ^^^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/diagnostic-derive.rs:551:29 - | -LL | #[label(no_crate_label, foo("..."))] - | ^^^ - -error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:563:5 - | -LL | #[primary_span] - | ^ - | - = help: the `primary_span` field attribute is not valid for lint diagnostics - -error: derive(Diagnostic): `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:583:1 - | -LL | #[error(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:583:1 - | -LL | #[error(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:590:1 - | -LL | #[warn_(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:590:1 - | -LL | #[warn_(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:597:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:597:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` - -error: derive(Diagnostic): `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:604:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - -error: derive(Diagnostic): diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:604:1 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^ - | - = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/diagnostic-derive.rs:613:53 - | -LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] - | ^^^^ - | -note: previously specified here - --> $DIR/diagnostic-derive.rs:613:39 - | -LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] - | ^^^^ - -error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive.rs:622:24 - | -LL | suggestion: (Span, usize), - | ^^^^^ - | - = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` - -error: derive(Diagnostic): wrong types for suggestion - --> $DIR/diagnostic-derive.rs:630:17 - | -LL | suggestion: (Span,), - | ^^^^^^^ - | - = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:637:5 - | -LL | #[suggestion(no_crate_suggestion)] - | ^ - -error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:644:1 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^ - | - = help: consider creating a `Subdiagnostic` instead - -error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:647:1 - | -LL | #[multipart_suggestion()] - | ^ - | - = help: consider creating a `Subdiagnostic` instead - -error: derive(Diagnostic): `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:651:5 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^ - | - = help: consider creating a `Subdiagnostic` instead - -error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:659:1 - | -LL | #[suggestion(no_crate_suggestion, code = "...")] - | ^ - | - = help: `#[label]` and `#[suggestion]` can only be applied to fields - -error: derive(Diagnostic): `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:668:1 - | -LL | #[label] - | ^ - | - = help: `#[label]` and `#[suggestion]` can only be applied to fields - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:702:5 - | -LL | #[subdiagnostic(bad)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:710:5 - | -LL | #[subdiagnostic = "bad"] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:718:5 - | -LL | #[subdiagnostic(bad, bad)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:726:5 - | -LL | #[subdiagnostic("bad")] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:734:5 - | -LL | #[subdiagnostic(eager)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:742:5 - | -LL | #[subdiagnostic(eager)] - | ^ - -error: derive(Diagnostic): `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:763:5 - | -LL | #[subdiagnostic(eager)] - | ^ - -error: derive(Diagnostic): expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:794:23 - | -LL | #[suggestion(code())] - | ^ - -error: derive(Diagnostic): `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:802:23 - | -LL | #[suggestion(code(foo))] - | ^^^ - -error: derive(Diagnostic): `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:826:5 - | -LL | #[suggestion(no_crate_suggestion, code = "")] - | ^ - | - = note: `#[suggestion(...)]` applied to `Vec` field is ambiguous - = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]` - = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:58:8 - | -LL | #[diag = "E0123"] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:802:23 - | -LL | #[suggestion(code(foo))] - | ^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/diagnostic-derive.rs:811:25 - | -LL | #[suggestion(code = 3)] - | ^ you might be missing crate `core` - -error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:63:3 - | -LL | #[nonsense(no_crate_example, code = E0123)] - | ^^^^^^^^ - -error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:150:7 - | -LL | #[nonsense] - | ^^^^^^^^ - -error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:583:3 - | -LL | #[error(no_crate_example, code = E0123)] - | ^^^^^ - | -help: `error` is an attribute that can be used by the derive macro `Error`, you might be missing a `derive` attribute - | -LL + #[derive(Error)] -LL | struct ErrorAttribute {} - | - -error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:590:3 - | -LL | #[warn_(no_crate_example, code = E0123)] - | ^^^^^ help: a built-in attribute with a similar name exists: `warn` - -error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:597:3 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ help: a built-in attribute with a similar name exists: `link` - -error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:604:3 - | -LL | #[lint(no_crate_example, code = E0123)] - | ^^^^ help: a built-in attribute with a similar name exists: `link` - -error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:644:3 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ - | -help: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute - | -LL + #[derive(Subdiagnostic)] -LL | struct MultipartSuggestion { - | - -error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:647:3 - | -LL | #[multipart_suggestion()] - | ^^^^^^^^^^^^^^^^^^^^ - | -help: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute - | -LL + #[derive(Subdiagnostic)] -LL | struct MultipartSuggestion { - | - -error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:651:7 - | -LL | #[multipart_suggestion(no_crate_suggestion)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: `multipart_suggestion` is an attribute that can be used by the derive macro `Subdiagnostic`, you might be missing a `derive` attribute - -error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` - --> $DIR/diagnostic-derive.rs:75:8 - | -LL | #[diag(nonsense, code = E0123)] - | ^^^^^^^^ not found in `crate::fluent_generated` - -error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:808:10 - | -LL | #[derive(Diagnostic)] - | ^^^^^^^^^^ not found in this scope - | - = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: the trait bound `Hello: IntoDiagArg` is not satisfied - --> $DIR/diagnostic-derive.rs:349:12 - | -LL | #[derive(Diagnostic)] - | ---------- required by a bound introduced by this call -... -LL | other: Hello, - | ^^^^^ unsatisfied trait bound - | -help: the trait `IntoDiagArg` is not implemented for `Hello` - --> $DIR/diagnostic-derive.rs:40:1 - | -LL | struct Hello {} - | ^^^^^^^^^^^^ - = help: normalized in stderr -note: required by a bound in `Diag::<'a, G>::arg` - --> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC - = note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 85 previous errors - -Some errors have detailed explanations: E0277, E0425, E0433. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs deleted file mode 100644 index 6402b00ef0a9..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ rustc-env:CARGO_CRATE_NAME=rustc_dummy - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_span; -use rustc_span::symbol::Ident; -use rustc_span::Span; - -extern crate rustc_macros; -use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; - -extern crate rustc_middle; -use rustc_middle::ty::Ty; - -extern crate rustc_errors; -use rustc_errors::{Applicability, MultiSpan}; - -extern crate rustc_session; - -#[derive(Diagnostic)] -#[diag(compiletest_example, code = E0123)] -//~^ ERROR diagnostic slug and crate name do not match -struct Hello {} diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr deleted file mode 100644 index 4f54239f0fa3..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: derive(Diagnostic): diagnostic slug and crate name do not match - --> $DIR/enforce_slug_naming.rs:22:8 - | -LL | #[diag(compiletest_example, code = E0123)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: slug is `compiletest_example` but the crate name is `rustc_dummy` - = help: expected a slug starting with `dummy_...` - -error: aborting due to 1 previous error - diff --git a/tests/ui-fulldeps/session-diagnostic/example.ftl b/tests/ui-fulldeps/session-diagnostic/example.ftl deleted file mode 100644 index 1d1ba8e1bd5c..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/example.ftl +++ /dev/null @@ -1,7 +0,0 @@ -no_crate_example = this is an example message used in testing - .note = with a note - .help = with a help - .suggestion = with a suggestion - .label = with a label - -no_crate_bad_reference = {$r} does not exist diff --git a/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs b/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs deleted file mode 100644 index cbe9e3f4ef4c..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/invalid-variable.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ run-fail -//@ compile-flags: --test -// test that messages referencing non-existent fields cause test failures - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_driver; -extern crate rustc_fluent_macro; -extern crate rustc_macros; -extern crate rustc_errors; -use rustc_macros::Diagnostic; -use rustc_errors::{DiagMessage, SubdiagMessage}; -extern crate rustc_session; - -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - -#[derive(Diagnostic)] -#[diag(no_crate_bad_reference)] -struct BadRef; diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs new file mode 100644 index 000000000000..2aed4fa9465c --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.rs @@ -0,0 +1,814 @@ +//@ check-fail +// Tests error conditions for specifying inline subdiagnostics using #[derive(Subdiagnostic)] + +// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, +// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler +// the test is just ignored on stable and beta: +//@ ignore-stage1 +//@ ignore-beta +//@ ignore-stable + +#![feature(rustc_private)] +#![crate_type = "lib"] + +extern crate rustc_errors; +extern crate rustc_macros; +extern crate rustc_session; +extern crate rustc_span; +extern crate core; + +use rustc_errors::{Applicability, DiagMessage}; +use rustc_macros::Subdiagnostic; +use rustc_span::Span; + +#[derive(Subdiagnostic)] +#[label("example message")] +struct A { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +enum B { + #[label("example message")] + A { + #[primary_span] + span: Span, + var: String, + }, + #[label("example message")] + B { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +//~^ ERROR label without `#[primary_span]` field +struct C { + var: String, +} + +#[derive(Subdiagnostic)] +#[label] +//~^ ERROR diagnostic message must be first argument +struct D { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[foo] +//~^ ERROR `#[foo]` is not a valid attribute +//~^^ ERROR cannot find attribute `foo` in this scope +struct E { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label = "..."] +//~^ ERROR `#[label = ...]` is not a valid attribute +struct F { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label(bug = "...")] +//~^ ERROR no nested attribute expected here +//~| ERROR diagnostic message must be first argument +struct G { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label("...")] +struct H { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label(slug = 4)] +//~^ ERROR no nested attribute expected here +//~| ERROR diagnostic message must be first argument +struct J { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label(slug("..."))] +//~^ ERROR no nested attribute expected here +//~| ERROR diagnostic message must be first argument +struct K { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label()] +//~^ ERROR diagnostic message must be first argument of a `#[label(...)]` attribute +struct M { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label("example message", code = "...")] +//~^ ERROR no nested attribute expected here +struct N { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[label("example message", applicability = "machine-applicable")] +//~^ ERROR no nested attribute expected here +struct O { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[foo] +//~^ ERROR cannot find attribute `foo` in this scope +//~^^ ERROR unsupported type attribute for subdiagnostic enum +enum P { + #[label("example message")] + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +enum Q { + #[bar] + //~^ ERROR `#[bar]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +enum R { + #[bar = "..."] + //~^ ERROR `#[bar = ...]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +enum S { + #[bar = 4] + //~^ ERROR `#[bar = ...]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +enum T { + #[bar("...")] + //~^ ERROR `#[bar(...)]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +enum U { + #[label(code = "...")] + //~^ ERROR diagnostic message must be first argument of a `#[label(...)]` attribute + //~| ERROR no nested attribute expected here + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +enum V { + #[label("example message")] + A { + #[primary_span] + span: Span, + var: String, + }, + B { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +//~^ ERROR label without `#[primary_span]` field +struct W { + #[primary_span] + //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` + span: String, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +struct X { + #[primary_span] + span: Span, + #[applicability] + //~^ ERROR `#[applicability]` is only valid on suggestions + applicability: Applicability, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +struct Y { + #[primary_span] + span: Span, + #[bar] + //~^ ERROR `#[bar]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + bar: String, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +struct Z { + #[primary_span] + span: Span, + #[bar = "..."] + //~^ ERROR `#[bar = ...]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + bar: String, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +struct AA { + #[primary_span] + span: Span, + #[bar("...")] + //~^ ERROR `#[bar(...)]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + bar: String, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +struct AB { + #[primary_span] + span: Span, + #[skip_arg] + z: Z, +} + +#[derive(Subdiagnostic)] +union AC { + //~^ ERROR unexpected unsupported untagged union + span: u32, + b: u64, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +#[label("example message")] +struct AD { + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +#[label("example message", no_crate::example)] +//~^ ERROR expected this path to be an identifier +struct AE { + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +struct AF { + #[primary_span] + //~^ NOTE previously specified here + span_a: Span, + #[primary_span] + //~^ ERROR specified multiple times + span_b: Span, +} + +#[derive(Subdiagnostic)] +struct AG { + //~^ ERROR subdiagnostic kind not specified + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...")] +struct AH { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, + var: String, +} + +#[derive(Subdiagnostic)] +enum AI { + #[suggestion("example message", code = "...")] + A { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, + var: String, + }, + #[suggestion("example message", code = "...")] + B { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, + var: String, + }, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...", code = "...")] +//~^ ERROR specified multiple times +//~^^ NOTE previously specified here +struct AJ { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...")] +struct AK { + #[primary_span] + span: Span, + #[applicability] + //~^ NOTE previously specified here + applicability_a: Applicability, + #[applicability] + //~^ ERROR specified multiple times + applicability_b: Applicability, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...")] +struct AL { + #[primary_span] + span: Span, + #[applicability] + //~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability` + applicability: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...")] +struct AM { + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message")] +//~^ ERROR suggestion without `code = "..."` +struct AN { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...", applicability = "foo")] +//~^ ERROR invalid applicability +struct AO { + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +#[help("example message")] +struct AP { + var: String, +} + +#[derive(Subdiagnostic)] +#[note("example message")] +struct AQ; + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...")] +//~^ ERROR suggestion without `#[primary_span]` field +struct AR { + var: String, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...", applicability = "machine-applicable")] +struct AS { + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +#[label] +//~^ ERROR unsupported type attribute for subdiagnostic enum +enum AT { + #[label("example message")] + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "{var}", applicability = "machine-applicable")] +struct AU { + #[primary_span] + span: Span, + var: String, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "{var}", applicability = "machine-applicable")] +//~^ ERROR `var` doesn't refer to a field on this type +struct AV { + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +enum AW { + #[suggestion("example message", code = "{var}", applicability = "machine-applicable")] + A { + #[primary_span] + span: Span, + var: String, + }, +} + +#[derive(Subdiagnostic)] +enum AX { + #[suggestion("example message", code = "{var}", applicability = "machine-applicable")] + //~^ ERROR `var` doesn't refer to a field on this type + A { + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +#[warning("example message")] +struct AY {} + +#[derive(Subdiagnostic)] +#[warning("example message")] +struct AZ { + #[primary_span] + span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "...")] +//~^ ERROR suggestion without `#[primary_span]` field +struct BA { + #[suggestion_part] + //~^ ERROR `#[suggestion_part]` is not a valid attribute + span: Span, + #[suggestion_part(code = "...")] + //~^ ERROR `#[suggestion_part(...)]` is not a valid attribute + span2: Span, + #[applicability] + applicability: Applicability, + var: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message", code = "...", applicability = "machine-applicable")] +//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields +//~| ERROR invalid nested attribute +struct BBa { + var: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message", applicability = "machine-applicable")] +struct BBb { + #[suggestion_part] + //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` + span1: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message", applicability = "machine-applicable")] +struct BBc { + #[suggestion_part()] + //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` + span1: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields +struct BC { + #[primary_span] + //~^ ERROR `#[primary_span]` is not a valid attribute + span: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +struct BD { + #[suggestion_part] + //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` + span1: Span, + #[suggestion_part()] + //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` + span2: Span, + #[suggestion_part(foo = "bar")] + //~^ ERROR `code` is the only valid nested attribute + //~| ERROR expected `,` + span4: Span, + #[suggestion_part(code = "...")] + //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + s1: String, + #[suggestion_part()] + //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + s2: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message", applicability = "machine-applicable")] +struct BE { + #[suggestion_part(code = "...", code = ",,,")] + //~^ ERROR specified multiple times + //~| NOTE previously specified here + span: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message", applicability = "machine-applicable")] +struct BF { + #[suggestion_part(code = "(")] + first: Span, + #[suggestion_part(code = ")")] + second: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +struct BG { + #[applicability] + appl: Applicability, + #[suggestion_part(code = "(")] + first: Span, + #[suggestion_part(code = ")")] + second: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message", applicability = "machine-applicable")] +struct BH { + #[applicability] + //~^ ERROR `#[applicability]` has no effect + appl: Applicability, + #[suggestion_part(code = "(")] + first: Span, + #[suggestion_part(code = ")")] + second: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message", applicability = "machine-applicable")] +struct BI { + #[suggestion_part(code = "")] + spans: Vec, +} + +#[derive(Subdiagnostic)] +#[label("example message")] +struct BJ { + #[primary_span] + span: Span, + r#type: String, +} + +/// with a doc comment on the type.. +#[derive(Subdiagnostic)] +#[label("example message")] +struct BK { + /// ..and the field + #[primary_span] + span: Span, +} + +/// with a doc comment on the type.. +#[derive(Subdiagnostic)] +enum BL { + /// ..and the variant.. + #[label("example message")] + Foo { + /// ..and the field + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +struct BM { + #[suggestion_part(code("foo"))] + //~^ ERROR expected exactly one string literal for `code = ...` + //~| ERROR unexpected token, expected `)` + span: Span, + r#type: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +struct BN { + #[suggestion_part(code("foo", "bar"))] + //~^ ERROR expected exactly one string literal for `code = ...` + //~| ERROR unexpected token, expected `)` + span: Span, + r#type: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +struct BO { + #[suggestion_part(code(3))] + //~^ ERROR expected exactly one string literal for `code = ...` + //~| ERROR unexpected token, expected `)` + span: Span, + r#type: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +struct BP { + #[suggestion_part(code())] + //~^ ERROR expected exactly one string literal for `code = ...` + span: Span, + r#type: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion("example message")] +struct BQ { + #[suggestion_part(code = 3)] + //~^ ERROR expected string literal + span: Span, + r#type: String, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "")] +struct SuggestionStyleDefault { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style = "short")] +struct SuggestionStyleShort { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style = "hidden")] +struct SuggestionStyleHidden { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style = "verbose")] +struct SuggestionStyleVerbose { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style = "tool-only")] +struct SuggestionStyleToolOnly { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style = "hidden", style = "normal")] +//~^ ERROR specified multiple times +//~| NOTE previously specified here +struct SuggestionStyleTwice { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion_hidden("example message", code = "")] +//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute +struct SuggestionStyleOldSyntax { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion_hidden("example message", code = "", style = "normal")] +//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute +struct SuggestionStyleOldAndNewSyntax { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style = "foo")] +//~^ ERROR invalid suggestion style +struct SuggestionStyleInvalid1 { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style = 42)] +//~^ ERROR expected string literal +struct SuggestionStyleInvalid2 { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style)] +//~^ ERROR expected `=` +struct SuggestionStyleInvalid3 { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "", style("foo"))] +//~^ ERROR expected `=` +struct SuggestionStyleInvalid4 { + #[primary_span] + sub: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion("example message", code = "")] +//~^ ERROR suggestion without `#[primary_span]` field +struct PrimarySpanOnVec { + #[primary_span] + //~^ ERROR `#[primary_span]` is not a valid attribute + //~| NOTE there must be exactly one primary span + sub: Vec, +} + +#[derive(Subdiagnostic)] +struct NestedParent { + #[subdiagnostic] + single_sub: A, + #[subdiagnostic] + option_sub: Option, + #[subdiagnostic] + vec_sub: Vec, +} diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr new file mode 100644 index 000000000000..8e634bf78797 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive-inline.stderr @@ -0,0 +1,549 @@ +error: derive(Diagnostic): label without `#[primary_span]` field + --> $DIR/subdiagnostic-derive-inline.rs:49:1 + | +LL | #[label("example message")] + | ^ + +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive-inline.rs:56:1 + | +LL | #[label] + | ^ + +error: derive(Diagnostic): `#[foo]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:65:1 + | +LL | #[foo] + | ^ + +error: derive(Diagnostic): `#[label = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:75:1 + | +LL | #[label = "..."] + | ^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/subdiagnostic-derive-inline.rs:84:9 + | +LL | #[label(bug = "...")] + | ^^^ + +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive-inline.rs:84:1 + | +LL | #[label(bug = "...")] + | ^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/subdiagnostic-derive-inline.rs:102:9 + | +LL | #[label(slug = 4)] + | ^^^^ + +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive-inline.rs:102:1 + | +LL | #[label(slug = 4)] + | ^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/subdiagnostic-derive-inline.rs:112:9 + | +LL | #[label(slug("..."))] + | ^^^^ + +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive-inline.rs:112:1 + | +LL | #[label(slug("..."))] + | ^ + +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive-inline.rs:122:1 + | +LL | #[label()] + | ^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/subdiagnostic-derive-inline.rs:131:28 + | +LL | #[label("example message", code = "...")] + | ^^^^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/subdiagnostic-derive-inline.rs:140:28 + | +LL | #[label("example message", applicability = "machine-applicable")] + | ^^^^^^^^^^^^^ + +error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum + --> $DIR/subdiagnostic-derive-inline.rs:149:1 + | +LL | #[foo] + | ^ + +error: derive(Diagnostic): `#[bar]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:163:5 + | +LL | #[bar] + | ^ + +error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:175:5 + | +LL | #[bar = "..."] + | ^ + +error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:187:5 + | +LL | #[bar = 4] + | ^ + +error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:199:5 + | +LL | #[bar("...")] + | ^ + +error: derive(Diagnostic): no nested attribute expected here + --> $DIR/subdiagnostic-derive-inline.rs:211:13 + | +LL | #[label(code = "...")] + | ^^^^ + +error: derive(Diagnostic): diagnostic message must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive-inline.rs:211:5 + | +LL | #[label(code = "...")] + | ^ + +error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` + --> $DIR/subdiagnostic-derive-inline.rs:240:5 + | +LL | #[primary_span] + | ^ + +error: derive(Diagnostic): label without `#[primary_span]` field + --> $DIR/subdiagnostic-derive-inline.rs:237:1 + | +LL | #[label("example message")] + | ^ + +error: derive(Diagnostic): `#[applicability]` is only valid on suggestions + --> $DIR/subdiagnostic-derive-inline.rs:250:5 + | +LL | #[applicability] + | ^ + +error: derive(Diagnostic): `#[bar]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:260:5 + | +LL | #[bar] + | ^ + | + = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes + +error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:271:5 + | +LL | #[bar = "..."] + | ^ + +error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:282:5 + | +LL | #[bar("...")] + | ^ + | + = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes + +error: unexpected unsupported untagged union + --> $DIR/subdiagnostic-derive-inline.rs:298:1 + | +LL | / union AC { +LL | | +LL | | span: u32, +LL | | b: u64, +LL | | } + | |_^ + +error: expected this path to be an identifier + --> $DIR/subdiagnostic-derive-inline.rs:313:28 + | +LL | #[label("example message", no_crate::example)] + | ^^^^^^^^^^^^^^^^^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/subdiagnostic-derive-inline.rs:326:5 + | +LL | #[primary_span] + | ^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive-inline.rs:323:5 + | +LL | #[primary_span] + | ^ + +error: derive(Diagnostic): subdiagnostic kind not specified + --> $DIR/subdiagnostic-derive-inline.rs:332:8 + | +LL | struct AG { + | ^^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/subdiagnostic-derive-inline.rs:369:47 + | +LL | #[suggestion("example message", code = "...", code = "...")] + | ^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive-inline.rs:369:33 + | +LL | #[suggestion("example message", code = "...", code = "...")] + | ^^^^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/subdiagnostic-derive-inline.rs:387:5 + | +LL | #[applicability] + | ^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive-inline.rs:384:5 + | +LL | #[applicability] + | ^ + +error: derive(Diagnostic): the `#[applicability]` attribute can only be applied to fields of type `Applicability` + --> $DIR/subdiagnostic-derive-inline.rs:397:5 + | +LL | #[applicability] + | ^ + +error: derive(Diagnostic): suggestion without `code = "..."` + --> $DIR/subdiagnostic-derive-inline.rs:410:1 + | +LL | #[suggestion("example message")] + | ^ + +error: derive(Diagnostic): invalid applicability + --> $DIR/subdiagnostic-derive-inline.rs:420:63 + | +LL | #[suggestion("example message", code = "...", applicability = "foo")] + | ^^^^^ + +error: derive(Diagnostic): suggestion without `#[primary_span]` field + --> $DIR/subdiagnostic-derive-inline.rs:438:1 + | +LL | #[suggestion("example message", code = "...")] + | ^ + +error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum + --> $DIR/subdiagnostic-derive-inline.rs:452:1 + | +LL | #[label] + | ^ + +error: derive(Diagnostic): `var` doesn't refer to a field on this type + --> $DIR/subdiagnostic-derive-inline.rs:472:40 + | +LL | #[suggestion("example message", code = "{var}", applicability = "machine-applicable")] + | ^^^^^^^ + +error: derive(Diagnostic): `var` doesn't refer to a field on this type + --> $DIR/subdiagnostic-derive-inline.rs:491:44 + | +LL | #[suggestion("example message", code = "{var}", applicability = "machine-applicable")] + | ^^^^^^^ + +error: derive(Diagnostic): `#[suggestion_part]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:514:5 + | +LL | #[suggestion_part] + | ^ + | + = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead + +error: derive(Diagnostic): `#[suggestion_part(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:517:5 + | +LL | #[suggestion_part(code = "...")] + | ^ + | + = help: `#[suggestion_part(...)]` is only valid in multipart suggestions + +error: derive(Diagnostic): suggestion without `#[primary_span]` field + --> $DIR/subdiagnostic-derive-inline.rs:511:1 + | +LL | #[suggestion("example message", code = "...")] + | ^ + +error: derive(Diagnostic): invalid nested attribute + --> $DIR/subdiagnostic-derive-inline.rs:526:43 + | +LL | #[multipart_suggestion("example message", code = "...", applicability = "machine-applicable")] + | ^^^^ + | + = help: only `style` and `applicability` are valid nested attributes + +error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields + --> $DIR/subdiagnostic-derive-inline.rs:526:1 + | +LL | #[multipart_suggestion("example message", code = "...", applicability = "machine-applicable")] + | ^ + +error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` + --> $DIR/subdiagnostic-derive-inline.rs:536:5 + | +LL | #[suggestion_part] + | ^ + +error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` + --> $DIR/subdiagnostic-derive-inline.rs:544:5 + | +LL | #[suggestion_part()] + | ^ + +error: derive(Diagnostic): `#[primary_span]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:553:5 + | +LL | #[primary_span] + | ^ + | + = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` + +error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields + --> $DIR/subdiagnostic-derive-inline.rs:550:1 + | +LL | #[multipart_suggestion("example message")] + | ^ + +error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` + --> $DIR/subdiagnostic-derive-inline.rs:561:5 + | +LL | #[suggestion_part] + | ^ + +error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` + --> $DIR/subdiagnostic-derive-inline.rs:564:5 + | +LL | #[suggestion_part()] + | ^ + +error: derive(Diagnostic): `code` is the only valid nested attribute + --> $DIR/subdiagnostic-derive-inline.rs:567:23 + | +LL | #[suggestion_part(foo = "bar")] + | ^^^ + +error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + --> $DIR/subdiagnostic-derive-inline.rs:571:5 + | +LL | #[suggestion_part(code = "...")] + | ^ + +error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` + --> $DIR/subdiagnostic-derive-inline.rs:574:5 + | +LL | #[suggestion_part()] + | ^ + +error: expected `,` + --> $DIR/subdiagnostic-derive-inline.rs:567:27 + | +LL | #[suggestion_part(foo = "bar")] + | ^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/subdiagnostic-derive-inline.rs:582:37 + | +LL | #[suggestion_part(code = "...", code = ",,,")] + | ^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive-inline.rs:582:23 + | +LL | #[suggestion_part(code = "...", code = ",,,")] + | ^^^^ + +error: derive(Diagnostic): `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` + --> $DIR/subdiagnostic-derive-inline.rs:611:5 + | +LL | #[applicability] + | ^ + +error: derive(Diagnostic): expected exactly one string literal for `code = ...` + --> $DIR/subdiagnostic-derive-inline.rs:659:28 + | +LL | #[suggestion_part(code("foo"))] + | ^^^^^ + +error: unexpected token, expected `)` + --> $DIR/subdiagnostic-derive-inline.rs:659:28 + | +LL | #[suggestion_part(code("foo"))] + | ^^^^^ + +error: derive(Diagnostic): expected exactly one string literal for `code = ...` + --> $DIR/subdiagnostic-derive-inline.rs:669:28 + | +LL | #[suggestion_part(code("foo", "bar"))] + | ^^^^^ + +error: unexpected token, expected `)` + --> $DIR/subdiagnostic-derive-inline.rs:669:28 + | +LL | #[suggestion_part(code("foo", "bar"))] + | ^^^^^ + +error: derive(Diagnostic): expected exactly one string literal for `code = ...` + --> $DIR/subdiagnostic-derive-inline.rs:679:28 + | +LL | #[suggestion_part(code(3))] + | ^ + +error: unexpected token, expected `)` + --> $DIR/subdiagnostic-derive-inline.rs:679:28 + | +LL | #[suggestion_part(code(3))] + | ^ + +error: derive(Diagnostic): expected exactly one string literal for `code = ...` + --> $DIR/subdiagnostic-derive-inline.rs:689:28 + | +LL | #[suggestion_part(code())] + | ^ + +error: expected string literal + --> $DIR/subdiagnostic-derive-inline.rs:698:30 + | +LL | #[suggestion_part(code = 3)] + | ^ + +error: derive(Diagnostic): attribute specified multiple times + --> $DIR/subdiagnostic-derive-inline.rs:740:1 + | +LL | #[suggestion("example message", code = "", style = "hidden", style = "normal")] + | ^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive-inline.rs:740:1 + | +LL | #[suggestion("example message", code = "", style = "hidden", style = "normal")] + | ^ + +error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:749:1 + | +LL | #[suggestion_hidden("example message", code = "")] + | ^ + | + = help: Use `#[suggestion(..., style = "hidden")]` instead + +error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:757:1 + | +LL | #[suggestion_hidden("example message", code = "", style = "normal")] + | ^ + | + = help: Use `#[suggestion(..., style = "hidden")]` instead + +error: derive(Diagnostic): invalid suggestion style + --> $DIR/subdiagnostic-derive-inline.rs:765:52 + | +LL | #[suggestion("example message", code = "", style = "foo")] + | ^^^^^ + | + = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` + +error: expected string literal + --> $DIR/subdiagnostic-derive-inline.rs:773:52 + | +LL | #[suggestion("example message", code = "", style = 42)] + | ^^ + +error: expected `=` + --> $DIR/subdiagnostic-derive-inline.rs:781:49 + | +LL | #[suggestion("example message", code = "", style)] + | ^ + +error: expected `=` + --> $DIR/subdiagnostic-derive-inline.rs:789:49 + | +LL | #[suggestion("example message", code = "", style("foo"))] + | ^ + +error: derive(Diagnostic): `#[primary_span]` is not a valid attribute + --> $DIR/subdiagnostic-derive-inline.rs:800:5 + | +LL | #[primary_span] + | ^ + | + = note: there must be exactly one primary span + = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead + +error: derive(Diagnostic): suggestion without `#[primary_span]` field + --> $DIR/subdiagnostic-derive-inline.rs:797:1 + | +LL | #[suggestion("example message", code = "")] + | ^ + +error: cannot find attribute `foo` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:65:3 + | +LL | #[foo] + | ^^^ + +error: cannot find attribute `foo` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:149:3 + | +LL | #[foo] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:163:7 + | +LL | #[bar] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:175:7 + | +LL | #[bar = "..."] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:187:7 + | +LL | #[bar = 4] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:199:7 + | +LL | #[bar("...")] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:260:7 + | +LL | #[bar] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:271:7 + | +LL | #[bar = "..."] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive-inline.rs:282:7 + | +LL | #[bar("...")] + | ^^^ + +error: aborting due to 82 previous errors + diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs deleted file mode 100644 index c837372a7a7a..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ /dev/null @@ -1,839 +0,0 @@ -//@ check-fail -// Tests error conditions for specifying subdiagnostics using #[derive(Subdiagnostic)] - -// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, -// changing the output of this test. Since Subdiagnostic is strictly internal to the compiler -// the test is just ignored on stable and beta: -//@ ignore-stage1 -//@ ignore-beta -//@ ignore-stable - -#![feature(rustc_private)] -#![crate_type = "lib"] - -extern crate rustc_errors; -extern crate rustc_fluent_macro; -extern crate rustc_macros; -extern crate rustc_session; -extern crate rustc_span; - -use rustc_errors::{Applicability, DiagMessage, SubdiagMessage}; -use rustc_macros::Subdiagnostic; -use rustc_span::Span; - -rustc_fluent_macro::fluent_messages! { "./example.ftl" } - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct A { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -enum B { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, - #[label(no_crate_example)] - B { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -//~^ ERROR label without `#[primary_span]` field -struct C { - var: String, -} - -#[derive(Subdiagnostic)] -#[label] -//~^ ERROR diagnostic slug must be first argument -struct D { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[foo] -//~^ ERROR `#[foo]` is not a valid attribute -//~^^ ERROR cannot find attribute `foo` in this scope -struct E { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label = "..."] -//~^ ERROR `#[label = ...]` is not a valid attribute -struct F { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(bug = "...")] -//~^ ERROR only `no_span` is a valid nested attribute -//~| ERROR diagnostic slug must be first argument -struct G { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label("...")] -//~^ ERROR failed to resolve: you might be missing crate `core` -//~| NOTE you might be missing crate `core` -struct H { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(slug = 4)] -//~^ ERROR only `no_span` is a valid nested attribute -//~| ERROR diagnostic slug must be first argument -struct J { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(slug("..."))] -//~^ ERROR only `no_span` is a valid nested attribute -//~| ERROR diagnostic slug must be first argument -struct K { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(slug)] -//~^ ERROR cannot find value `slug` in module `crate::fluent_generated` -//~^^ NOTE not found in `crate::fluent_generated` -struct L { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label()] -//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute -struct M { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example, code = "...")] -//~^ ERROR only `no_span` is a valid nested attribute -struct N { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example, applicability = "machine-applicable")] -//~^ ERROR only `no_span` is a valid nested attribute -struct O { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[foo] -//~^ ERROR cannot find attribute `foo` in this scope -//~^^ ERROR unsupported type attribute for subdiagnostic enum -enum P { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum Q { - #[bar] - //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum R { - #[bar = "..."] - //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum S { - #[bar = 4] - //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum T { - #[bar("...")] - //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum U { - #[label(code = "...")] - //~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute - //~| ERROR only `no_span` is a valid nested attribute - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum V { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, - B { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -//~^ ERROR label without `#[primary_span]` field -struct W { - #[primary_span] - //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - span: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct X { - #[primary_span] - span: Span, - #[applicability] - //~^ ERROR `#[applicability]` is only valid on suggestions - applicability: Applicability, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct Y { - #[primary_span] - span: Span, - #[bar] - //~^ ERROR `#[bar]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - bar: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct Z { - #[primary_span] - span: Span, - #[bar = "..."] - //~^ ERROR `#[bar = ...]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - bar: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct AA { - #[primary_span] - span: Span, - #[bar("...")] - //~^ ERROR `#[bar(...)]` is not a valid attribute - //~^^ ERROR cannot find attribute `bar` in this scope - bar: String, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct AB { - #[primary_span] - span: Span, - #[skip_arg] - z: Z, -} - -#[derive(Subdiagnostic)] -union AC { - //~^ ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` - span: u32, - b: u64, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -#[label(no_crate_example)] -struct AD { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example, no_crate::example)] -//~^ ERROR a diagnostic slug must be the first argument to the attribute -struct AE { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct AF { - #[primary_span] - //~^ NOTE previously specified here - span_a: Span, - #[primary_span] - //~^ ERROR specified multiple times - span_b: Span, -} - -#[derive(Subdiagnostic)] -struct AG { - //~^ ERROR subdiagnostic kind not specified - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AH { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, - var: String, -} - -#[derive(Subdiagnostic)] -enum AI { - #[suggestion(no_crate_example, code = "...")] - A { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, - var: String, - }, - #[suggestion(no_crate_example, code = "...")] - B { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...", code = "...")] -//~^ ERROR specified multiple times -//~^^ NOTE previously specified here -struct AJ { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AK { - #[primary_span] - span: Span, - #[applicability] - //~^ NOTE previously specified here - applicability_a: Applicability, - #[applicability] - //~^ ERROR specified multiple times - applicability_b: Applicability, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AL { - #[primary_span] - span: Span, - #[applicability] - //~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability` - applicability: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -struct AM { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example)] -//~^ ERROR suggestion without `code = "..."` -struct AN { - #[primary_span] - span: Span, - #[applicability] - applicability: Applicability, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...", applicability = "foo")] -//~^ ERROR invalid applicability -struct AO { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[help(no_crate_example)] -struct AP { - var: String, -} - -#[derive(Subdiagnostic)] -#[note(no_crate_example)] -struct AQ; - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -//~^ ERROR suggestion without `#[primary_span]` field -struct AR { - var: String, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] -struct AS { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[label] -//~^ ERROR unsupported type attribute for subdiagnostic enum -enum AT { - #[label(no_crate_example)] - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] -struct AU { - #[primary_span] - span: Span, - var: String, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] -//~^ ERROR `var` doesn't refer to a field on this type -struct AV { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -enum AW { - #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - A { - #[primary_span] - span: Span, - var: String, - }, -} - -#[derive(Subdiagnostic)] -enum AX { - #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - //~^ ERROR `var` doesn't refer to a field on this type - A { - #[primary_span] - span: Span, - }, -} - -#[derive(Subdiagnostic)] -#[warning(no_crate_example)] -struct AY {} - -#[derive(Subdiagnostic)] -#[warning(no_crate_example)] -struct AZ { - #[primary_span] - span: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "...")] -//~^ ERROR suggestion without `#[primary_span]` field -struct BA { - #[suggestion_part] - //~^ ERROR `#[suggestion_part]` is not a valid attribute - span: Span, - #[suggestion_part(code = "...")] - //~^ ERROR `#[suggestion_part(...)]` is not a valid attribute - span2: Span, - #[applicability] - applicability: Applicability, - var: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] -//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields -//~| ERROR invalid nested attribute -struct BBa { - var: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BBb { - #[suggestion_part] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span1: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BBc { - #[suggestion_part()] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span1: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -//~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields -struct BC { - #[primary_span] - //~^ ERROR `#[primary_span]` is not a valid attribute - span: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BD { - #[suggestion_part] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span1: Span, - #[suggestion_part()] - //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` - span2: Span, - #[suggestion_part(foo = "bar")] - //~^ ERROR `code` is the only valid nested attribute - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` - span4: Span, - #[suggestion_part(code = "...")] - //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - s1: String, - #[suggestion_part()] - //~^ ERROR the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - s2: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BE { - #[suggestion_part(code = "...", code = ",,,")] - //~^ ERROR specified multiple times - //~| NOTE previously specified here - span: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BF { - #[suggestion_part(code = "(")] - first: Span, - #[suggestion_part(code = ")")] - second: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BG { - #[applicability] - appl: Applicability, - #[suggestion_part(code = "(")] - first: Span, - #[suggestion_part(code = ")")] - second: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BH { - #[applicability] - //~^ ERROR `#[applicability]` has no effect - appl: Applicability, - #[suggestion_part(code = "(")] - first: Span, - #[suggestion_part(code = ")")] - second: Span, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] -struct BI { - #[suggestion_part(code = "")] - spans: Vec, -} - -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct BJ { - #[primary_span] - span: Span, - r#type: String, -} - -/// with a doc comment on the type.. -#[derive(Subdiagnostic)] -#[label(no_crate_example)] -struct BK { - /// ..and the field - #[primary_span] - span: Span, -} - -/// with a doc comment on the type.. -#[derive(Subdiagnostic)] -enum BL { - /// ..and the variant.. - #[label(no_crate_example)] - Foo { - /// ..and the field - #[primary_span] - span: Span, - }, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BM { - #[suggestion_part(code("foo"))] - //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BN { - #[suggestion_part(code("foo", "bar"))] - //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BO { - #[suggestion_part(code(3))] - //~^ ERROR expected exactly one string literal for `code = ...` - //~| ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion(no_crate_example)] -struct BP { - #[suggestion_part(code())] - //~^ ERROR expected exactly one string literal for `code = ...` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -//~^ ERROR cannot find value `__code_29` in this scope -//~| NOTE in this expansion -//~| NOTE not found in this scope -#[multipart_suggestion(no_crate_example)] -struct BQ { - #[suggestion_part(code = 3)] - //~^ ERROR failed to resolve: you might be missing crate `core` - //~| NOTE you might be missing crate `core` - span: Span, - r#type: String, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "")] -struct SuggestionStyleDefault { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "short")] -struct SuggestionStyleShort { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "hidden")] -struct SuggestionStyleHidden { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "verbose")] -struct SuggestionStyleVerbose { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "tool-only")] -struct SuggestionStyleToolOnly { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] -//~^ ERROR specified multiple times -//~| NOTE previously specified here -struct SuggestionStyleTwice { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion_hidden(no_crate_example, code = "")] -//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute -struct SuggestionStyleOldSyntax { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion_hidden(no_crate_example, code = "", style = "normal")] -//~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute -struct SuggestionStyleOldAndNewSyntax { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = "foo")] -//~^ ERROR invalid suggestion style -struct SuggestionStyleInvalid1 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style = 42)] -//~^ ERROR expected `= "xxx"` -struct SuggestionStyleInvalid2 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style)] -//~^ ERROR a diagnostic slug must be the first argument to the attribute -struct SuggestionStyleInvalid3 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "", style("foo"))] -//~^ ERROR expected `= "xxx"` -//~| ERROR failed to resolve: you might be missing crate `core` -//~| NOTE you might be missing crate `core` -struct SuggestionStyleInvalid4 { - #[primary_span] - sub: Span, -} - -#[derive(Subdiagnostic)] -#[suggestion(no_crate_example, code = "")] -//~^ ERROR suggestion without `#[primary_span]` field -struct PrimarySpanOnVec { - #[primary_span] - //~^ ERROR `#[primary_span]` is not a valid attribute - //~| NOTE there must be exactly one primary span - sub: Vec, -} - -#[derive(Subdiagnostic)] -struct NestedParent { - #[subdiagnostic] - single_sub: A, - #[subdiagnostic] - option_sub: Option, - #[subdiagnostic] - vec_sub: Vec, -} diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr deleted file mode 100644 index 0ae7ba4c4973..000000000000 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ /dev/null @@ -1,573 +0,0 @@ -error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:51:1 - | -LL | #[label(no_crate_example)] - | ^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:58:1 - | -LL | #[label] - | ^ - -error: derive(Diagnostic): `#[foo]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:67:1 - | -LL | #[foo] - | ^ - -error: derive(Diagnostic): `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:77:1 - | -LL | #[label = "..."] - | ^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:86:9 - | -LL | #[label(bug = "...")] - | ^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:86:1 - | -LL | #[label(bug = "...")] - | ^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:106:9 - | -LL | #[label(slug = 4)] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:106:1 - | -LL | #[label(slug = 4)] - | ^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:116:9 - | -LL | #[label(slug("..."))] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:116:1 - | -LL | #[label(slug("..."))] - | ^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:136:1 - | -LL | #[label()] - | ^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:145:27 - | -LL | #[label(no_crate_example, code = "...")] - | ^^^^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:154:27 - | -LL | #[label(no_crate_example, applicability = "machine-applicable")] - | ^^^^^^^^^^^^^ - -error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:163:1 - | -LL | #[foo] - | ^ - -error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:177:5 - | -LL | #[bar] - | ^ - -error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:189:5 - | -LL | #[bar = "..."] - | ^ - -error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:201:5 - | -LL | #[bar = 4] - | ^ - -error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:213:5 - | -LL | #[bar("...")] - | ^ - -error: derive(Diagnostic): only `no_span` is a valid nested attribute - --> $DIR/subdiagnostic-derive.rs:225:13 - | -LL | #[label(code = "...")] - | ^^^^ - -error: derive(Diagnostic): diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:225:5 - | -LL | #[label(code = "...")] - | ^ - -error: derive(Diagnostic): the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:254:5 - | -LL | #[primary_span] - | ^ - -error: derive(Diagnostic): label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:251:1 - | -LL | #[label(no_crate_example)] - | ^ - -error: derive(Diagnostic): `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:264:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:274:5 - | -LL | #[bar] - | ^ - | - = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes - -error: derive(Diagnostic): `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:285:5 - | -LL | #[bar = "..."] - | ^ - -error: derive(Diagnostic): `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:296:5 - | -LL | #[bar("...")] - | ^ - | - = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes - -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:328:44 - | -LL | #[label(no_crate_example, no_crate::example)] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:341:5 - | -LL | #[primary_span] - | ^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:338:5 - | -LL | #[primary_span] - | ^ - -error: derive(Diagnostic): subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:347:8 - | -LL | struct AG { - | ^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:384:46 - | -LL | #[suggestion(no_crate_example, code = "...", code = "...")] - | ^^^^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:384:32 - | -LL | #[suggestion(no_crate_example, code = "...", code = "...")] - | ^^^^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:402:5 - | -LL | #[applicability] - | ^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:399:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:412:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:425:1 - | -LL | #[suggestion(no_crate_example)] - | ^ - -error: derive(Diagnostic): invalid applicability - --> $DIR/subdiagnostic-derive.rs:435:62 - | -LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] - | ^^^^^ - -error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:453:1 - | -LL | #[suggestion(no_crate_example, code = "...")] - | ^ - -error: derive(Diagnostic): unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:467:1 - | -LL | #[label] - | ^ - -error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:487:39 - | -LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - | ^^^^^^^ - -error: derive(Diagnostic): `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:506:43 - | -LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] - | ^^^^^^^ - -error: derive(Diagnostic): `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:529:5 - | -LL | #[suggestion_part] - | ^ - | - = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead - -error: derive(Diagnostic): `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:532:5 - | -LL | #[suggestion_part(code = "...")] - | ^ - | - = help: `#[suggestion_part(...)]` is only valid in multipart suggestions - -error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:526:1 - | -LL | #[suggestion(no_crate_example, code = "...")] - | ^ - -error: derive(Diagnostic): invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:541:42 - | -LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] - | ^^^^ - | - = help: only `no_span`, `style` and `applicability` are valid nested attributes - -error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:541:1 - | -LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:551:5 - | -LL | #[suggestion_part] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:559:5 - | -LL | #[suggestion_part()] - | ^ - -error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:568:5 - | -LL | #[primary_span] - | ^ - | - = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` - -error: derive(Diagnostic): multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:565:1 - | -LL | #[multipart_suggestion(no_crate_example)] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:576:5 - | -LL | #[suggestion_part] - | ^ - -error: derive(Diagnostic): `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:579:5 - | -LL | #[suggestion_part()] - | ^ - -error: derive(Diagnostic): `code` is the only valid nested attribute - --> $DIR/subdiagnostic-derive.rs:582:23 - | -LL | #[suggestion_part(foo = "bar")] - | ^^^ - -error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:587:5 - | -LL | #[suggestion_part(code = "...")] - | ^ - -error: derive(Diagnostic): the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:590:5 - | -LL | #[suggestion_part()] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:598:37 - | -LL | #[suggestion_part(code = "...", code = ",,,")] - | ^^^^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:598:23 - | -LL | #[suggestion_part(code = "...", code = ",,,")] - | ^^^^ - -error: derive(Diagnostic): `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive.rs:627:5 - | -LL | #[applicability] - | ^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:675:34 - | -LL | #[suggestion_part(code("foo"))] - | ^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:686:41 - | -LL | #[suggestion_part(code("foo", "bar"))] - | ^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:697:30 - | -LL | #[suggestion_part(code(3))] - | ^ - -error: derive(Diagnostic): expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:708:29 - | -LL | #[suggestion_part(code())] - | ^ - -error: derive(Diagnostic): attribute specified multiple times - --> $DIR/subdiagnostic-derive.rs:763:1 - | -LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] - | ^ - | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:763:1 - | -LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] - | ^ - -error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:772:1 - | -LL | #[suggestion_hidden(no_crate_example, code = "")] - | ^ - | - = help: Use `#[suggestion(..., style = "hidden")]` instead - -error: derive(Diagnostic): `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:780:1 - | -LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] - | ^ - | - = help: Use `#[suggestion(..., style = "hidden")]` instead - -error: derive(Diagnostic): invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:788:51 - | -LL | #[suggestion(no_crate_example, code = "", style = "foo")] - | ^^^^^ - | - = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` - -error: derive(Diagnostic): expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:796:49 - | -LL | #[suggestion(no_crate_example, code = "", style = 42)] - | ^ - -error: derive(Diagnostic): a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:804:48 - | -LL | #[suggestion(no_crate_example, code = "", style)] - | ^ - -error: derive(Diagnostic): expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:812:48 - | -LL | #[suggestion(no_crate_example, code = "", style("foo"))] - | ^ - -error: derive(Diagnostic): `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:825:5 - | -LL | #[primary_span] - | ^ - | - = note: there must be exactly one primary span - = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead - -error: derive(Diagnostic): suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:822:1 - | -LL | #[suggestion(no_crate_example, code = "")] - | ^ - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:96:9 - | -LL | #[label("...")] - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:312:1 - | -LL | union AC { - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:582:27 - | -LL | #[suggestion_part(foo = "bar")] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:675:28 - | -LL | #[suggestion_part(code("foo"))] - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:686:28 - | -LL | #[suggestion_part(code("foo", "bar"))] - | ^^^^^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:697:28 - | -LL | #[suggestion_part(code(3))] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:720:30 - | -LL | #[suggestion_part(code = 3)] - | ^ you might be missing crate `core` - -error[E0433]: failed to resolve: you might be missing crate `core` - --> $DIR/subdiagnostic-derive.rs:812:48 - | -LL | #[suggestion(no_crate_example, code = "", style("foo"))] - | ^ you might be missing crate `core` - -error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:67:3 - | -LL | #[foo] - | ^^^ - -error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:163:3 - | -LL | #[foo] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:177:7 - | -LL | #[bar] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:189:7 - | -LL | #[bar = "..."] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:201:7 - | -LL | #[bar = 4] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:213:7 - | -LL | #[bar("...")] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:274:7 - | -LL | #[bar] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:285:7 - | -LL | #[bar = "..."] - | ^^^ - -error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:296:7 - | -LL | #[bar("...")] - | ^^^ - -error[E0425]: cannot find value `slug` in module `crate::fluent_generated` - --> $DIR/subdiagnostic-derive.rs:126:9 - | -LL | #[label(slug)] - | ^^^^ not found in `crate::fluent_generated` - -error[E0425]: cannot find value `__code_29` in this scope - --> $DIR/subdiagnostic-derive.rs:714:10 - | -LL | #[derive(Subdiagnostic)] - | ^^^^^^^^^^^^^ not found in this scope - | - = note: this error originates in the derive macro `Subdiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 86 previous errors - -Some errors have detailed explanations: E0425, E0433. -For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/README.md b/tests/ui/README.md index 25e870fd8f18..16cdde08431c 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -10,17 +10,23 @@ These tests deal with *Application Binary Interfaces* (ABI), mostly relating to Tests for unsupported ABIs can be made cross-platform by using the `extern "rust-invalid"` ABI, which is considered unsupported on every platform. +## `tests/ui/alloc-error` + +These tests exercise alloc error handling. + +See . + ## `tests/ui/allocator` These tests exercise `#![feature(allocator_api)]` and the `#[global_allocator]` attribute. See [Allocator traits and `std::heap` #32838](https://github.com/rust-lang/rust/issues/32838). -## `tests/ui/alloc-error` +## `tests/ui/annotate-moves` -These tests exercise alloc error handling. +These tests exercise the `annotate-moves` feature. -See . +See [`annotate-moves` | The Unstable book](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/annotate-moves.html) ## `tests/ui/annotate-snippet` @@ -34,20 +40,26 @@ These tests exercise the [`annotate-snippets`]-based emitter implementation. These tests deal with anonymous parameters (no name, only type), a deprecated feature that becomes a hard error in Edition 2018. +## `tests/ui/any` + +These tests exercise the `try_as_dyn` feature. + +See [`core::any::try_as_dyn`](https://doc.rust-lang.org/nightly/core/any/fn.try_as_dyn.html) + ## `tests/ui/argfile`: External files providing command line arguments These tests exercise rustc reading command line arguments from an externally provided argfile (`@argsfile`). See [Implement `@argsfile` to read arguments from command line #63576](https://github.com/rust-lang/rust/issues/63576). -## `tests/ui/array-slice-vec`: Arrays, slices and vectors - -Exercises various aspects surrounding basic collection types `[]`, `&[]` and `Vec`. E.g. type-checking, out-of-bounds indices, attempted instructions which are allowed in other programming languages, and more. - ## `tests/ui/argument-suggestions`: Argument suggestions Calling a function with the wrong number of arguments causes a compilation failure, but the compiler is able to, in some cases, provide suggestions on how to fix the error, such as which arguments to add or delete. These tests exercise the quality of such diagnostics. +## `tests/ui/array-slice-vec`: Arrays, slices and vectors + +Exercises various aspects surrounding basic collection types `[]`, `&[]` and `Vec`. E.g. type-checking, out-of-bounds indices, attempted instructions which are allowed in other programming languages, and more. + ## `tests/ui/asm`: `asm!` macro These tests exercise the `asm!` macro, which is used for adding inline assembly. @@ -160,10 +172,6 @@ See: - [`std::box::Boxed`](https://doc.rust-lang.org/std/boxed/struct.Box.html) - [Tracking issue for `box_patterns` feature #29641](https://github.com/rust-lang/rust/issues/29641) -## `tests/ui/btreemap/`: B-Tree Maps - -Tests focused on `BTreeMap` collections and their compiler interactions. E.g. collection patterns, iterator behavior, and trait implementations specific to `BTreeMap`. See [`std::collections::BTreeMap`](https://doc.rust-lang.org/std/collections/struct.BTreeMap.html). - ## `tests/ui/builtin-superkinds/`: Built-in Trait Hierarchy Tests Tests for built-in trait hierarchy (Send, Sync, Sized, etc.) and their supertrait relationships. E.g. auto traits and marker trait constraints. @@ -172,6 +180,10 @@ See [RFC 3729: Hierarchy of Sized traits](https://github.com/rust-lang/rfcs/pull Defining custom auto traits with the `auto` keyword belongs to `tests/ui/auto-traits/` instead. +## `tests/ui/c-variadic`: C Variadic Function + +Tests for FFI with C varargs (`va_list`). + ## `tests/ui/cast/`: Type Casting Tests for type casting using the `as` operator. Includes tests for valid/invalid casts between primitive types, trait objects, and custom types. For example, check that trying to cast `i32` into `bool` results in a helpful error message. @@ -190,16 +202,16 @@ Tests for the `--check-cfg` compiler mechanism for checking cfg configurations, See [Checking conditional configurations | The rustc book](https://doc.rust-lang.org/rustc/check-cfg.html). -## `tests/ui/closure_context/`: Closure type inference in context - -Tests for closure type inference with respect to surrounding scopes, mostly quality of diagnostics. - ## `tests/ui/closure-expected-type/`: Closure type inference Tests targeted at how we deduce the types of closure arguments. This process is a result of some heuristics which take into account the *expected type* we have alongside the *actual types* that we get from inputs. **FIXME**: Appears to have significant overlap with `tests/ui/closure_context` and `tests/ui/functions-closures/closure-expected-type`. Needs further investigation. +## `tests/ui/closure_context`: Closure type inference in context + +Tests for closure type inference with respect to surrounding scopes, mostly quality of diagnostics. + ## `tests/ui/closures/`: General Closure Tests Any closure-focused tests that does not fit in the other more specific closure subdirectories belong here. E.g. syntax, `move`, lifetimes. @@ -244,6 +256,12 @@ See: This directory only contains one highly specific test. Other coinduction tests can be found down the deeply located `tests/ui/traits/next-solver/cycles/coinduction/` subdirectory. +## `tests/ui/collections` + +These tests exercise the `collections` library. For example, `BTreeMap` and `HashMap`. + +See [`std::collections`](https://doc.rust-lang.org/std/collections/index.html) + ## `tests/ui/command/`: `std::process::Command` This directory is actually for the standard library [`std::process::Command`](https://doc.rust-lang.org/std/process/struct.Command.html) type, where some tests are too difficult or inconvenient to write as unit tests or integration tests within the standard library itself. @@ -256,6 +274,10 @@ Some traits' implementation must be compared with their definition, checking for This subdirectory is *not* intended comparison traits (`PartialEq`, `Eq`, `PartialOrd`, `Ord`). +## `tests/ui/compile-flags/` + +Tests for compile flags. + ## `tests/ui/compiletest-self-test/`: compiletest "meta" tests Meta test suite of the test harness `compiletest` itself. @@ -281,10 +303,6 @@ See: - [Tracking Issue for complex generic constants: `feature(generic_const_exprs)` #76560](https://github.com/rust-lang/rust/issues/76560) - [Const generics | Reference](https://doc.rust-lang.org/reference/items/generics.html#const-generics) -## `tests/ui/const_prop/`: Constant Propagation - -Tests exercising `ConstProp` mir-opt pass (mostly regression tests). See . - ## `tests/ui/const-ptr/`: Constant Pointers Tests exercise const raw pointers. E.g. pointer arithmetic, casting and dereferencing, always with a `const`. @@ -295,6 +313,10 @@ See: - [`std::ptr`](https://doc.rust-lang.org/std/ptr/index.html) - [Pointer types | Reference](https://doc.rust-lang.org/reference/types/pointer.html) +## `tests/ui/const_prop`: Constant Propagation + +Tests exercising `ConstProp` mir-opt pass (mostly regression tests). See . + ## `tests/ui/consts/`: General Constant Evaluation Anything to do with constants, which does not fit in the previous two `const` categories, goes here. This does not always imply use of the `const` keyword - other values considered constant, such as defining an enum variant as `enum Foo { Variant = 5 }` also counts. @@ -324,7 +346,7 @@ Tests for crate resolution and loading behavior, including `extern crate` declar ## `tests/ui/cross/`: Various tests related to the concept of "cross" -**FIXME**: The unifying topic of these tests appears to be that their filenames begin with the word "cross". The similarities end there - one test is about "cross-borrowing" a `Box` into `&T`, while another is about a global trait used "across" files. Some of these terminology are really outdated and does not match the current terminology. Additionally, "cross" is also way too generic, it's easy to confuse with cross-compile. +**FIXME**: The unifying topic of these tests appears to be that their filenames begin with the word "cross". The similarities end there - one test is about "cross-borrowing" a `Box` into `&T`, while another is about a global trait used "across" files. Some of this terminology is really outdated and does not match the current terminology. Additionally, "cross" is also way too generic, it's easy to confuse with cross-compile. ## `tests/ui/cross-crate/`: Cross-Crate Interaction @@ -336,10 +358,6 @@ Tests for `#[bench]`, `#[test_case]` attributes and the `custom_test_frameworks` See [Tracking issue for eRFC 2318, Custom test frameworks #50297](https://github.com/rust-lang/rust/issues/50297). -## `tests/ui/c-variadic/`: C Variadic Function - -Tests for FFI with C varargs (`va_list`). - ## `tests/ui/cycle-trait/`: Trait Cycle Detection Tests for detection and handling of cyclic trait dependencies. @@ -376,12 +394,18 @@ These tests use the unstable command line option `query-dep-graph` to examine th Tests for `#[deprecated]` attribute and `deprecated_in_future` internal lint. -## `tests/ui/deref-patterns/`: `#![feature(deref_patterns)]` and `#![feature(string_deref_patterns)]` +## `tests/ui/deref` + +Tests for `Deref` and `DerefMut` traits. + +## `tests/ui/deref-patterns`: `#![feature(deref_patterns)]` and `#![feature(string_deref_patterns)]` Tests for `#![feature(deref_patterns)]` and `#![feature(string_deref_patterns)]`. See [Deref patterns | The Unstable book](https://doc.rust-lang.org/nightly/unstable-book/language-features/deref-patterns.html). **FIXME**: May have some overlap with `tests/ui/pattern/deref-patterns`. +See [`std::ops::Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html) and [`std::ops::DerefMut`](https://doc.rust-lang.org/std/ops/trait.DerefMut.html) + ## `tests/ui/derived-errors/`: Derived Error Messages Tests for quality of diagnostics involving suppression of cascading errors in some cases to avoid overwhelming the user. @@ -408,6 +432,10 @@ These tests revolve around command-line flags which change the way error/warning **FIXME**: Check redundancy with `annotate-snippet`, which is another emitter. +## `tests/ui/diagnostic-width`: `--diagnostic-width` + +Everything to do with `--diagnostic-width`. + ## `tests/ui/diagnostic_namespace/` Exercises `#[diagnostic::*]` namespaced attributes. See [RFC 3368 Diagnostic attribute namespace](https://github.com/rust-lang/rfcs/blob/master/text/3368-diagnostic-attribute-namespace.md). @@ -416,10 +444,6 @@ Exercises `#[diagnostic::*]` namespaced attributes. See [RFC 3368 Diagnostic att This directory contains tests and infrastructure related to the diagnostics system, including support for translatable diagnostics -## `tests/ui/diagnostic-width/`: `--diagnostic-width` - -Everything to do with `--diagnostic-width`. - ## `tests/ui/did_you_mean/` Tests for miscellaneous suggestions. @@ -432,6 +456,10 @@ Exercises diagnostics for when a code block attempts to gain ownership of a non- Exercises diagnostics for disallowed struct destructuring. +## `tests/ui/dist` + +Tests that require distribution artifacts. + ## `tests/ui/dollar-crate/`: `$crate` used with the `use` keyword There are a few rules - which are checked in this directory - to follow when using `$crate` - it must be used in the start of a `use` line and is a reserved identifier. @@ -463,10 +491,6 @@ Tests for dynamically-sized types (DSTs). See [Dynamically Sized Types | Referen Tests about duplicated symbol names and associated errors, such as using the `#[export_name]` attribute to rename a function with the same name as another function. -## `tests/ui/dynamically-sized-types/`: Dynamically Sized Types - -**FIXME**: should be coalesced with `tests/ui/dst`. - ## `tests/ui/dyn-compatibility/`: Dyn-compatibility Tests for dyn-compatibility of traits. @@ -494,6 +518,10 @@ These tests run in specific Rust editions, such as Rust 2015 or Rust 2018, and c **FIXME**: Maybe regroup `rust-2018`, `rust-2021` and `rust-2024` under this umbrella? +## `tests/ui/eii`: Externally Implementable Items + +Exercises `eii` keyword. + ## `tests/ui/empty/`: Various tests related to the concept of "empty" **FIXME**: These tests need better homes, this is not very informative. @@ -548,6 +576,8 @@ A broad directory for tests on expressions. Tests on the `extern` keyword and `extern` blocks and functions. +**FIXME**: Merge with `tests/ui/abi/extern`. + ## `tests/ui/extern-flag/`: `--extern` command line flag Tests for the `--extern` CLI flag. @@ -556,6 +586,12 @@ Tests for the `--extern` CLI flag. Tests on feature-gating, and the `#![feature(..)]` mechanism itself. +## `tests/ui/ffi/`: Foreign Function Interface + +Tests for the `std::ffi` module. + +See [`std::ffi`](https://doc.rust-lang.org/std/ffi/index.html) + ## `tests/ui/ffi-attrs/`: `#![feature(ffi_const, ffi_pure)]` The `#[ffi_const]` and `#[ffi_pure]` attributes applies clang's `const` and `pure` attributes to foreign functions declarations, respectively. These attributes are the core element of the tests in this category. @@ -565,6 +601,10 @@ See: - [`ffi_const` | The Unstable book](https://doc.rust-lang.org/unstable-book/language-features/ffi-const.html) - [`ffi_pure` | The Unstable book](https://doc.rust-lang.org/beta/unstable-book/language-features/ffi-pure.html) +## `tests/ui/float` + +See: [Tracking Issue for `f16` and `f128` float types #116909](https://github.com/rust-lang/rust/issues/116909) + ## `tests/ui/fmt/` Exercises the `format!` macro. @@ -573,6 +613,16 @@ Exercises the `format!` macro. A broad category of tests on functions. +## `tests/ui/fn_traits` + +Tests for `#![feature(fn_traits)]`. See [`fn_traits` | The Unstable book](https://doc.rust-lang.org/nightly/unstable-book/library-features/fn-traits.html). + +## `tests/ui/for-loop-while` + +Anything to do with loops and `for`, `loop` and `while` keywords to express them. + +**FIXME**: After `ui/for` is merged into this, also carry over its SUMMARY text. + ## `tests/ui/force-inlining/`: `#[rustc_force_inline]` Tests for `#[rustc_force_inline]`, which will force a function to always be labelled as inline by the compiler (it will be inserted at the point of its call instead of being used as a normal function call.) If the compiler is unable to inline the function, an error will be reported. See . @@ -583,12 +633,6 @@ Tests for `extern "C"` and `extern "Rust`. **FIXME**: Check for potential overlap/merge with `ui/c-variadic` and/or `ui/extern`. -## `tests/ui/for-loop-while/` - -Anything to do with loops and `for`, `loop` and `while` keywords to express them. - -**FIXME**: After `ui/for` is merged into this, also carry over its SUMMARY text. - ## `tests/ui/frontmatter/` Tests for `#![feature(frontmatter)]`. See [Tracking Issue for `frontmatter` #136889](https://github.com/rust-lang/rust/issues/136889). @@ -597,12 +641,6 @@ Tests for `#![feature(frontmatter)]`. See [Tracking Issue for `frontmatter` #136 Tests for diagnostics when there may be identically named types that need further qualifications to disambiguate. -## `tests/ui/functional-struct-update/` - -Functional Struct Update is the name for the idiom by which one can write `..` at the end of a struct literal expression to fill in all remaining fields of the struct literal by using `` as the source for them. - -See [RFC 0736 Privacy-respecting Functional Struct Update](https://github.com/rust-lang/rfcs/blob/master/text/0736-privacy-respecting-fru.md). - ## `tests/ui/function-pointer/` Tests on function pointers, such as testing their compatibility with higher-ranked trait bounds. @@ -612,6 +650,12 @@ See: - [Function pointer types | Reference](https://doc.rust-lang.org/reference/types/function-pointer.html) - [Higher-ranked trait bounds | Nomicon](https://doc.rust-lang.org/nomicon/hrtb.html) +## `tests/ui/functional-struct-update/` + +Functional Struct Update is the name for the idiom by which one can write `..` at the end of a struct literal expression to fill in all remaining fields of the struct literal by using `` as the source for them. + +See [RFC 0736 Privacy-respecting Functional Struct Update](https://github.com/rust-lang/rfcs/blob/master/text/0736-privacy-respecting-fru.md). + ## `tests/ui/functions-closures/` Tests on closures. See [Closure expressions | Reference](https://doc.rust-lang.org/reference/expressions/closure-expr.html). @@ -634,10 +678,6 @@ Tests on range patterns where one of the bounds is not a direct value. **FIXME**: Overlaps with `ui/range`. `impossible_range.rs` is particularly suspected to be a duplicate test. -## `tests/ui/hashmap/` - -Tests for the standard library collection [`std::collections::HashMap`](https://doc.rust-lang.org/std/collections/struct.HashMap.html). - ## `tests/ui/higher-ranked/` Tests for higher-ranked trait bounds. @@ -663,14 +703,14 @@ This test category revolves around trait objects with `Sized` having illegal ope Tests on lifetime elision in impl function signatures. See [Lifetime elision | Nomicon](https://doc.rust-lang.org/nomicon/lifetime-elision.html). -## `tests/ui/implied-bounds/` - -See [Implied bounds | Reference](https://doc.rust-lang.org/reference/trait-bounds.html#implied-bounds). - ## `tests/ui/impl-trait/` Tests for trait impls. +## `tests/ui/implied-bounds/` + +See [Implied bounds | Reference](https://doc.rust-lang.org/reference/trait-bounds.html#implied-bounds). + ## `tests/ui/imports/` Tests for module system and imports. @@ -697,12 +737,6 @@ Tests on type inference. Tests for diagnostics on infinitely recursive types without indirection. -## `tests/ui/inherent-impls-overlap-check/` - -Checks that repeating the same function names across separate `impl` blocks triggers an informative error, but not if the `impl` are for different types, such as `Bar` and `Bar`. - -NOTE: This should maybe be a subdirectory within another related to duplicate definitions, such as `tests/ui/duplicate/`. - ## `tests/ui/inline-const/` These tests revolve around the inline `const` block that forces the compiler to const-eval its content. @@ -733,15 +767,9 @@ Various tests related to rejecting invalid inputs. **FIXME**: This is rather uninformative, possibly rehome into more meaningful directories. -## `tests/ui/invalid-compile-flags/` +## `tests/ui/io-checks/`: Input Output -Tests for checking that invalid usage of compiler flags are rejected. - -## `tests/ui/io-checks/` - -Contains a single test. The test tries to output a file into an invalid directory with `-o`, then checks that the result is an error, not an internal compiler error. - -**FIXME**: Rehome to invalid compiler flags maybe. +Tests for I/O related behaviour, covering stdout/stderr handling and error propagation. ## `tests/ui/issues/`: Tests directly related to GitHub issues @@ -808,6 +836,12 @@ Broad directory on lifetimes, including proper specifiers, lifetimes not living These tests exercises numerical limits, such as `[[u8; 1518599999]; 1518600000]`. +## `tests/ui/link-native-libs/` + +Tests for `#[link(name = "", kind = "")]` and `-l` command line flag. + +See [Tracking Issue for linking modifiers for native libraries #81490](https://github.com/rust-lang/rust/issues/81490). + ## `tests/ui/linkage-attr/` Tests for the linkage attribute `#[linkage]` of `#![feature(linkage)]`. @@ -820,12 +854,6 @@ Tests on code which fails during the linking stage, or which contain arguments a See [Linkage | Reference](https://doc.rust-lang.org/reference/linkage.html). -## `tests/ui/link-native-libs/` - -Tests for `#[link(name = "", kind = "")]` and `-l` command line flag. - -See [Tracking Issue for linking modifiers for native libraries #81490](https://github.com/rust-lang/rust/issues/81490). - ## `tests/ui/lint/` Tests for the lint infrastructure, lint levels, lint reasons, etc. @@ -841,6 +869,10 @@ Tests exercising analysis for unused variables, unreachable statements, function **FIXME**: This seems unrelated to "liveness" as defined in the rustc compiler guide. Is this misleadingly named? https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference/lifetime_parameters.html#liveness-and-universal-regions +## `tests/ui/loop-match` + +Tests for `loop` with `match` expressions. + ## `tests/ui/loops/` Tests on the `loop` construct. @@ -877,12 +909,6 @@ See [Tracking issue for allowing overlapping implementations for marker trait #2 Broad category of tests on `match` constructs. -## `tests/ui/meta/`: Tests for compiletest itself - -These tests check the function of the UI test suite at large and Compiletest in itself. - -**FIXME**: This should absolutely be merged with `tests/ui/compiletest-self-test/`. - ## `tests/ui/methods/` A broad category for anything related to methods and method resolution. @@ -911,7 +937,7 @@ Something is missing which could be added to fix (e.g. suggestions). Tests for checking missing trait bounds, and their diagnostics. -**FIMXE**: Maybe a subdirectory of `ui/trait-bounds` would be more appropriate. +**FIXME**: Maybe a subdirectory of `ui/trait-bounds` would be more appropriate. ## `tests/ui/modules/` @@ -947,6 +973,10 @@ See [RFC 3550 New Range](https://github.com/rust-lang/rfcs/blob/master/text/3550 Tests for Non-lexical lifetimes. See [RFC 2094 NLL](https://rust-lang.github.io/rfcs/2094-nll.html). +## `tests/ui/no_std/` + +Tests for where the standard library is disabled through `#![no_std]`. + ## `tests/ui/non_modrs_mods/` Despite the size of the directory, this is a single test, spawning a sprawling `mod` dependency tree and checking its successful build. @@ -957,11 +987,7 @@ Despite the size of the directory, this is a single test, spawning a sprawling ` A very similar principle as `non_modrs_mods`, but with an added inline `mod` statement inside another `mod`'s code block. -**FXIME**: Consider merge with `tests/ui/modules/`, keeping the directory structure. - -## `tests/ui/no_std/` - -Tests for where the standard library is disabled through `#![no_std]`. +**FIXME**: Consider merge with `tests/ui/modules/`, keeping the directory structure. ## `tests/ui/not-panic/` @@ -987,6 +1013,15 @@ Contains a single test. Check that we reject the ancient Rust syntax `x <- y` an **FIXME**: Definitely should be rehomed, maybe to `tests/ui/deprecation/`. +## `tests/ui/offload` + +Exercises the offload feature. + +See: + +- [`std::offload` | rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/offload/internals.html) +- [Tracking Issue for GPU-offload #131513](https://github.com/rust-lang/rust/issues/131513) + ## `tests/ui/offset-of/` Exercises the [`std::mem::offset_of` macro](https://doc.rust-lang.org/beta/std/mem/macro.offset_of.html). @@ -1045,6 +1080,16 @@ Broad category of tests surrounding patterns. See [Patterns | Reference](https:/ **FIXME**: Some overlap with `tests/ui/match/`. +## `tests/ui/pin` + +**FIXME**: Consider merging with `tests/ui/pin-macro`. + +## `tests/ui/pin-ergonomics` + +Exercises the `#![feature(pin_ergonomics)]` feature. + +See [Tracking issue for pin ergonomics #130494](https://github.com/rust-lang/rust/issues/130494) + ## `tests/ui/pin-macro/` See [`std::pin`](https://doc.rust-lang.org/std/pin/). @@ -1065,6 +1110,10 @@ Exercises the `-Z print-type-sizes` flag. Exercises on name privacy. E.g. the meaning of `pub`, `pub(crate)`, etc. +## `tests/ui/proc-macro/` + +Broad category of tests on proc-macros. See [Procedural Macros | Reference](https://doc.rust-lang.org/reference/procedural-macros.html). + ## `tests/ui/process/` Some standard library process tests which are hard to write within standard library crate tests. @@ -1073,10 +1122,6 @@ Some standard library process tests which are hard to write within standard libr Some standard library process termination tests which are hard to write within standard library crate tests. -## `tests/ui/proc-macro/` - -Broad category of tests on proc-macros. See [Procedural Macros | Reference](https://doc.rust-lang.org/reference/procedural-macros.html). - ## `tests/ui/ptr_ops/`: Using operations on a pointer Contains only 2 tests, related to a single issue, which was about an error caused by using addition on a pointer to `i8`. @@ -1109,6 +1154,12 @@ Reachability tests, primarily unreachable code and coercions into the never type **FIXME**: Check for overlap with `ui/liveness`. +## `tests/ui/reborrow` + +Exercises the `#![feature(reborrow)]` feature. + +See [Tracking Issue for Reborrow trait lang experiment #145612](https://github.com/rust-lang/rust/issues/145612) + ## `tests/ui/recursion/` Broad category of tests exercising recursions (compile test and run time), in functions, macros, `type` definitions, and more. @@ -1121,6 +1172,12 @@ Sets a recursion limit on recursive code. **FIXME**: Should be merged with `tests/ui/recursion/`. +## `tests/ui/reflection/` + +Exercises the `#![feature(type_info)]` feature. + +See [Tracking Issue for type_info #146922](https://github.com/rust-lang/rust/issues/146922) + ## `tests/ui/regions/` **FIXME**: Maybe merge with `ui/lifetimes`. @@ -1163,22 +1220,44 @@ Exercises `.rmeta` crate metadata and the `--emit=metadata` cli flag. Tests for runtime environment on which Rust programs are executed. E.g. Unix `SIGPIPE`. -## `tests/ui/rust-{2018,2021,2024}/` +## `tests/ui/rust-2018` -Tests that exercise behaviors and features that are specific to editions. +Tests that exercise behaviors and features specific to the Rust 2018 edition. + +## `tests/ui/rust-2021` + +Tests that exercise behaviors and features specific to the Rust 2021 edition. + +## `tests/ui/rust-2024` + +Tests that exercise behaviors and features specific to the Rust 2024 edition. ## `tests/ui/rustc-env` Tests on environmental variables that affect `rustc`. +## `tests/ui/rustc_public-ir-print` + +Some tests for pretty printing of rustc_public's IR. + ## `tests/ui/rustdoc` Hybrid tests that exercises `rustdoc`, and also some joint `rustdoc`/`rustc` interactions. +## `tests/ui/sanitize-attr` + +Tests for the `#![feature(sanitize)]` attribute. + +See [Sanitize | The Unstable Book](https://doc.rust-lang.org/unstable-book/language-features/sanitize.html). + ## `tests/ui/sanitizer/` Exercises sanitizer support. See [Sanitizer | The rustc book](https://doc.rust-lang.org/unstable-book/compiler-flags/sanitizer.html). +## `tests/ui/scalable-vectors` + +See [Tracking Issue for Scalable Vectors #145052](https://github.com/rust-lang/rust/issues/145052) + ## `tests/ui/self/`: `self` keyword Tests with erroneous ways of using `self`, such as using `this.x` syntax as seen in other languages, having it not be the first argument, or using it in a non-associated function (no `impl` or `trait`). It also contains correct uses of `self` which have previously been observed to cause ICEs. @@ -1217,6 +1296,12 @@ This is a test directory for the specific error case where a lifetime never gets While many tests here involve the `Sized` trait directly, some instead test, for example the slight variations between returning a zero-sized `Vec` and a `Vec` with one item, where one has no known type and the other does. +## `tests/ui/sized-hierarchy` + +Tests for `#![feature(sized_hierarchy)]` attribute. + +See [Tracking Issue for Sized Hierarchy #144404](https://github.com/rust-lang/rust/issues/144404) + ## `tests/ui/span/` An assorted collection of tests that involves specific diagnostic spans. @@ -1231,9 +1316,9 @@ See [Tracking issue for specialization (RFC 1210) #31844](https://github.com/rus Stability attributes used internally by the standard library: `#[stable()]` and `#[unstable()]`. -## `tests/ui/rustc_public-ir-print/` +## `tests/ui/stack-probes` -Some tests for pretty printing of rustc_public's IR. +**FIXME**: Contains a single test, should likely be rehomed to `tests/ui/abi`. ## `tests/ui/stack-protector/`: `-Z stack-protector` command line flag @@ -1365,6 +1450,10 @@ Tests surrounding [`std::mem::transmute`](https://doc.rust-lang.org/std/mem/fn.t Exercises compiler development support flag `-Z treat-err-as-bug`. +## `tests/ui/trimmed-paths/` + +Tests for the `#[doc(hidden)]` items. + ## `tests/ui/trivial-bounds/` `#![feature(trivial_bounds)]`. See [RFC 2056 Allow trivial where clause constraints](https://github.com/rust-lang/rfcs/blob/master/text/2056-allow-trivial-where-clause-constraints.md). @@ -1399,17 +1488,13 @@ Tests for `type` aliases in the context of `enum` variants, such as that applied `#![feature(type_alias_impl_trait)]`. See [Type Alias Impl Trait | The Unstable book](https://doc.rust-lang.org/nightly/unstable-book/language-features/type-alias-impl-trait.html). -## `tests/ui/typeck/` - -General collection of type checking related tests. - ## `tests/ui/type-inference/` General collection of type inference related tests. -## `tests/ui/typeof/` +## `tests/ui/typeck` -`typeof` keyword, reserved but unimplemented. +General collection of type checking related tests. ## `tests/ui/ufcs/` @@ -1421,12 +1506,6 @@ See [RFC 0132 Unified Function Call Syntax](https://github.com/rust-lang/rfcs/bl See [Tracking issue for Fn traits (`unboxed_closures` & `fn_traits` feature)](https://github.com/rust-lang/rust/issues/29625). -## `tests/ui/underscore-imports/` - -See [Underscore imports | Reference](https://doc.rust-lang.org/reference/items/use-declarations.html#underscore-imports). - -**FIXME**: should become a subdirectory of `tests/ui/imports/`. - ## `tests/ui/underscore-lifetime/`: `'_` elided lifetime Exercises [anonymous elided lifetimes](https://doc.rust-lang.org/reference/lifetime-elision.html). @@ -1489,7 +1568,11 @@ See: **FIXME**: Seems to also contain more generic tests that fit in `tests/ui/unsized/`. -## `tests/ui/unused-crate-deps/` +## `tests/ui/unstable-feature-bound` + +Tests for gating and diagnostics when unstable features are used. + +## `tests/ui/unused-crate-deps` Exercises the `unused_crate_dependencies` lint. diff --git a/tests/ui/abi/avr-sram.disable_sram.stderr b/tests/ui/abi/avr-sram.disable_sram.stderr new file mode 100644 index 000000000000..31b9084f73a4 --- /dev/null +++ b/tests/ui/abi/avr-sram.disable_sram.stderr @@ -0,0 +1,12 @@ +warning: target feature `sram` cannot be disabled with `-Ctarget-feature`: devices that have no SRAM are unsupported + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: target feature `sram` must be enabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: 2 warnings emitted + diff --git a/tests/ui/abi/avr-sram.no_sram.stderr b/tests/ui/abi/avr-sram.no_sram.stderr new file mode 100644 index 000000000000..3f74bf66f190 --- /dev/null +++ b/tests/ui/abi/avr-sram.no_sram.stderr @@ -0,0 +1,7 @@ +warning: target feature `sram` must be enabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: 1 warning emitted + diff --git a/tests/ui/abi/avr-sram.rs b/tests/ui/abi/avr-sram.rs new file mode 100644 index 000000000000..0266f7d6b22c --- /dev/null +++ b/tests/ui/abi/avr-sram.rs @@ -0,0 +1,15 @@ +//@ revisions: has_sram no_sram disable_sram +//@ build-pass +//@[has_sram] compile-flags: --target avr-none -C target-cpu=atmega328p +//@[has_sram] needs-llvm-components: avr +//@[no_sram] compile-flags: --target avr-none -C target-cpu=attiny11 +//@[no_sram] needs-llvm-components: avr +//@[disable_sram] compile-flags: --target avr-none -C target-cpu=atmega328p -C target-feature=-sram +//@[disable_sram] needs-llvm-components: avr +//@ ignore-backends: gcc +//[no_sram,disable_sram]~? WARN target feature `sram` must be enabled +//[disable_sram]~? WARN target feature `sram` cannot be disabled with `-Ctarget-feature` + +#![feature(no_core)] +#![no_core] +#![crate_type = "lib"] diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index d050bfcbaa17..6d2ac90c0c97 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -41,7 +41,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index d050bfcbaa17..6d2ac90c0c97 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -41,7 +41,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index 816addd79576..f297aa984dd2 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -52,7 +52,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/cannot-be-called.amdgpu.stderr b/tests/ui/abi/cannot-be-called.amdgpu.stderr new file mode 100644 index 000000000000..039e2d7b4f00 --- /dev/null +++ b/tests/ui/abi/cannot-be-called.amdgpu.stderr @@ -0,0 +1,87 @@ +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:43:8 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:45:8 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:47:8 + | +LL | extern "riscv-interrupt-m" fn riscv_m() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:49:8 + | +LL | extern "riscv-interrupt-s" fn riscv_s() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:51:8 + | +LL | extern "x86-interrupt" fn x86(_x: *const u8) {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:76:22 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:82:25 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:88:26 + | +LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:94:26 + | +LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:100:22 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.avr.stderr b/tests/ui/abi/cannot-be-called.avr.stderr index 2128991d83cd..752292a58705 100644 --- a/tests/ui/abi/cannot-be-called.avr.stderr +++ b/tests/ui/abi/cannot-be-called.avr.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:53:5 + --> $DIR/cannot-be-called.rs:60:5 | LL | avr(); | ^^^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:53:5 + --> $DIR/cannot-be-called.rs:60:5 | LL | avr(); | ^^^^^ error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:69:5 + --> $DIR/cannot-be-called.rs:78:5 | LL | f() | ^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:69:5 + --> $DIR/cannot-be-called.rs:78:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.i686.stderr b/tests/ui/abi/cannot-be-called.i686.stderr index 9b1755921aea..30e294ad61ec 100644 --- a/tests/ui/abi/cannot-be-called.i686.stderr +++ b/tests/ui/abi/cannot-be-called.i686.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.msp430.stderr b/tests/ui/abi/cannot-be-called.msp430.stderr index 9a047b11cf79..12ab88bc858b 100644 --- a/tests/ui/abi/cannot-be-called.msp430.stderr +++ b/tests/ui/abi/cannot-be-called.msp430.stderr @@ -1,75 +1,87 @@ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:55:5 + --> $DIR/cannot-be-called.rs:62:5 | LL | msp430(); | ^^^^^^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:55:5 + --> $DIR/cannot-be-called.rs:62:5 | LL | msp430(); | ^^^^^^^^ error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:75:5 + --> $DIR/cannot-be-called.rs:84:5 | LL | f() | ^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:75:5 + --> $DIR/cannot-be-called.rs:84:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.nvptx.stderr b/tests/ui/abi/cannot-be-called.nvptx.stderr new file mode 100644 index 000000000000..039e2d7b4f00 --- /dev/null +++ b/tests/ui/abi/cannot-be-called.nvptx.stderr @@ -0,0 +1,87 @@ +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:43:8 + | +LL | extern "msp430-interrupt" fn msp430() {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:45:8 + | +LL | extern "avr-interrupt" fn avr() {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:47:8 + | +LL | extern "riscv-interrupt-m" fn riscv_m() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:49:8 + | +LL | extern "riscv-interrupt-s" fn riscv_s() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:51:8 + | +LL | extern "x86-interrupt" fn x86(_x: *const u8) {} + | ^^^^^^^^^^^^^^^ + +error[E0570]: "avr-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:76:22 + | +LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error[E0570]: "msp430-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:82:25 + | +LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { + | ^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:88:26 + | +LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:94:26 + | +LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { + | ^^^^^^^^^^^^^^^^^^^ + +error[E0570]: "x86-interrupt" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:100:22 + | +LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { + | ^^^^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:70:5 + | +LL | gpu_kernel(); + | ^^^^^^^^^^^^ + +error: functions with the "gpu-kernel" ABI cannot be called + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + | +note: an `extern "gpu-kernel"` function must be launched on the GPU by the runtime + --> $DIR/cannot-be-called.rs:108:5 + | +LL | f() + | ^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.riscv32.stderr b/tests/ui/abi/cannot-be-called.riscv32.stderr index 135b20c50d58..b1897b74ebbe 100644 --- a/tests/ui/abi/cannot-be-called.riscv32.stderr +++ b/tests/ui/abi/cannot-be-called.riscv32.stderr @@ -1,87 +1,99 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.riscv64.stderr b/tests/ui/abi/cannot-be-called.riscv64.stderr index 135b20c50d58..b1897b74ebbe 100644 --- a/tests/ui/abi/cannot-be-called.riscv64.stderr +++ b/tests/ui/abi/cannot-be-called.riscv64.stderr @@ -1,87 +1,99 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:46:8 + --> $DIR/cannot-be-called.rs:51:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:91:22 + --> $DIR/cannot-be-called.rs:100:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:57:5 + --> $DIR/cannot-be-called.rs:64:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:59:5 + --> $DIR/cannot-be-called.rs:66:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:81:5 + --> $DIR/cannot-be-called.rs:90:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:87:5 + --> $DIR/cannot-be-called.rs:96:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.rs b/tests/ui/abi/cannot-be-called.rs index 315ea1601633..8d1a4ae0b557 100644 --- a/tests/ui/abi/cannot-be-called.rs +++ b/tests/ui/abi/cannot-be-called.rs @@ -4,7 +4,7 @@ Interrupt ABIs share similar semantics, in that they are special entry-points un So we test that they error in essentially all of the same places. */ //@ add-minicore -//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 +//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 amdgpu nvptx // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -20,6 +20,10 @@ So we test that they error in essentially all of the same places. //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib //@ ignore-backends: gcc #![no_core] #![feature( @@ -27,7 +31,8 @@ So we test that they error in essentially all of the same places. abi_msp430_interrupt, abi_avr_interrupt, abi_x86_interrupt, - abi_riscv_interrupt + abi_riscv_interrupt, + abi_gpu_kernel )] extern crate minicore; @@ -36,15 +41,17 @@ use minicore::*; /* extern "interrupt" definition */ extern "msp430-interrupt" fn msp430() {} -//[x64,x64_win,i686,riscv32,riscv64,avr]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,riscv32,riscv64,avr,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "avr-interrupt" fn avr() {} -//[x64,x64_win,i686,riscv32,riscv64,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,riscv32,riscv64,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "riscv-interrupt-m" fn riscv_m() {} -//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "riscv-interrupt-s" fn riscv_s() {} -//[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI +//[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI extern "x86-interrupt" fn x86(_x: *const u8) {} -//[riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI +//[riscv32,riscv64,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI +extern "gpu-kernel" fn gpu_kernel() {} +//[x64,x64_win,i686,riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI static BYTE: u8 = 0; @@ -60,36 +67,44 @@ fn call_the_interrupts() { //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be called x86(&raw const BYTE); //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be called + gpu_kernel(); + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be called } /* extern "interrupt" fnptr calls */ fn avr_ptr(f: extern "avr-interrupt" fn()) { - //[x64,x64_win,i686,riscv32,riscv64,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,riscv32,riscv64,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[avr]~^ ERROR functions with the "avr-interrupt" ABI cannot be called } fn msp430_ptr(f: extern "msp430-interrupt" fn()) { - //[x64,x64_win,i686,riscv32,riscv64,avr]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,riscv32,riscv64,avr,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[msp430]~^ ERROR functions with the "msp430-interrupt" ABI cannot be called } fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { - //[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-m" ABI cannot be called } fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { - //[x64,x64_win,i686,avr,msp430]~^ ERROR is not a supported ABI + //[x64,x64_win,i686,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[riscv32,riscv64]~^ ERROR functions with the "riscv-interrupt-s" ABI cannot be called } fn x86_ptr(f: extern "x86-interrupt" fn()) { - //[riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI + //[riscv32,riscv64,avr,msp430,amdgpu,nvptx]~^ ERROR is not a supported ABI f() //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be called } + +fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + //[x64,x64_win,i686,riscv32,riscv64,avr,msp430]~^ ERROR is not a supported ABI + f() + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be called +} diff --git a/tests/ui/abi/cannot-be-called.x64.stderr b/tests/ui/abi/cannot-be-called.x64.stderr index 9b1755921aea..30e294ad61ec 100644 --- a/tests/ui/abi/cannot-be-called.x64.stderr +++ b/tests/ui/abi/cannot-be-called.x64.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-called.x64_win.stderr b/tests/ui/abi/cannot-be-called.x64_win.stderr index 9b1755921aea..30e294ad61ec 100644 --- a/tests/ui/abi/cannot-be-called.x64_win.stderr +++ b/tests/ui/abi/cannot-be-called.x64_win.stderr @@ -1,75 +1,87 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:38:8 + --> $DIR/cannot-be-called.rs:43:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:40:8 + --> $DIR/cannot-be-called.rs:45:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:42:8 + --> $DIR/cannot-be-called.rs:47:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:44:8 + --> $DIR/cannot-be-called.rs:49:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:53:8 + | +LL | extern "gpu-kernel" fn gpu_kernel() {} + | ^^^^^^^^^^^^ + error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:67:22 + --> $DIR/cannot-be-called.rs:76:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:73:25 + --> $DIR/cannot-be-called.rs:82:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:79:26 + --> $DIR/cannot-be-called.rs:88:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:85:26 + --> $DIR/cannot-be-called.rs:94:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ +error[E0570]: "gpu-kernel" is not a supported ABI for the current target + --> $DIR/cannot-be-called.rs:106:29 + | +LL | fn gpu_kernel_ptr(f: extern "gpu-kernel" fn()) { + | ^^^^^^^^^^^^ + error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:61:5 + --> $DIR/cannot-be-called.rs:68:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:93:5 + --> $DIR/cannot-be-called.rs:102:5 | LL | f() | ^^^ -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0570`. diff --git a/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr b/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr new file mode 100644 index 000000000000..a36ea0caa19e --- /dev/null +++ b/tests/ui/abi/cannot-be-coroutine.amdgpu.stderr @@ -0,0 +1,23 @@ +error: functions with the "gpu-kernel" ABI cannot be `async` + --> $DIR/cannot-be-coroutine.rs:62:1 + | +LL | async extern "gpu-kernel" fn async_kernel() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `async` keyword from this definition + | +LL - async extern "gpu-kernel" fn async_kernel() { +LL + extern "gpu-kernel" fn async_kernel() { + | + +error: requires `ResumeTy` lang_item + --> $DIR/cannot-be-coroutine.rs:38:19 + | +LL | async fn vanilla(){ + | ___________________^ +LL | | +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/abi/cannot-be-coroutine.avr.stderr b/tests/ui/abi/cannot-be-coroutine.avr.stderr index 11bc93b1eef1..643a575bece1 100644 --- a/tests/ui/abi/cannot-be-coroutine.avr.stderr +++ b/tests/ui/abi/cannot-be-coroutine.avr.stderr @@ -1,5 +1,5 @@ error: functions with the "avr-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:37:1 + --> $DIR/cannot-be-coroutine.rs:42:1 | LL | async extern "avr-interrupt" fn avr() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "avr-interrupt" fn avr() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.i686.stderr b/tests/ui/abi/cannot-be-coroutine.i686.stderr index 4a344bb09020..f618507df47d 100644 --- a/tests/ui/abi/cannot-be-coroutine.i686.stderr +++ b/tests/ui/abi/cannot-be-coroutine.i686.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.msp430.stderr b/tests/ui/abi/cannot-be-coroutine.msp430.stderr index c2867705df78..f2586c8cd975 100644 --- a/tests/ui/abi/cannot-be-coroutine.msp430.stderr +++ b/tests/ui/abi/cannot-be-coroutine.msp430.stderr @@ -1,5 +1,5 @@ error: functions with the "msp430-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:41:1 + --> $DIR/cannot-be-coroutine.rs:46:1 | LL | async extern "msp430-interrupt" fn msp430() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "msp430-interrupt" fn msp430() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.nvptx.stderr b/tests/ui/abi/cannot-be-coroutine.nvptx.stderr new file mode 100644 index 000000000000..a36ea0caa19e --- /dev/null +++ b/tests/ui/abi/cannot-be-coroutine.nvptx.stderr @@ -0,0 +1,23 @@ +error: functions with the "gpu-kernel" ABI cannot be `async` + --> $DIR/cannot-be-coroutine.rs:62:1 + | +LL | async extern "gpu-kernel" fn async_kernel() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: remove the `async` keyword from this definition + | +LL - async extern "gpu-kernel" fn async_kernel() { +LL + extern "gpu-kernel" fn async_kernel() { + | + +error: requires `ResumeTy` lang_item + --> $DIR/cannot-be-coroutine.rs:38:19 + | +LL | async fn vanilla(){ + | ___________________^ +LL | | +LL | | } + | |_^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr index 398f888205df..c5a8c3f60a38 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:45:1 + --> $DIR/cannot-be-coroutine.rs:50:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:49:1 + --> $DIR/cannot-be-coroutine.rs:54:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr index 398f888205df..c5a8c3f60a38 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:45:1 + --> $DIR/cannot-be-coroutine.rs:50:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:49:1 + --> $DIR/cannot-be-coroutine.rs:54:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.rs b/tests/ui/abi/cannot-be-coroutine.rs index c070e8032e1a..239f5aa5c31f 100644 --- a/tests/ui/abi/cannot-be-coroutine.rs +++ b/tests/ui/abi/cannot-be-coroutine.rs @@ -1,6 +1,6 @@ //@ add-minicore //@ edition: 2021 -//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 +//@ revisions: x64 x64_win i686 riscv32 riscv64 avr msp430 amdgpu nvptx // //@ [x64] needs-llvm-components: x86 //@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib @@ -16,6 +16,10 @@ //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib //@ ignore-backends: gcc #![no_core] #![feature( @@ -23,7 +27,8 @@ abi_msp430_interrupt, abi_avr_interrupt, abi_x86_interrupt, - abi_riscv_interrupt + abi_riscv_interrupt, + abi_gpu_kernel )] extern crate minicore; @@ -53,3 +58,7 @@ async extern "riscv-interrupt-s" fn riscv_s() { async extern "x86-interrupt" fn x86(_p: *mut ()) { //[x64,x64_win,i686]~^ ERROR functions with the "x86-interrupt" ABI cannot be `async` } + +async extern "gpu-kernel" fn async_kernel() { + //[amdgpu,nvptx]~^ ERROR functions with the "gpu-kernel" ABI cannot be `async` +} diff --git a/tests/ui/abi/cannot-be-coroutine.x64.stderr b/tests/ui/abi/cannot-be-coroutine.x64.stderr index 4a344bb09020..f618507df47d 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr index 4a344bb09020..f618507df47d 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:53:1 + --> $DIR/cannot-be-coroutine.rs:58:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:33:19 + --> $DIR/cannot-be-coroutine.rs:38:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-return.amdgpu.stderr b/tests/ui/abi/cannot-return.amdgpu.stderr new file mode 100644 index 000000000000..f264907d00ec --- /dev/null +++ b/tests/ui/abi/cannot-return.amdgpu.stderr @@ -0,0 +1,15 @@ +error: invalid signature for `extern "gpu-kernel"` function + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + | + = note: functions with the "gpu-kernel" ABI cannot have a return type +help: remove the return type + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/cannot-return.nvptx.stderr b/tests/ui/abi/cannot-return.nvptx.stderr new file mode 100644 index 000000000000..f264907d00ec --- /dev/null +++ b/tests/ui/abi/cannot-return.nvptx.stderr @@ -0,0 +1,15 @@ +error: invalid signature for `extern "gpu-kernel"` function + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + | + = note: functions with the "gpu-kernel" ABI cannot have a return type +help: remove the return type + --> $DIR/cannot-return.rs:17:37 + | +LL | extern "gpu-kernel" fn ret_i32() -> i32 { 0 } + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/abi/cannot-return.rs b/tests/ui/abi/cannot-return.rs new file mode 100644 index 000000000000..9a5db30431b9 --- /dev/null +++ b/tests/ui/abi/cannot-return.rs @@ -0,0 +1,18 @@ +//@ add-minicore +//@ ignore-backends: gcc +//@ edition: 2024 +//@ revisions: amdgpu nvptx +// +//@ [amdgpu] needs-llvm-components: amdgpu +//@ [amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 --crate-type=rlib +//@ [nvptx] needs-llvm-components: nvptx +//@ [nvptx] compile-flags: --target nvptx64-nvidia-cuda --crate-type=rlib +#![no_core] +#![feature(no_core, abi_gpu_kernel)] + +extern crate minicore; +use minicore::*; + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_i32() -> i32 { 0 } +//~^ ERROR invalid signature for `extern "gpu-kernel"` function diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 84294ab34311..6071ad9bb435 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -78,7 +78,6 @@ // FIXME: some targets are broken in various ways. // Hence there are `cfg` throughout this test to disable parts of it on those targets. -// sparc64: https://github.com/rust-lang/rust/issues/115336 // mips64: https://github.com/rust-lang/rust/issues/115404 extern crate minicore; @@ -246,7 +245,7 @@ test_transparent!(zst, Zst); test_transparent!(unit, ()); test_transparent!(enum_, Option); test_transparent!(enum_niched, Option<&'static i32>); -#[cfg(not(any(target_arch = "mips64", target_arch = "sparc64")))] +#[cfg(not(any(target_arch = "mips64")))] mod tuples { use super::*; // mixing in some floats since they often get special treatment @@ -260,7 +259,6 @@ mod tuples { test_transparent!(tuple, (i32, f32, i64, f64)); } // Some targets have special rules for arrays. -#[cfg(not(any(target_arch = "mips64", target_arch = "sparc64")))] mod arrays { use super::*; test_transparent!(empty_array, [u32; 0]); diff --git a/tests/ui/abi/debug.generic.stderr b/tests/ui/abi/debug.generic.stderr index 04d6f50872a3..b154c3fa201e 100644 --- a/tests/ui/abi/debug.generic.stderr +++ b/tests/ui/abi/debug.generic.stderr @@ -1,3 +1,36 @@ +error: `#[rustc_abi]` attribute cannot be used on constants + --> $DIR/debug.rs:42:1 + | +LL | #[rustc_abi(debug)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_abi]` can be applied to functions and type aliases + +error: `#[rustc_abi]` attribute cannot be used on associated consts + --> $DIR/debug.rs:46:5 + | +LL | #[rustc_abi(debug)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_abi]` can be applied to functions and type aliases + +error[E0539]: malformed `rustc_abi` attribute input + --> $DIR/debug.rs:74:1 + | +LL | #[rustc_abi("assert_eq")] + | ^^^^^^^^^^^-------------^ + | | + | valid arguments are `assert_eq` or `debug` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_abi("assert_eq")] +LL + #[rustc_abi(assert_eq)] + | +LL - #[rustc_abi("assert_eq")] +LL + #[rustc_abi(debug)] + | + error: fn_abi_of(test) = FnAbi { args: [ ArgAbi { @@ -244,7 +277,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -328,7 +361,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -400,7 +433,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -479,7 +512,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -552,7 +585,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -629,7 +662,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -701,7 +734,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -779,7 +812,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -851,7 +884,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -884,12 +917,6 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = help: the trait `Sized` is not implemented for `str` = note: only the last element of a tuple may have a dynamically sized type -error: unrecognized argument - --> $DIR/debug.rs:74:13 - | -LL | #[rustc_abi("assert_eq")] - | ^^^^^^^^^^^ - error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions --> $DIR/debug.rs:47:5 | @@ -962,7 +989,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -986,6 +1013,7 @@ error: fn_abi_of(assoc_test) = FnAbi { LL | fn assoc_test(&self) {} | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 14 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0539. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/abi/debug.loongarch64.stderr b/tests/ui/abi/debug.loongarch64.stderr index 85c888c4fae0..68bcd736e47c 100644 --- a/tests/ui/abi/debug.loongarch64.stderr +++ b/tests/ui/abi/debug.loongarch64.stderr @@ -1,3 +1,36 @@ +error: `#[rustc_abi]` attribute cannot be used on constants + --> $DIR/debug.rs:42:1 + | +LL | #[rustc_abi(debug)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_abi]` can be applied to functions and type aliases + +error: `#[rustc_abi]` attribute cannot be used on associated consts + --> $DIR/debug.rs:46:5 + | +LL | #[rustc_abi(debug)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_abi]` can be applied to functions and type aliases + +error[E0539]: malformed `rustc_abi` attribute input + --> $DIR/debug.rs:74:1 + | +LL | #[rustc_abi("assert_eq")] + | ^^^^^^^^^^^-------------^ + | | + | valid arguments are `assert_eq` or `debug` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_abi("assert_eq")] +LL + #[rustc_abi(assert_eq)] + | +LL - #[rustc_abi("assert_eq")] +LL + #[rustc_abi(debug)] + | + error: fn_abi_of(test) = FnAbi { args: [ ArgAbi { @@ -244,7 +277,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -328,7 +361,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -400,7 +433,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -479,7 +512,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -552,7 +585,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -629,7 +662,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -701,7 +734,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -779,7 +812,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -851,7 +884,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -884,12 +917,6 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = help: the trait `Sized` is not implemented for `str` = note: only the last element of a tuple may have a dynamically sized type -error: unrecognized argument - --> $DIR/debug.rs:74:13 - | -LL | #[rustc_abi("assert_eq")] - | ^^^^^^^^^^^ - error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions --> $DIR/debug.rs:47:5 | @@ -962,7 +989,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -986,6 +1013,7 @@ error: fn_abi_of(assoc_test) = FnAbi { LL | fn assoc_test(&self) {} | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 14 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0539. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/abi/debug.riscv64.stderr b/tests/ui/abi/debug.riscv64.stderr index 85c888c4fae0..68bcd736e47c 100644 --- a/tests/ui/abi/debug.riscv64.stderr +++ b/tests/ui/abi/debug.riscv64.stderr @@ -1,3 +1,36 @@ +error: `#[rustc_abi]` attribute cannot be used on constants + --> $DIR/debug.rs:42:1 + | +LL | #[rustc_abi(debug)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_abi]` can be applied to functions and type aliases + +error: `#[rustc_abi]` attribute cannot be used on associated consts + --> $DIR/debug.rs:46:5 + | +LL | #[rustc_abi(debug)] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_abi]` can be applied to functions and type aliases + +error[E0539]: malformed `rustc_abi` attribute input + --> $DIR/debug.rs:74:1 + | +LL | #[rustc_abi("assert_eq")] + | ^^^^^^^^^^^-------------^ + | | + | valid arguments are `assert_eq` or `debug` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_abi("assert_eq")] +LL + #[rustc_abi(assert_eq)] + | +LL - #[rustc_abi("assert_eq")] +LL + #[rustc_abi(debug)] + | + error: fn_abi_of(test) = FnAbi { args: [ ArgAbi { @@ -244,7 +277,7 @@ error: fn_abi_of(test_generic) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -328,7 +361,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -400,7 +433,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -479,7 +512,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -552,7 +585,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -629,7 +662,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -701,7 +734,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -779,7 +812,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -851,7 +884,7 @@ error: ABIs are not compatible }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -884,12 +917,6 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = help: the trait `Sized` is not implemented for `str` = note: only the last element of a tuple may have a dynamically sized type -error: unrecognized argument - --> $DIR/debug.rs:74:13 - | -LL | #[rustc_abi("assert_eq")] - | ^^^^^^^^^^^ - error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions --> $DIR/debug.rs:47:5 | @@ -962,7 +989,7 @@ error: fn_abi_of(assoc_test) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -986,6 +1013,7 @@ error: fn_abi_of(assoc_test) = FnAbi { LL | fn assoc_test(&self) {} | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 14 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0539. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index 2e34fa5d7df4..42ea14ec51d0 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -39,12 +39,12 @@ type TestFnPtr = fn(bool) -> u8; //~ ERROR: fn_abi #[rustc_abi(debug)] fn test_generic(_x: *const T) {} //~ ERROR: fn_abi -#[rustc_abi(debug)] -const C: () = (); //~ ERROR: can only be applied to +#[rustc_abi(debug)] //~ ERROR: `#[rustc_abi]` attribute cannot be used on constants +const C: () = (); //~ ERROR: `#[rustc_abi]` can only be applied to impl S { - #[rustc_abi(debug)] - const C: () = (); //~ ERROR: can only be applied to + #[rustc_abi(debug)] //~ ERROR: `#[rustc_abi]` attribute cannot be used on assoc + const C: () = (); //~ ERROR: `#[rustc_abi]` can only be applied to } impl S { @@ -71,5 +71,5 @@ type TestAbiNeSign = (fn(i32), fn(u32)); //~ ERROR: ABIs are not compatible #[rustc_abi(assert_eq)] type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); //~ ERROR: cannot be known at compilation time -#[rustc_abi("assert_eq")] //~ ERROR unrecognized argument +#[rustc_abi("assert_eq")] //~ ERROR malformed `rustc_abi` attribute input type Bad = u32; diff --git a/tests/ui/abi/issues/issue-22565-rust-call.stderr b/tests/ui/abi/issues/issue-22565-rust-call.stderr index 0fd3285cd3a5..90fa210fa2fa 100644 --- a/tests/ui/abi/issues/issue-22565-rust-call.stderr +++ b/tests/ui/abi/issues/issue-22565-rust-call.stderr @@ -2,7 +2,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/issue-22565-rust-call.rs:3:1 | LL | extern "rust-call" fn b(_i: i32) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` error: functions with the "rust-call" ABI must take a single non-self tuple argument --> $DIR/issue-22565-rust-call.rs:17:5 @@ -32,7 +32,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/issue-22565-rust-call.rs:27:7 | LL | b(10); - | ^^ the trait `Tuple` is not implemented for `i32` + | ^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` error: functions with the "rust-call" ABI must take a single non-self tuple argument --> $DIR/issue-22565-rust-call.rs:29:5 diff --git a/tests/ui/abi/pass-indirectly-attr.stderr b/tests/ui/abi/pass-indirectly-attr.stderr index a93982dacfa1..03fe9ea46a4b 100644 --- a/tests/ui/abi/pass-indirectly-attr.stderr +++ b/tests/ui/abi/pass-indirectly-attr.stderr @@ -24,7 +24,7 @@ error: fn_abi_of(extern_c) = FnAbi { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -65,7 +65,7 @@ error: fn_abi_of(extern_c) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -106,7 +106,7 @@ error: fn_abi_of(extern_rust) = FnAbi { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -165,7 +165,7 @@ error: fn_abi_of(extern_rust) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/rust-preserve-none-cc.rs b/tests/ui/abi/rust-preserve-none-cc.rs new file mode 100644 index 000000000000..deacb926971c --- /dev/null +++ b/tests/ui/abi/rust-preserve-none-cc.rs @@ -0,0 +1,67 @@ +//@ run-pass +//@ needs-unwind + +#![feature(rust_preserve_none_cc)] + +struct CrateOf<'a> { + mcintosh: f64, + golden_delicious: u64, + jonagold: Option<&'a u64>, + rome: [u64; 12], +} + +#[inline(never)] +extern "rust-preserve-none" fn oven_explosion() { + panic!("bad time"); +} + +#[inline(never)] +fn bite_into(yummy: u64) -> u64 { + let did_it_actually = std::panic::catch_unwind(move || { + oven_explosion() + }); + assert!(did_it_actually.is_err()); + yummy - 25 +} + +#[inline(never)] +extern "rust-preserve-none" fn lotsa_apples( + honeycrisp: u64, + gala: u32, + fuji: f64, + granny_smith: &[u64], + pink_lady: (), + and_a: CrateOf<'static>, + cosmic_crisp: u64, + ambrosia: f64, + winesap: &[u64], +) -> (u64, f64, u64, u64) { + assert_eq!(honeycrisp, 220); + assert_eq!(gala, 140); + assert_eq!(fuji, 210.54201234); + assert_eq!(granny_smith, &[180, 210]); + assert_eq!(pink_lady, ()); + assert_eq!(and_a.mcintosh, 150.0); + assert_eq!(and_a.golden_delicious, 185); + assert_eq!(and_a.jonagold, None); // my scales can't weight these gargantuans. + assert_eq!(and_a.rome, [180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202]); + assert_eq!(cosmic_crisp, 270); + assert_eq!(ambrosia, 193.1); + assert_eq!(winesap, &[]); + ( + and_a.rome.iter().sum(), + fuji + ambrosia, + cosmic_crisp - honeycrisp, + bite_into(and_a.golden_delicious) + ) +} + +fn main() { + let pie = lotsa_apples(220, 140, 210.54201234, &[180, 210], (), CrateOf { + mcintosh: 150.0, + golden_delicious: 185, + jonagold: None, + rome: [180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202] + }, 270, 193.1, &[]); + assert_eq!(pie, (2292, 403.64201234, 50, 160)); +} diff --git a/tests/ui/abi/s390x-softfloat-gate.disable-softfloat.stderr b/tests/ui/abi/s390x-softfloat-gate.disable-softfloat.stderr new file mode 100644 index 000000000000..e82d5b744a26 --- /dev/null +++ b/tests/ui/abi/s390x-softfloat-gate.disable-softfloat.stderr @@ -0,0 +1,12 @@ +warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: unsupported ABI-configuration feature + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: 2 warnings emitted + diff --git a/tests/ui/abi/s390x-softfloat-gate.enable-softfloat.stderr b/tests/ui/abi/s390x-softfloat-gate.enable-softfloat.stderr new file mode 100644 index 000000000000..ecc96e448dcf --- /dev/null +++ b/tests/ui/abi/s390x-softfloat-gate.enable-softfloat.stderr @@ -0,0 +1,7 @@ +warning: target feature `vector` must be disabled to ensure that the ABI of the current target can be implemented correctly + | + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 + +warning: 1 warning emitted + diff --git a/tests/ui/abi/s390x-softfloat-gate.rs b/tests/ui/abi/s390x-softfloat-gate.rs new file mode 100644 index 000000000000..496929eb0955 --- /dev/null +++ b/tests/ui/abi/s390x-softfloat-gate.rs @@ -0,0 +1,38 @@ +//@ add-minicore +//@ revisions: disable-softfloat enable-softfloat +//@ assembly-output: emit-asm +//@ compile-flags: -Copt-level=3 --crate-type=lib + +// we expect the build to fail in the feature +//@ build-pass +//@ [enable-softfloat] compile-flags: --target=s390x-unknown-none-softfloat +//@ [enable-softfloat] compile-flags: -C target-feature=+vector +//@ [enable-softfloat] needs-llvm-components: systemz +//@ [disable-softfloat] compile-flags: --target=s390x-unknown-linux-gnu +//@ [disable-softfloat] compile-flags: -C target-feature=+soft-float +//@ [disable-softfloat] needs-llvm-components: systemz +//@ ignore-backends: gcc + +//[disable-softfloat]~? WARN target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly +//[disable-softfloat]~? WARN target feature `soft-float` cannot be enabled with `-Ctarget-feature` +//[enable-softfloat]~? WARN target feature `vector` must be disabled to ensure that the ABI of the current target can be implemented correctly + +#![feature(no_core, lang_items)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +extern "C" { + fn extern_func(value: f64) -> f64; +} + +#[no_mangle] +extern "C" fn test_softfloat() -> f64 { + let value = 3.141_f64; + + unsafe { extern_func(value) } ; + + 2.718_f64 +} diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr index 0e8e6637507d..cda51a211324 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr @@ -1,4 +1,4 @@ -warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: currently unsupported ABI-configuration feature +warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: unsupported ABI-configuration feature | = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #116344 diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr index 2233e8e4f623..82d3793c3532 100644 --- a/tests/ui/abi/sysv64-zst.stderr +++ b/tests/ui/abi/sysv64-zst.stderr @@ -13,7 +13,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -41,7 +41,7 @@ error: fn_abi_of(pass_zst) = FnAbi { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/abi/variadic-ffi.rs b/tests/ui/abi/variadic-ffi.rs index dfdbff33264b..3ffa0bea0ecf 100644 --- a/tests/ui/abi/variadic-ffi.rs +++ b/tests/ui/abi/variadic-ffi.rs @@ -10,37 +10,45 @@ extern "C" { fn rust_interesting_average(_: u64, ...) -> f64; fn rust_valist_interesting_average(_: u64, _: VaList) -> f64; + + fn rust_va_list_next_i32(_: *mut VaList<'_>) -> i32; } -pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 { - rust_valist_interesting_average(n, ap.as_va_list()) +pub unsafe extern "C" fn test_valist_forward(n: u64, ap: ...) -> f64 { + rust_valist_interesting_average(n, ap) } -pub unsafe extern "C-unwind" fn c_unwind_can_forward(n: u64, mut ap: ...) -> f64 { - rust_valist_interesting_average(n, ap.as_va_list()) +pub unsafe extern "C-unwind" fn c_unwind_can_forward(n: u64, ap: ...) -> f64 { + rust_valist_interesting_average(n, ap) } pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) { - let mut ap2 = ap.clone(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30); + let ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 30); // Advance one pair in the copy before checking let mut ap2 = ap.clone(); let _ = ap2.arg::(); let _ = ap2.arg::(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 50); // Advance one pair in the original let _ = ap.arg::(); let _ = ap.arg::(); - let mut ap2 = ap.clone(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50); + let ap2 = ap.clone(); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 50); let mut ap2 = ap.clone(); let _ = ap2.arg::(); let _ = ap2.arg::(); - assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70); + assert_eq!(rust_valist_interesting_average(2, ap2) as i64, 70); +} + +pub unsafe extern "C" fn test_ref(mut ap: ...) { + assert_eq!(rust_va_list_next_i32(&mut ap), 2); + assert_eq!(rust_va_list_next_i32(&mut ap), 4); + assert_eq!(rust_va_list_next_i32(&mut ap), 8); } pub fn main() { @@ -85,4 +93,8 @@ pub fn main() { unsafe { test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64); } + + unsafe { + test_ref(2, 4, 8); + } } diff --git a/tests/ui/annotate-snippet/missing-type.rs b/tests/ui/annotate-snippet/missing-type.rs index 54088def3eea..2d06c13b96ab 100644 --- a/tests/ui/annotate-snippet/missing-type.rs +++ b/tests/ui/annotate-snippet/missing-type.rs @@ -1,5 +1,5 @@ //@ edition: 2015 -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human pub fn main() { let x: Iter; diff --git a/tests/ui/annotate-snippet/multiple-files.rs b/tests/ui/annotate-snippet/multiple-files.rs index c67a31d8f071..060e817bea08 100644 --- a/tests/ui/annotate-snippet/multiple-files.rs +++ b/tests/ui/annotate-snippet/multiple-files.rs @@ -1,5 +1,5 @@ //@ aux-build:other_file.rs -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human extern crate other_file; diff --git a/tests/ui/annotate-snippet/multispan.rs b/tests/ui/annotate-snippet/multispan.rs index c2054f62d24c..adbbef6d42f7 100644 --- a/tests/ui/annotate-snippet/multispan.rs +++ b/tests/ui/annotate-snippet/multispan.rs @@ -1,5 +1,5 @@ //@ proc-macro: multispan.rs -//@ compile-flags: --error-format human-annotate-rs -Z unstable-options +//@ compile-flags: --error-format human #![feature(proc_macro_hygiene)] diff --git a/tests/ui/anon-params/anon-params-deprecated.stderr b/tests/ui/anon-params/anon-params-deprecated.stderr index 541cb004b5b2..0f508bad70b4 100644 --- a/tests/ui/anon-params/anon-params-deprecated.stderr +++ b/tests/ui/anon-params/anon-params-deprecated.stderr @@ -5,7 +5,7 @@ LL | fn foo(i32); | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see note: the lint level is defined here --> $DIR/anon-params-deprecated.rs:1:9 | @@ -19,7 +19,7 @@ LL | fn bar_with_default_impl(String, String) {} | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see warning: anonymous parameters are deprecated and will be removed in the next edition --> $DIR/anon-params-deprecated.rs:13:38 @@ -28,7 +28,7 @@ LL | fn bar_with_default_impl(String, String) {} | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see warning: 3 warnings emitted diff --git a/tests/ui/anon-params/anon-params-trait-method-multiple.rs b/tests/ui/anon-params/anon-params-trait-method-multiple.rs new file mode 100644 index 000000000000..ba06aa5115ba --- /dev/null +++ b/tests/ui/anon-params/anon-params-trait-method-multiple.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ edition: 2015 +//@ check-pass +// Make sure several unnamed function parameters don't conflict with each other + +trait Tr { + #[allow(anonymous_parameters)] + fn f(u8, u8) {} +} + +fn main() {} diff --git a/tests/ui/any/try_as_dyn.rs b/tests/ui/any/try_as_dyn.rs new file mode 100644 index 000000000000..ee220f797ced --- /dev/null +++ b/tests/ui/any/try_as_dyn.rs @@ -0,0 +1,29 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::Debug; + +// Look ma, no `T: Debug` +fn debug_format_with_try_as_dyn(t: &T) -> String { + match std::any::try_as_dyn::<_, dyn Debug>(t) { + Some(d) => format!("{d:?}"), + None => "default".to_string() + } +} + +// Test that downcasting to a dyn trait works as expected +fn main() { + #[allow(dead_code)] + #[derive(Debug)] + struct A { + index: usize + } + let a = A { index: 42 }; + let result = debug_format_with_try_as_dyn(&a); + assert_eq!("A { index: 42 }", result); + + struct B {} + let b = B {}; + let result = debug_format_with_try_as_dyn(&b); + assert_eq!("default", result); +} diff --git a/tests/ui/any/try_as_dyn_mut.rs b/tests/ui/any/try_as_dyn_mut.rs new file mode 100644 index 000000000000..ff7baa32ea87 --- /dev/null +++ b/tests/ui/any/try_as_dyn_mut.rs @@ -0,0 +1,20 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::fmt::{Error, Write}; + +// Look ma, no `T: Write` +fn try_as_dyn_mut_write(t: &mut T, s: &str) -> Result<(), Error> { + match std::any::try_as_dyn_mut::<_, dyn Write>(t) { + Some(w) => w.write_str(s), + None => Ok(()) + } +} + +// Test that downcasting to a mut dyn trait works as expected +fn main() { + let mut buf = "Hello".to_string(); + + try_as_dyn_mut_write(&mut buf, " world!").unwrap(); + assert_eq!(buf, "Hello world!"); +} diff --git a/tests/ui/any/try_as_dyn_soundness_test1.rs b/tests/ui/any/try_as_dyn_soundness_test1.rs new file mode 100644 index 000000000000..0772e9a2d77e --- /dev/null +++ b/tests/ui/any/try_as_dyn_soundness_test1.rs @@ -0,0 +1,22 @@ +//@ run-pass +#![feature(try_as_dyn)] + +use std::any::try_as_dyn; + +trait Trait { + +} + +impl Trait for for<'a> fn(&'a Box) { + +} + +fn store(_: &'static Box) { + +} + +fn main() { + let fn_ptr: fn(&'static Box) = store; + let dt = try_as_dyn::<_, dyn Trait>(&fn_ptr); + assert!(dt.is_none()); +} diff --git a/tests/ui/any/try_as_dyn_soundness_test2.rs b/tests/ui/any/try_as_dyn_soundness_test2.rs new file mode 100644 index 000000000000..c16b50d0261e --- /dev/null +++ b/tests/ui/any/try_as_dyn_soundness_test2.rs @@ -0,0 +1,16 @@ +//@ run-pass +#![feature(try_as_dyn)] +use std::any::try_as_dyn; + +trait Trait { + +} + +impl Trait fn(&'a Box)> for () { + +} + +fn main() { + let dt = try_as_dyn::<_, dyn Trait)>>(&()); + assert!(dt.is_none()); +} diff --git a/tests/ui/argument-suggestions/disjoint-spans-issue-151607.rs b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.rs new file mode 100644 index 000000000000..31390faa488b --- /dev/null +++ b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.rs @@ -0,0 +1,16 @@ +// Regression test for #151607 +// The ICE was "all spans must be disjoint" when emitting diagnostics +// with overlapping suggestion spans. + +struct B; +struct D; +struct F; +fn foo(g: F, y: F, e: &E) { + //~^ ERROR cannot find type `E` in this scope + foo(B, g, D, E, F, G) + //~^ ERROR this function takes 3 arguments but 6 arguments were supplied + //~| ERROR cannot find value `E` in this scope + //~| ERROR cannot find value `G` in this scope +} + +fn main() {} diff --git a/tests/ui/argument-suggestions/disjoint-spans-issue-151607.stderr b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.stderr new file mode 100644 index 000000000000..f1bda1203347 --- /dev/null +++ b/tests/ui/argument-suggestions/disjoint-spans-issue-151607.stderr @@ -0,0 +1,85 @@ +error[E0425]: cannot find type `E` in this scope + --> $DIR/disjoint-spans-issue-151607.rs:8:24 + | +LL | struct B; + | --------- similarly named struct `B` defined here +... +LL | fn foo(g: F, y: F, e: &E) { + | ^ + | +help: a struct with a similar name exists + | +LL - fn foo(g: F, y: F, e: &E) { +LL + fn foo(g: F, y: F, e: &B) { + | +help: you might be missing a type parameter + | +LL | fn foo(g: F, y: F, e: &E) { + | +++ + +error[E0425]: cannot find value `E` in this scope + --> $DIR/disjoint-spans-issue-151607.rs:10:18 + | +LL | foo(B, g, D, E, F, G) + | ^ + | +help: a local variable with a similar name exists + | +LL - foo(B, g, D, E, F, G) +LL + foo(B, g, D, e, F, G) + | +help: consider importing one of these constants + | +LL + use std::f128::consts::E; + | +LL + use std::f16::consts::E; + | +LL + use std::f32::consts::E; + | +LL + use std::f64::consts::E; + | + +error[E0425]: cannot find value `G` in this scope + --> $DIR/disjoint-spans-issue-151607.rs:10:24 + | +LL | foo(B, g, D, E, F, G) + | ^ + | +help: a local variable with a similar name exists + | +LL - foo(B, g, D, E, F, G) +LL + foo(B, g, D, E, F, g) + | +help: you might be missing a const parameter + | +LL | fn foo(g: F, y: F, e: &E) { + | +++++++++++++++++++++ + +error[E0061]: this function takes 3 arguments but 6 arguments were supplied + --> $DIR/disjoint-spans-issue-151607.rs:10:5 + | +LL | foo(B, g, D, E, F, G) + | ^^^ - - - unexpected argument #4 + | | | + | | unexpected argument #3 of type `D` + | unexpected argument #1 of type `B` + | +note: function defined here + --> $DIR/disjoint-spans-issue-151607.rs:8:4 + | +LL | fn foo(g: F, y: F, e: &E) { + | ^^^ ----- +help: consider borrowing here + | +LL | foo(B, g, D, E, F, &G) + | + +help: remove the extra arguments + | +LL - foo(B, g, D, E, F, G) +LL + foo(, g, F, G) + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0061, E0425. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/argument-suggestions/issue-109831.stderr b/tests/ui/argument-suggestions/issue-109831.stderr index 6c25236ebb1b..852016c983f7 100644 --- a/tests/ui/argument-suggestions/issue-109831.stderr +++ b/tests/ui/argument-suggestions/issue-109831.stderr @@ -24,7 +24,13 @@ LL | struct A; | --------- similarly named unit struct `A` defined here ... LL | f(A, A, B, C); - | ^ help: a unit struct with a similar name exists: `A` + | ^ + | +help: a unit struct with a similar name exists + | +LL - f(A, A, B, C); +LL + f(A, A, B, A); + | error[E0061]: this function takes 3 arguments but 4 arguments were supplied --> $DIR/issue-109831.rs:7:5 diff --git a/tests/ui/array-slice-vec/array-break-length.rs b/tests/ui/array-slice-vec/array-break-length.rs deleted file mode 100644 index 60589f7c264a..000000000000 --- a/tests/ui/array-slice-vec/array-break-length.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - loop { - |_: [_; break]| {} //~ ERROR: `break` outside of a loop - } - - loop { - |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop - } -} diff --git a/tests/ui/array-slice-vec/array-break-length.stderr b/tests/ui/array-slice-vec/array-break-length.stderr deleted file mode 100644 index 2df7b6d7f63c..000000000000 --- a/tests/ui/array-slice-vec/array-break-length.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/array-break-length.rs:3:17 - | -LL | |_: [_; break]| {} - | ^^^^^ cannot `break` outside of a loop or labeled block - -error[E0268]: `continue` outside of a loop - --> $DIR/array-break-length.rs:7:17 - | -LL | |_: [_; continue]| {} - | ^^^^^^^^ cannot `continue` outside of a loop - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/array-slice-vec/array_const_index-2.rs b/tests/ui/array-slice-vec/array_const_index-2.rs index 30338e0ab87c..8dcfc294aae5 100644 --- a/tests/ui/array-slice-vec/array_const_index-2.rs +++ b/tests/ui/array-slice-vec/array_const_index-2.rs @@ -1,8 +1,5 @@ //@ run-pass #![allow(dead_code)] -#![allow(stable_features)] - -#![feature(const_indexing)] fn main() { const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47]; diff --git a/tests/ui/array-slice-vec/closure-in-array-len.rs b/tests/ui/array-slice-vec/closure-in-array-len.rs new file mode 100644 index 000000000000..ce13e0f16081 --- /dev/null +++ b/tests/ui/array-slice-vec/closure-in-array-len.rs @@ -0,0 +1,6 @@ +//! regression test for +struct Foo( + fn([u8; |x: u8| {}]), //~ ERROR mismatched types +); + +fn main() {} diff --git a/tests/ui/array-slice-vec/closure-in-array-len.stderr b/tests/ui/array-slice-vec/closure-in-array-len.stderr new file mode 100644 index 000000000000..decdde042c6f --- /dev/null +++ b/tests/ui/array-slice-vec/closure-in-array-len.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/closure-in-array-len.rs:3:13 + | +LL | fn([u8; |x: u8| {}]), + | ^^^^^^^^^^ expected `usize`, found closure + | + = note: expected type `usize` + found closure `{closure@$DIR/closure-in-array-len.rs:3:13: 3:20}` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/array-slice-vec/return-in-array-len.rs b/tests/ui/array-slice-vec/return-in-array-len.rs new file mode 100644 index 000000000000..dea1bb2818bb --- /dev/null +++ b/tests/ui/array-slice-vec/return-in-array-len.rs @@ -0,0 +1,22 @@ +//! regression test for +fn main() { + //~^ NOTE: not the enclosing function body + //~| NOTE: not the enclosing function body + //~| NOTE: not the enclosing function body + //~| NOTE: not the enclosing function body + |_: [_; return || {}]| {}; + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... + + [(); return || {}]; + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... + + [(); return |ice| {}]; + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... + + [(); return while let Some(n) = Some(0) {}]; + //~^ ERROR: return statement outside of function body [E0572] + //~| NOTE: the return is part of this body... +} diff --git a/tests/ui/array-slice-vec/return-in-array-len.stderr b/tests/ui/array-slice-vec/return-in-array-len.stderr new file mode 100644 index 000000000000..974a748edc93 --- /dev/null +++ b/tests/ui/array-slice-vec/return-in-array-len.stderr @@ -0,0 +1,47 @@ +error[E0572]: return statement outside of function body + --> $DIR/return-in-array-len.rs:7:13 + | +LL | / fn main() { +... | +LL | | |_: [_; return || {}]| {}; + | | ^^^^^^^^^^^^ the return is part of this body... +... | +LL | | } + | |_- ...not the enclosing function body + +error[E0572]: return statement outside of function body + --> $DIR/return-in-array-len.rs:11:10 + | +LL | / fn main() { +... | +LL | | [(); return || {}]; + | | ^^^^^^^^^^^^ the return is part of this body... +... | +LL | | } + | |_- ...not the enclosing function body + +error[E0572]: return statement outside of function body + --> $DIR/return-in-array-len.rs:15:10 + | +LL | / fn main() { +... | +LL | | [(); return |ice| {}]; + | | ^^^^^^^^^^^^^^^ the return is part of this body... +... | +LL | | } + | |_- ...not the enclosing function body + +error[E0572]: return statement outside of function body + --> $DIR/return-in-array-len.rs:19:10 + | +LL | / fn main() { +... | +LL | | [(); return while let Some(n) = Some(0) {}]; + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body... +... | +LL | | } + | |_- ...not the enclosing function body + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0572`. diff --git a/tests/ui/array-slice-vec/slice-of-multi-ref.rs b/tests/ui/array-slice-vec/slice-of-multi-ref.rs new file mode 100644 index 000000000000..b4917f594d83 --- /dev/null +++ b/tests/ui/array-slice-vec/slice-of-multi-ref.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ run-pass +fn main() { + let s: &[isize] = &[0, 1, 2, 3, 4]; + let ss: &&[isize] = &s; + let sss: &&&[isize] = &ss; + + println!("{:?}", &s[..3]); + println!("{:?}", &ss[3..]); + println!("{:?}", &sss[2..4]); +} diff --git a/tests/ui/array-slice-vec/slice-of-zero-size-elements.rs b/tests/ui/array-slice-vec/slice-of-zero-size-elements.rs index 7aa8a251fec5..ea7d8f8be2bf 100644 --- a/tests/ui/array-slice-vec/slice-of-zero-size-elements.rs +++ b/tests/ui/array-slice-vec/slice-of-zero-size-elements.rs @@ -1,10 +1,6 @@ //@ run-pass -#![allow(stable_features)] - //@ compile-flags: -C debug-assertions -#![feature(iter_to_slice)] - use std::slice; fn foo(v: &[T]) -> Option<&[T]> { diff --git a/tests/ui/asm/.gitattributes b/tests/ui/asm/.gitattributes new file mode 100644 index 000000000000..5d6f83c0e18c --- /dev/null +++ b/tests/ui/asm/.gitattributes @@ -0,0 +1,2 @@ +# Disable EOL normalization, as it is deliberately denormalized +normalize-offsets-for-crlf.s -text diff --git a/tests/ui/asm/aarch64/type-check-2.stderr b/tests/ui/asm/aarch64/type-check-2.stderr index 84bc5f08b4ed..2cd767db0334 100644 --- a/tests/ui/asm/aarch64/type-check-2.stderr +++ b/tests/ui/asm/aarch64/type-check-2.stderr @@ -21,7 +21,6 @@ LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly --> $DIR/type-check-2.rs:36:28 diff --git a/tests/ui/asm/aarch64v8r.rs b/tests/ui/asm/aarch64v8r.rs new file mode 100644 index 000000000000..abc254ad5f8e --- /dev/null +++ b/tests/ui/asm/aarch64v8r.rs @@ -0,0 +1,144 @@ +// Codegen test of mandatory Armv8-R AArch64 extensions + +// The Cortex-R82 CPU is an implementation of the Arm v8-R AArch64 ISA so +// it also implements the ISA-level mandatory extensions. We check that with a revision +//@ add-minicore +//@ revisions: hf sf r82 +//@ [hf] compile-flags: --target aarch64v8r-unknown-none +//@ [hf] needs-llvm-components: aarch64 +//@ [sf] compile-flags: --target aarch64v8r-unknown-none-softfloat +//@ [sf] needs-llvm-components: aarch64 +//@ [r82] compile-flags: --target aarch64v8r-unknown-none -C target-cpu=cortex-r82 +//@ [r82] needs-llvm-components: aarch64 +//@ build-pass +//@ ignore-backends: gcc + +#![feature(no_core)] +#![no_core] +#![no_main] +#![crate_type = "rlib"] +#![deny(dead_code)] // ensures we call all private functions from the public one + +extern crate minicore; +use minicore::*; + +/* # Mandatory extensions + * + * A comment indicates that the extension has no associated assembly instruction and cannot be + * codegen tested + * + * ## References: + * + * - Arm Architecture Reference Manual for R-profile AArch64 architecture (DDI 0628) -- has the + * list of mandatory extensions + * - Arm Architecture Reference Manual for A-profile architecture (ARM DDI 0487) -- has the + * mapping from features to instructions + * - Feature names in A-profile architecture (109697_0100_02_en Version 1.0) -- overview of + * what each extension mean + * */ +pub fn mandatory_extensions() { + /* ## ARMv8.0 */ + feat_aa64(); + // FEAT_AA64EL0 + // FEAT_AA64EL1 + // FEAT_AA64EL2 + feat_crc32(); + // FEAT_EL0 + // FEAT_EL1 + // FEAT_EL2 + // FEAT_IVIPT + + /* ## ARMv8.1 */ + // FEAT_HPDS + feat_lse(); + feat_pan(); + + /* ## ARMv8.2 */ + feat_asmv8p2(); + feat_dpb(); + // FEAT_Debugv8p2 + // FEAT_PAN2 + feat_ras(); + // FEAT_TTCNP + feat_uao(); + // FEAT_XNX + + /* ## ARMv8.3 */ + feat_lrcpc(); + feat_pauth(); + + /* ## ARMv8.4 */ + feat_dit(); + // FEAT_Debugv8p4 + feat_flagm(); + // FEAT_IDST + feat_lrcpc2(); + // FEAT_LSE2 + // FEAT_S2FWB + feat_tlbios(); + feat_tlbirange(); + // FEAT_TTL +} + +fn feat_aa64() { + // CurrentEL register only present when FEAT_AA64 is implemented + unsafe { asm!("mrs x0, CurrentEL") } +} + +fn feat_crc32() { + // instruction is present when FEAT_CRC32 is implemented + unsafe { asm!("crc32b w0, w1, w2") } +} + +fn feat_lse() { + // instruction is present when FEAT_LSE is implemented + unsafe { asm!("casp w0, w1, w2, w3, [x4]") } +} + +fn feat_pan() { + unsafe { asm!("mrs x0, PAN") } +} + +fn feat_asmv8p2() { + unsafe { asm!("BFC w0, #0, #1") } +} + +fn feat_dpb() { + unsafe { asm!("DC CVAP, x0") } +} + +fn feat_ras() { + unsafe { asm!("ESB") } +} + +fn feat_uao() { + unsafe { asm!("mrs x0, UAO") } +} + +fn feat_lrcpc() { + unsafe { asm!("ldaprb w0, [x1]") } +} + +fn feat_pauth() { + unsafe { asm!("xpacd x0") } +} + +fn feat_dit() { + unsafe { asm!("mrs x0, DIT") } +} + +fn feat_flagm() { + unsafe { asm!("cfinv") } +} + +fn feat_lrcpc2() { + unsafe { asm!("stlurb w0, [x1]") } +} + +fn feat_tlbios() { + unsafe { asm!("tlbi VMALLE1OS") } +} + +fn feat_tlbirange() { + unsafe { asm!("tlbi RVAE1IS, x0") } +} diff --git a/tests/ui/asm/cortex-r82.rs b/tests/ui/asm/cortex-r82.rs new file mode 100644 index 000000000000..74313e5cb48c --- /dev/null +++ b/tests/ui/asm/cortex-r82.rs @@ -0,0 +1,180 @@ +// Codegen test of mandatory Cortex-R82 extensions + +//@ add-minicore +//@ compile-flags: --target aarch64v8r-unknown-none -C target-cpu=cortex-r82 +//@ needs-llvm-components: aarch64 +//@ build-pass +//@ ignore-backends: gcc + +#![deny(dead_code)] +#![feature(no_core)] +#![no_core] +#![no_main] +#![crate_type = "rlib"] + +extern crate minicore; +use minicore::*; + +/* # Mandatory extensions + * + * A `//` comment indicates that the extension has no associated assembly instruction and cannot + * be codegen tested + * A `/* */` comment indicates that the extension is being tested in the ISA level codegen test + * (`tests/ui/asm/aarch64v8r.rs`) + * + * Note that as we use the hard-float `aarch64v8r-unknown-none` target as the base, the neon + * extension is present (`NEON_FPm=1`). This affects which R82-specific extensions are enabled + * (see "when `NEON_FPm == 1`" note in Cortex-R82 Processor Technical Reference Manual) + * + * ## References: + * + * - Arm Cortex-R82 Processor Technical Reference Manual Revision r3p1 (102670_0301_06_en Issue 6) + * section 3.2.1 has the list of mandatory extensions + * - Arm Architecture Reference Manual for A-profile architecture (ARM DDI 0487) -- has the + * mapping from features to instructions + * - Feature names in A-profile architecture (109697_0100_02_en Version 1.0) -- overview of what + * each extension mean + * */ +pub fn mandatory_extensions() { + // FEAT_GICv3 + // FEAT_GICv3p1 + // FEAT_GICv3_TDIR + feat_pmuv3(); + // FEAT_ETMv4 + // FEAT_ETMv4p1 + // FEAT_ETMv4p2 + // FEAT_ETMv4p3 + // FEAT_ETMv4p4 + // FEAT_ETMv4p5 + /* FEAT_RAS */ + // FEAT_PCSRv8 + feat_ssbs(); + feat_ssbs2(); + // FEAT_CSV2 + // FEAT_CSV2_1p1 + // FEAT_CSV3 + feat_sb(); + feat_specres(); + feat_dgh(); + // FEAT_nTLBPA + /* FEAT_CRC32 */ + /* FEAT_LSE */ + feat_rdm(); // mandatory given that NEON_FPm=1 + /* FEAT_HPDS */ + /* FEAT_PAN */ + // FEAT_HAFDBS + // FEAT_PMUv3p1 + // FEAT_TTCNP + // FEAT_XNX + /* FEAT_UAO */ + feat_pan2(); + feat_dpb(); + /* FEAT_Debugv8p2 */ + /* FEAT_ASMv8p2 */ + // FEAT_IESB + feat_fp16(); // mandatory given that NEON_FPm=1 + // FEAT_PCSRv8p2 + feat_dotprod(); // mandatory given that NEON_FPm=1 + feat_fhm(); // mandatory given that NEON_FPm=1 + feat_dpb2(); + /* FEAT_PAuth */ + // FEAT_PACQARMA3 + // FEAT_PAuth2 + // FEAT_FPAC + // FEAT_FPACCOMBINE + // FEAT_CONSTPACFIELD + feat_jscvt(); // mandatory given that NEON_FPm=1 + /* FEAT_LRCPC */ + feat_fcma(); // mandatory given that NEON_FPm=1 + // FEAT_DoPD + // FEAT_SEL2 + /* FEAT_S2FWB */ + /* FEAT_DIT */ + /* FEAT_IDST */ + /* FEAT_FlagM */ + /* FEAT_LSE2 */ + /* FEAT_LRCPC2 */ + /* FEAT_TLBIOS */ + /* FEAT_TLBIRANGE */ + /* FEAT_TTL */ + // FEAT_BBM + // FEAT_CNTSC + feat_rasv1p1(); + // FEAT_Debugv8p4 + feat_pmuv3p4(); + feat_trf(); + // FEAT_TTST + // FEAT_E0PD +} + +fn feat_pmuv3() { + unsafe { asm!("mrs x0, PMCCFILTR_EL0") } +} + +fn feat_ssbs() { + unsafe { asm!("msr SSBS, 1") } +} + +fn feat_ssbs2() { + unsafe { asm!("mrs x0, SSBS") } +} + +fn feat_sb() { + unsafe { asm!("sb") } +} + +fn feat_specres() { + unsafe { asm!("cfp rctx, x0") } +} + +fn feat_dgh() { + unsafe { asm!("dgh") } +} + +fn feat_rdm() { + unsafe { asm!("sqrdmlah v0.4h, v1.4h, v2.4h") } +} + +fn feat_pan2() { + unsafe { asm!("AT S1E1RP, x0") } +} + +fn feat_dpb() { + unsafe { asm!("DC CVAP, x0") } +} + +fn feat_fp16() { + unsafe { asm!("fmulx h0, h1, h2") } +} + +fn feat_dotprod() { + unsafe { asm!("sdot V0.4S, V1.16B, V2.16B") } +} + +fn feat_fhm() { + unsafe { asm!("fmlal v0.2s, v1.2h, v2.2h") } +} + +fn feat_dpb2() { + unsafe { asm!("DC CVADP, x0") } +} + +fn feat_jscvt() { + unsafe { asm!("fjcvtzs w0, d1") } +} + +fn feat_fcma() { + unsafe { asm!("fcadd v0.4h, v1.4h, v2.4h, #90") } +} + +fn feat_rasv1p1() { + unsafe { asm!("mrs x0, ERXMISC2_EL1") } +} + +fn feat_pmuv3p4() { + unsafe { asm!("mrs x0, PMMIR_EL1") } +} + +fn feat_trf() { + unsafe { asm!("tsb csync") } +} diff --git a/tests/ui/asm/ice-bad-err-span-in-template-129503.rs b/tests/ui/asm/ice-bad-err-span-in-template-129503.rs index 3b4390f881a7..0a7d0d405d17 100644 --- a/tests/ui/asm/ice-bad-err-span-in-template-129503.rs +++ b/tests/ui/asm/ice-bad-err-span-in-template-129503.rs @@ -1,17 +1,22 @@ -// Regression test for ICE #129503 - - +// Regression test for ICEs #129503 and #131292 +// // Tests that we come up with decent error spans // when the template fed to `asm!()` is itself a // macro call like `concat!()` and should not ICE +//@ needs-asm-support + use std::arch::asm; fn main() { - // Should not ICE + // Should not ICE (test case for #129503) asm!(concat!(r#"lJð¿Ã†ï¿½.ð¿ï¿½"#, "r} {}")); //~^ ERROR invalid asm template string: unmatched `}` found + // Should not ICE (test case for #131292) + asm!(concat!(r#"lJð¿Ã†ï¿½.ð¿ï¿½"#, "{}/day{:02}.txt")); + //~^ ERROR invalid asm template string: expected `}`, found `0` + // Macro call template: should point to // everything within `asm!()` as error span diff --git a/tests/ui/asm/ice-bad-err-span-in-template-129503.stderr b/tests/ui/asm/ice-bad-err-span-in-template-129503.stderr index 066959a052d9..980338138c66 100644 --- a/tests/ui/asm/ice-bad-err-span-in-template-129503.stderr +++ b/tests/ui/asm/ice-bad-err-span-in-template-129503.stderr @@ -1,13 +1,24 @@ error: invalid asm template string: unmatched `}` found - --> $DIR/ice-bad-err-span-in-template-129503.rs:12:10 + --> $DIR/ice-bad-err-span-in-template-129503.rs:13:10 | LL | asm!(concat!(r#"lJð¿Ã†ï¿½.ð¿ï¿½"#, "r} {}")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in asm template string | = note: if you intended to print `}`, you can escape it using `}}` +error: invalid asm template string: expected `}`, found `0` + --> $DIR/ice-bad-err-span-in-template-129503.rs:17:10 + | +LL | asm!(concat!(r#"lJð¿Ã†ï¿½.ð¿ï¿½"#, "{}/day{:02}.txt")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected `}` in asm template string + | because of this opening brace + | + = note: if you intended to print `{`, you can escape it using `{{` + error: invalid asm template string: unmatched `}` found - --> $DIR/ice-bad-err-span-in-template-129503.rs:18:10 + --> $DIR/ice-bad-err-span-in-template-129503.rs:23:10 | LL | asm!(concat!("abc", "r} {}")); | ^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in asm template string @@ -15,12 +26,12 @@ LL | asm!(concat!("abc", "r} {}")); = note: if you intended to print `}`, you can escape it using `}}` error: invalid asm template string: unmatched `}` found - --> $DIR/ice-bad-err-span-in-template-129503.rs:24:19 + --> $DIR/ice-bad-err-span-in-template-129503.rs:29:19 | LL | asm!("abc", "r} {}"); | ^ unmatched `}` in asm template string | = note: if you intended to print `}`, you can escape it using `}}` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs index 93741f26275b..b6fddc88e19b 100644 --- a/tests/ui/asm/naked-functions-inline.rs +++ b/tests/ui/asm/naked-functions-inline.rs @@ -30,7 +30,7 @@ pub extern "C" fn inline_never() { } #[unsafe(naked)] -#[cfg_attr(all(), inline(never))] +#[cfg_attr(true, inline(never))] //~^ ERROR [E0736] pub extern "C" fn conditional_inline_never() { naked_asm!(""); diff --git a/tests/ui/asm/naked-functions-inline.stderr b/tests/ui/asm/naked-functions-inline.stderr index 91140a301edc..785ecf734b9d 100644 --- a/tests/ui/asm/naked-functions-inline.stderr +++ b/tests/ui/asm/naked-functions-inline.stderr @@ -23,12 +23,12 @@ LL | #[inline(never)] | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error[E0736]: attribute incompatible with `#[unsafe(naked)]` - --> $DIR/naked-functions-inline.rs:33:19 + --> $DIR/naked-functions-inline.rs:33:18 | LL | #[unsafe(naked)] | ---------------- function marked with `#[unsafe(naked)]` here -LL | #[cfg_attr(all(), inline(never))] - | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` +LL | #[cfg_attr(true, inline(never))] + | ^^^^^^ the `inline` attribute is incompatible with `#[unsafe(naked)]` error: aborting due to 4 previous errors diff --git a/tests/ui/asm/naked-invalid-attr.rs b/tests/ui/asm/naked-invalid-attr.rs index eba7cf01b7b2..d020fae41cf9 100644 --- a/tests/ui/asm/naked-invalid-attr.rs +++ b/tests/ui/asm/naked-invalid-attr.rs @@ -56,7 +56,7 @@ fn main() { // Check that the path of an attribute without a name is printed correctly (issue #140082) #[::a] //~^ ERROR attribute incompatible with `#[unsafe(naked)]` -//~| ERROR failed to resolve: use of unresolved module or unlinked crate `a` +//~| ERROR cannot find module or crate `a` in the crate root #[unsafe(naked)] extern "C" fn issue_140082() { naked_asm!("") diff --git a/tests/ui/asm/naked-invalid-attr.stderr b/tests/ui/asm/naked-invalid-attr.stderr index a6348923277d..9962cbafc37f 100644 --- a/tests/ui/asm/naked-invalid-attr.stderr +++ b/tests/ui/asm/naked-invalid-attr.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `a` +error[E0433]: cannot find module or crate `a` in the crate root --> $DIR/naked-invalid-attr.rs:57:5 | LL | #[::a] diff --git a/tests/ui/asm/normalize-offsets-for-crlf.rs b/tests/ui/asm/normalize-offsets-for-crlf.rs new file mode 100644 index 000000000000..7b4ec386ebb0 --- /dev/null +++ b/tests/ui/asm/normalize-offsets-for-crlf.rs @@ -0,0 +1,14 @@ +// Byte positions into inline assembly reported by codegen errors require normalization or else +// they may not identify the appropriate span. Worse still, an ICE can occur if the erroneous +// span begins or ends part-way through a multibyte character. +// +// Regression test for https://github.com/rust-lang/rust/issues/110885 + +// This test is tied to assembler syntax and errors, which can vary by backend and architecture. +//@only-x86_64 +//@needs-backends: llvm +//@build-fail + +//~? ERROR instruction mnemonic +std::arch::global_asm!(include_str!("normalize-offsets-for-crlf.s")); +fn main() {} diff --git a/tests/ui/asm/normalize-offsets-for-crlf.s b/tests/ui/asm/normalize-offsets-for-crlf.s new file mode 100644 index 000000000000..ec48aad44123 --- /dev/null +++ b/tests/ui/asm/normalize-offsets-for-crlf.s @@ -0,0 +1,13 @@ +// This file contains (some) CRLF line endings. When codegen reports an error, the byte +// offsets into this file that it identifies require normalization or else they will not +// identify the appropriate span. Worse still, an ICE can result if the erroneous span +// begins or ends part-way through a multibyte character such as £. +non_existent_mnemonic + +// Without normalization, the three CRLF line endings below cause the diagnostic on the +// `non_existent_mnemonic` above to be spanned three bytes backward, and thus begin +// part-way inside the multibyte character in the preceding comment. +// +// NOTE: The lines of this note DELIBERATELY end with CRLF - DO NOT strip/convert them! +// It may not be obvious if you accidentally do, eg `git diff` may appear to show +// that the lines have been updated to the exact same content. diff --git a/tests/ui/asm/normalize-offsets-for-crlf.stderr b/tests/ui/asm/normalize-offsets-for-crlf.stderr new file mode 100644 index 000000000000..28f5510308be --- /dev/null +++ b/tests/ui/asm/normalize-offsets-for-crlf.stderr @@ -0,0 +1,10 @@ +error: invalid instruction mnemonic 'non_existent_mnemonic' + | +note: instantiated into assembly here + --> :6:1 + | +LL | non_existent_mnemonic + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/asm/parse-error.stderr b/tests/ui/asm/parse-error.stderr index dff85a601b73..fe6802b0c0c9 100644 --- a/tests/ui/asm/parse-error.stderr +++ b/tests/ui/asm/parse-error.stderr @@ -193,16 +193,12 @@ error: asm template must be a string literal | LL | asm!(format!("{{{}}}", 0), in(reg) foo); | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal --> $DIR/parse-error.rs:86:21 | LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar); | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: _ cannot be used for input operands --> $DIR/parse-error.rs:88:28 @@ -357,16 +353,12 @@ error: asm template must be a string literal | LL | global_asm!(format!("{{{}}}", 0), const FOO); | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: asm template must be a string literal --> $DIR/parse-error.rs:143:20 | LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR); | ^^^^^^^^^^^^^^^^^^^^ - | - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `in` operand cannot be used with `global_asm!` --> $DIR/parse-error.rs:146:19 diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr index 4490053215b5..c7373780e382 100644 --- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,21 +693,27 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:63:27 + --> $DIR/bad-reg.rs:65:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -715,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:28 + --> $DIR/bad-reg.rs:68:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -723,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:74:35 + --> $DIR/bad-reg.rs:76:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -731,7 +737,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:104:28 + --> $DIR/bad-reg.rs:106:28 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -739,7 +745,7 @@ LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:107:29 + --> $DIR/bad-reg.rs:109:29 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -747,7 +753,7 @@ LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:114:36 + --> $DIR/bad-reg.rs:116:36 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^ @@ -755,7 +761,7 @@ LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is ava = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -763,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -771,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -779,7 +785,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -787,7 +793,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -795,7 +801,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -803,7 +809,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -811,7 +817,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -819,7 +825,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -827,7 +833,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -835,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -843,12 +849,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 112 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 114 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr index 651e8cdfd3d5..5c4cd71c2d1a 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,147 +693,153 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", in("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:60:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:68:18 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:69:26 + --> $DIR/bad-reg.rs:71:26 | LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:71:26 + --> $DIR/bad-reg.rs:73:26 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:74:26 + --> $DIR/bad-reg.rs:76:26 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:77:26 + --> $DIR/bad-reg.rs:79:26 | LL | asm!("/* {} */", out(vreg) _); // requires altivec | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:96:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:100:18 | LL | asm!("", out("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:102:18 | LL | asm!("", in("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:102:18 + --> $DIR/bad-reg.rs:104:18 | LL | asm!("", out("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:104:18 + --> $DIR/bad-reg.rs:106:18 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:107:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:110:26 + --> $DIR/bad-reg.rs:112:26 | LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:112:26 + --> $DIR/bad-reg.rs:114:26 | LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:114:26 + --> $DIR/bad-reg.rs:116:26 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:117:26 + --> $DIR/bad-reg.rs:119:26 | LL | asm!("/* {} */", out(vsreg) _); // requires vsx | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -841,7 +847,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -849,7 +855,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -857,7 +863,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -865,7 +871,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -873,7 +879,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -881,7 +887,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -889,7 +895,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -897,7 +903,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -905,7 +911,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -913,7 +919,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -921,12 +927,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 127 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 129 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr index 552fb0504b8d..151bb5682e03 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,21 +693,27 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:57:27 + --> $DIR/bad-reg.rs:59:27 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^ @@ -715,7 +721,7 @@ LL | asm!("", in("v0") v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:60:28 + --> $DIR/bad-reg.rs:62:28 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^ @@ -723,7 +729,7 @@ LL | asm!("", out("v0") v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:63:27 + --> $DIR/bad-reg.rs:65:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -731,7 +737,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:28 + --> $DIR/bad-reg.rs:68:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -739,7 +745,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:71:35 + --> $DIR/bad-reg.rs:73:35 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^ @@ -747,7 +753,7 @@ LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:74:35 + --> $DIR/bad-reg.rs:76:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -755,67 +761,67 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:96:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", in("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:98:18 + --> $DIR/bad-reg.rs:100:18 | LL | asm!("", out("vs0") v32x4); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:102:18 | LL | asm!("", in("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:102:18 + --> $DIR/bad-reg.rs:104:18 | LL | asm!("", out("vs0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:104:18 + --> $DIR/bad-reg.rs:106:18 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:107:18 + --> $DIR/bad-reg.rs:109:18 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:110:26 + --> $DIR/bad-reg.rs:112:26 | LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:112:26 + --> $DIR/bad-reg.rs:114:26 | LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:114:26 + --> $DIR/bad-reg.rs:116:26 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vsreg` requires the `vsx` target feature - --> $DIR/bad-reg.rs:117:26 + --> $DIR/bad-reg.rs:119:26 | LL | asm!("/* {} */", out(vsreg) _); // requires vsx | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -823,7 +829,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -831,7 +837,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -839,7 +845,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -847,7 +853,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -855,7 +861,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -863,7 +869,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -871,7 +877,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -879,7 +885,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -887,7 +893,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -895,7 +901,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -903,12 +909,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 122 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 124 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr index 4490053215b5..c7373780e382 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr @@ -1,131 +1,131 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:137:18 + --> $DIR/bad-reg.rs:139:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:140:18 + --> $DIR/bad-reg.rs:142:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:143:26 + --> $DIR/bad-reg.rs:145:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:146:26 + --> $DIR/bad-reg.rs:148:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:150:18 + --> $DIR/bad-reg.rs:152:18 | LL | asm!("", in("ctr") x); | ^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:153:18 + --> $DIR/bad-reg.rs:155:18 | LL | asm!("", out("ctr") x); | ^^^^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:156:26 + --> $DIR/bad-reg.rs:158:26 | LL | asm!("/* {} */", in(ctr) x); | ^^^^^^^^^ error: register class `ctr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:159:26 + --> $DIR/bad-reg.rs:161:26 | LL | asm!("/* {} */", out(ctr) _); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:163:18 + --> $DIR/bad-reg.rs:165:18 | LL | asm!("", in("lr") x); | ^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:166:18 + --> $DIR/bad-reg.rs:168:18 | LL | asm!("", out("lr") x); | ^^^^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:169:26 + --> $DIR/bad-reg.rs:171:26 | LL | asm!("/* {} */", in(lr) x); | ^^^^^^^^ error: register class `lr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:172:26 + --> $DIR/bad-reg.rs:174:26 | LL | asm!("/* {} */", out(lr) _); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:176:18 + --> $DIR/bad-reg.rs:178:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:179:18 + --> $DIR/bad-reg.rs:181:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:182:26 + --> $DIR/bad-reg.rs:184:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:185:26 + --> $DIR/bad-reg.rs:187:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:189:31 + --> $DIR/bad-reg.rs:191:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -133,7 +133,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:191:31 + --> $DIR/bad-reg.rs:193:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -141,7 +141,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:193:31 + --> $DIR/bad-reg.rs:195:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -149,7 +149,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:195:31 + --> $DIR/bad-reg.rs:197:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -157,7 +157,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:197:31 + --> $DIR/bad-reg.rs:199:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -165,7 +165,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:199:31 + --> $DIR/bad-reg.rs:201:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -173,7 +173,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:201:31 + --> $DIR/bad-reg.rs:203:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -181,7 +181,7 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:203:31 + --> $DIR/bad-reg.rs:205:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` @@ -189,7 +189,7 @@ LL | asm!("", out("cr") _, out("cr7") _); | register `cr` error: register `vs0` conflicts with register `f0` - --> $DIR/bad-reg.rs:206:31 + --> $DIR/bad-reg.rs:208:31 | LL | asm!("", out("f0") _, out("vs0") _); | ----------- ^^^^^^^^^^^^ register `vs0` @@ -197,7 +197,7 @@ LL | asm!("", out("f0") _, out("vs0") _); | register `f0` error: register `vs1` conflicts with register `f1` - --> $DIR/bad-reg.rs:208:31 + --> $DIR/bad-reg.rs:210:31 | LL | asm!("", out("f1") _, out("vs1") _); | ----------- ^^^^^^^^^^^^ register `vs1` @@ -205,7 +205,7 @@ LL | asm!("", out("f1") _, out("vs1") _); | register `f1` error: register `vs2` conflicts with register `f2` - --> $DIR/bad-reg.rs:210:31 + --> $DIR/bad-reg.rs:212:31 | LL | asm!("", out("f2") _, out("vs2") _); | ----------- ^^^^^^^^^^^^ register `vs2` @@ -213,7 +213,7 @@ LL | asm!("", out("f2") _, out("vs2") _); | register `f2` error: register `vs3` conflicts with register `f3` - --> $DIR/bad-reg.rs:212:31 + --> $DIR/bad-reg.rs:214:31 | LL | asm!("", out("f3") _, out("vs3") _); | ----------- ^^^^^^^^^^^^ register `vs3` @@ -221,7 +221,7 @@ LL | asm!("", out("f3") _, out("vs3") _); | register `f3` error: register `vs4` conflicts with register `f4` - --> $DIR/bad-reg.rs:214:31 + --> $DIR/bad-reg.rs:216:31 | LL | asm!("", out("f4") _, out("vs4") _); | ----------- ^^^^^^^^^^^^ register `vs4` @@ -229,7 +229,7 @@ LL | asm!("", out("f4") _, out("vs4") _); | register `f4` error: register `vs5` conflicts with register `f5` - --> $DIR/bad-reg.rs:216:31 + --> $DIR/bad-reg.rs:218:31 | LL | asm!("", out("f5") _, out("vs5") _); | ----------- ^^^^^^^^^^^^ register `vs5` @@ -237,7 +237,7 @@ LL | asm!("", out("f5") _, out("vs5") _); | register `f5` error: register `vs6` conflicts with register `f6` - --> $DIR/bad-reg.rs:218:31 + --> $DIR/bad-reg.rs:220:31 | LL | asm!("", out("f6") _, out("vs6") _); | ----------- ^^^^^^^^^^^^ register `vs6` @@ -245,7 +245,7 @@ LL | asm!("", out("f6") _, out("vs6") _); | register `f6` error: register `vs7` conflicts with register `f7` - --> $DIR/bad-reg.rs:220:31 + --> $DIR/bad-reg.rs:222:31 | LL | asm!("", out("f7") _, out("vs7") _); | ----------- ^^^^^^^^^^^^ register `vs7` @@ -253,7 +253,7 @@ LL | asm!("", out("f7") _, out("vs7") _); | register `f7` error: register `vs8` conflicts with register `f8` - --> $DIR/bad-reg.rs:222:31 + --> $DIR/bad-reg.rs:224:31 | LL | asm!("", out("f8") _, out("vs8") _); | ----------- ^^^^^^^^^^^^ register `vs8` @@ -261,7 +261,7 @@ LL | asm!("", out("f8") _, out("vs8") _); | register `f8` error: register `vs9` conflicts with register `f9` - --> $DIR/bad-reg.rs:224:31 + --> $DIR/bad-reg.rs:226:31 | LL | asm!("", out("f9") _, out("vs9") _); | ----------- ^^^^^^^^^^^^ register `vs9` @@ -269,7 +269,7 @@ LL | asm!("", out("f9") _, out("vs9") _); | register `f9` error: register `vs10` conflicts with register `f10` - --> $DIR/bad-reg.rs:226:32 + --> $DIR/bad-reg.rs:228:32 | LL | asm!("", out("f10") _, out("vs10") _); | ------------ ^^^^^^^^^^^^^ register `vs10` @@ -277,7 +277,7 @@ LL | asm!("", out("f10") _, out("vs10") _); | register `f10` error: register `vs11` conflicts with register `f11` - --> $DIR/bad-reg.rs:228:32 + --> $DIR/bad-reg.rs:230:32 | LL | asm!("", out("f11") _, out("vs11") _); | ------------ ^^^^^^^^^^^^^ register `vs11` @@ -285,7 +285,7 @@ LL | asm!("", out("f11") _, out("vs11") _); | register `f11` error: register `vs12` conflicts with register `f12` - --> $DIR/bad-reg.rs:230:32 + --> $DIR/bad-reg.rs:232:32 | LL | asm!("", out("f12") _, out("vs12") _); | ------------ ^^^^^^^^^^^^^ register `vs12` @@ -293,7 +293,7 @@ LL | asm!("", out("f12") _, out("vs12") _); | register `f12` error: register `vs13` conflicts with register `f13` - --> $DIR/bad-reg.rs:232:32 + --> $DIR/bad-reg.rs:234:32 | LL | asm!("", out("f13") _, out("vs13") _); | ------------ ^^^^^^^^^^^^^ register `vs13` @@ -301,7 +301,7 @@ LL | asm!("", out("f13") _, out("vs13") _); | register `f13` error: register `vs14` conflicts with register `f14` - --> $DIR/bad-reg.rs:234:32 + --> $DIR/bad-reg.rs:236:32 | LL | asm!("", out("f14") _, out("vs14") _); | ------------ ^^^^^^^^^^^^^ register `vs14` @@ -309,7 +309,7 @@ LL | asm!("", out("f14") _, out("vs14") _); | register `f14` error: register `vs15` conflicts with register `f15` - --> $DIR/bad-reg.rs:236:32 + --> $DIR/bad-reg.rs:238:32 | LL | asm!("", out("f15") _, out("vs15") _); | ------------ ^^^^^^^^^^^^^ register `vs15` @@ -317,7 +317,7 @@ LL | asm!("", out("f15") _, out("vs15") _); | register `f15` error: register `vs16` conflicts with register `f16` - --> $DIR/bad-reg.rs:238:32 + --> $DIR/bad-reg.rs:240:32 | LL | asm!("", out("f16") _, out("vs16") _); | ------------ ^^^^^^^^^^^^^ register `vs16` @@ -325,7 +325,7 @@ LL | asm!("", out("f16") _, out("vs16") _); | register `f16` error: register `vs17` conflicts with register `f17` - --> $DIR/bad-reg.rs:240:32 + --> $DIR/bad-reg.rs:242:32 | LL | asm!("", out("f17") _, out("vs17") _); | ------------ ^^^^^^^^^^^^^ register `vs17` @@ -333,7 +333,7 @@ LL | asm!("", out("f17") _, out("vs17") _); | register `f17` error: register `vs18` conflicts with register `f18` - --> $DIR/bad-reg.rs:242:32 + --> $DIR/bad-reg.rs:244:32 | LL | asm!("", out("f18") _, out("vs18") _); | ------------ ^^^^^^^^^^^^^ register `vs18` @@ -341,7 +341,7 @@ LL | asm!("", out("f18") _, out("vs18") _); | register `f18` error: register `vs19` conflicts with register `f19` - --> $DIR/bad-reg.rs:244:32 + --> $DIR/bad-reg.rs:246:32 | LL | asm!("", out("f19") _, out("vs19") _); | ------------ ^^^^^^^^^^^^^ register `vs19` @@ -349,7 +349,7 @@ LL | asm!("", out("f19") _, out("vs19") _); | register `f19` error: register `vs20` conflicts with register `f20` - --> $DIR/bad-reg.rs:246:32 + --> $DIR/bad-reg.rs:248:32 | LL | asm!("", out("f20") _, out("vs20") _); | ------------ ^^^^^^^^^^^^^ register `vs20` @@ -357,7 +357,7 @@ LL | asm!("", out("f20") _, out("vs20") _); | register `f20` error: register `vs21` conflicts with register `f21` - --> $DIR/bad-reg.rs:248:32 + --> $DIR/bad-reg.rs:250:32 | LL | asm!("", out("f21") _, out("vs21") _); | ------------ ^^^^^^^^^^^^^ register `vs21` @@ -365,7 +365,7 @@ LL | asm!("", out("f21") _, out("vs21") _); | register `f21` error: register `vs22` conflicts with register `f22` - --> $DIR/bad-reg.rs:250:32 + --> $DIR/bad-reg.rs:252:32 | LL | asm!("", out("f22") _, out("vs22") _); | ------------ ^^^^^^^^^^^^^ register `vs22` @@ -373,7 +373,7 @@ LL | asm!("", out("f22") _, out("vs22") _); | register `f22` error: register `vs23` conflicts with register `f23` - --> $DIR/bad-reg.rs:252:32 + --> $DIR/bad-reg.rs:254:32 | LL | asm!("", out("f23") _, out("vs23") _); | ------------ ^^^^^^^^^^^^^ register `vs23` @@ -381,7 +381,7 @@ LL | asm!("", out("f23") _, out("vs23") _); | register `f23` error: register `vs24` conflicts with register `f24` - --> $DIR/bad-reg.rs:254:32 + --> $DIR/bad-reg.rs:256:32 | LL | asm!("", out("f24") _, out("vs24") _); | ------------ ^^^^^^^^^^^^^ register `vs24` @@ -389,7 +389,7 @@ LL | asm!("", out("f24") _, out("vs24") _); | register `f24` error: register `vs25` conflicts with register `f25` - --> $DIR/bad-reg.rs:256:32 + --> $DIR/bad-reg.rs:258:32 | LL | asm!("", out("f25") _, out("vs25") _); | ------------ ^^^^^^^^^^^^^ register `vs25` @@ -397,7 +397,7 @@ LL | asm!("", out("f25") _, out("vs25") _); | register `f25` error: register `vs26` conflicts with register `f26` - --> $DIR/bad-reg.rs:258:32 + --> $DIR/bad-reg.rs:260:32 | LL | asm!("", out("f26") _, out("vs26") _); | ------------ ^^^^^^^^^^^^^ register `vs26` @@ -405,7 +405,7 @@ LL | asm!("", out("f26") _, out("vs26") _); | register `f26` error: register `vs27` conflicts with register `f27` - --> $DIR/bad-reg.rs:260:32 + --> $DIR/bad-reg.rs:262:32 | LL | asm!("", out("f27") _, out("vs27") _); | ------------ ^^^^^^^^^^^^^ register `vs27` @@ -413,7 +413,7 @@ LL | asm!("", out("f27") _, out("vs27") _); | register `f27` error: register `vs28` conflicts with register `f28` - --> $DIR/bad-reg.rs:262:32 + --> $DIR/bad-reg.rs:264:32 | LL | asm!("", out("f28") _, out("vs28") _); | ------------ ^^^^^^^^^^^^^ register `vs28` @@ -421,7 +421,7 @@ LL | asm!("", out("f28") _, out("vs28") _); | register `f28` error: register `vs29` conflicts with register `f29` - --> $DIR/bad-reg.rs:264:32 + --> $DIR/bad-reg.rs:266:32 | LL | asm!("", out("f29") _, out("vs29") _); | ------------ ^^^^^^^^^^^^^ register `vs29` @@ -429,7 +429,7 @@ LL | asm!("", out("f29") _, out("vs29") _); | register `f29` error: register `vs30` conflicts with register `f30` - --> $DIR/bad-reg.rs:266:32 + --> $DIR/bad-reg.rs:268:32 | LL | asm!("", out("f30") _, out("vs30") _); | ------------ ^^^^^^^^^^^^^ register `vs30` @@ -437,7 +437,7 @@ LL | asm!("", out("f30") _, out("vs30") _); | register `f30` error: register `vs31` conflicts with register `f31` - --> $DIR/bad-reg.rs:268:32 + --> $DIR/bad-reg.rs:270:32 | LL | asm!("", out("f31") _, out("vs31") _); | ------------ ^^^^^^^^^^^^^ register `vs31` @@ -445,7 +445,7 @@ LL | asm!("", out("f31") _, out("vs31") _); | register `f31` error: register `v0` conflicts with register `vs32` - --> $DIR/bad-reg.rs:270:33 + --> $DIR/bad-reg.rs:272:33 | LL | asm!("", out("vs32") _, out("v0") _); | ------------- ^^^^^^^^^^^ register `v0` @@ -453,7 +453,7 @@ LL | asm!("", out("vs32") _, out("v0") _); | register `vs32` error: register `v1` conflicts with register `vs33` - --> $DIR/bad-reg.rs:272:33 + --> $DIR/bad-reg.rs:274:33 | LL | asm!("", out("vs33") _, out("v1") _); | ------------- ^^^^^^^^^^^ register `v1` @@ -461,7 +461,7 @@ LL | asm!("", out("vs33") _, out("v1") _); | register `vs33` error: register `v2` conflicts with register `vs34` - --> $DIR/bad-reg.rs:274:33 + --> $DIR/bad-reg.rs:276:33 | LL | asm!("", out("vs34") _, out("v2") _); | ------------- ^^^^^^^^^^^ register `v2` @@ -469,7 +469,7 @@ LL | asm!("", out("vs34") _, out("v2") _); | register `vs34` error: register `v3` conflicts with register `vs35` - --> $DIR/bad-reg.rs:276:33 + --> $DIR/bad-reg.rs:278:33 | LL | asm!("", out("vs35") _, out("v3") _); | ------------- ^^^^^^^^^^^ register `v3` @@ -477,7 +477,7 @@ LL | asm!("", out("vs35") _, out("v3") _); | register `vs35` error: register `v4` conflicts with register `vs36` - --> $DIR/bad-reg.rs:278:33 + --> $DIR/bad-reg.rs:280:33 | LL | asm!("", out("vs36") _, out("v4") _); | ------------- ^^^^^^^^^^^ register `v4` @@ -485,7 +485,7 @@ LL | asm!("", out("vs36") _, out("v4") _); | register `vs36` error: register `v5` conflicts with register `vs37` - --> $DIR/bad-reg.rs:280:33 + --> $DIR/bad-reg.rs:282:33 | LL | asm!("", out("vs37") _, out("v5") _); | ------------- ^^^^^^^^^^^ register `v5` @@ -493,7 +493,7 @@ LL | asm!("", out("vs37") _, out("v5") _); | register `vs37` error: register `v6` conflicts with register `vs38` - --> $DIR/bad-reg.rs:282:33 + --> $DIR/bad-reg.rs:284:33 | LL | asm!("", out("vs38") _, out("v6") _); | ------------- ^^^^^^^^^^^ register `v6` @@ -501,7 +501,7 @@ LL | asm!("", out("vs38") _, out("v6") _); | register `vs38` error: register `v7` conflicts with register `vs39` - --> $DIR/bad-reg.rs:284:33 + --> $DIR/bad-reg.rs:286:33 | LL | asm!("", out("vs39") _, out("v7") _); | ------------- ^^^^^^^^^^^ register `v7` @@ -509,7 +509,7 @@ LL | asm!("", out("vs39") _, out("v7") _); | register `vs39` error: register `v8` conflicts with register `vs40` - --> $DIR/bad-reg.rs:286:33 + --> $DIR/bad-reg.rs:288:33 | LL | asm!("", out("vs40") _, out("v8") _); | ------------- ^^^^^^^^^^^ register `v8` @@ -517,7 +517,7 @@ LL | asm!("", out("vs40") _, out("v8") _); | register `vs40` error: register `v9` conflicts with register `vs41` - --> $DIR/bad-reg.rs:288:33 + --> $DIR/bad-reg.rs:290:33 | LL | asm!("", out("vs41") _, out("v9") _); | ------------- ^^^^^^^^^^^ register `v9` @@ -525,7 +525,7 @@ LL | asm!("", out("vs41") _, out("v9") _); | register `vs41` error: register `v10` conflicts with register `vs42` - --> $DIR/bad-reg.rs:290:33 + --> $DIR/bad-reg.rs:292:33 | LL | asm!("", out("vs42") _, out("v10") _); | ------------- ^^^^^^^^^^^^ register `v10` @@ -533,7 +533,7 @@ LL | asm!("", out("vs42") _, out("v10") _); | register `vs42` error: register `v11` conflicts with register `vs43` - --> $DIR/bad-reg.rs:292:33 + --> $DIR/bad-reg.rs:294:33 | LL | asm!("", out("vs43") _, out("v11") _); | ------------- ^^^^^^^^^^^^ register `v11` @@ -541,7 +541,7 @@ LL | asm!("", out("vs43") _, out("v11") _); | register `vs43` error: register `v12` conflicts with register `vs44` - --> $DIR/bad-reg.rs:294:33 + --> $DIR/bad-reg.rs:296:33 | LL | asm!("", out("vs44") _, out("v12") _); | ------------- ^^^^^^^^^^^^ register `v12` @@ -549,7 +549,7 @@ LL | asm!("", out("vs44") _, out("v12") _); | register `vs44` error: register `v13` conflicts with register `vs45` - --> $DIR/bad-reg.rs:296:33 + --> $DIR/bad-reg.rs:298:33 | LL | asm!("", out("vs45") _, out("v13") _); | ------------- ^^^^^^^^^^^^ register `v13` @@ -557,7 +557,7 @@ LL | asm!("", out("vs45") _, out("v13") _); | register `vs45` error: register `v14` conflicts with register `vs46` - --> $DIR/bad-reg.rs:298:33 + --> $DIR/bad-reg.rs:300:33 | LL | asm!("", out("vs46") _, out("v14") _); | ------------- ^^^^^^^^^^^^ register `v14` @@ -565,7 +565,7 @@ LL | asm!("", out("vs46") _, out("v14") _); | register `vs46` error: register `v15` conflicts with register `vs47` - --> $DIR/bad-reg.rs:300:33 + --> $DIR/bad-reg.rs:302:33 | LL | asm!("", out("vs47") _, out("v15") _); | ------------- ^^^^^^^^^^^^ register `v15` @@ -573,7 +573,7 @@ LL | asm!("", out("vs47") _, out("v15") _); | register `vs47` error: register `v16` conflicts with register `vs48` - --> $DIR/bad-reg.rs:302:33 + --> $DIR/bad-reg.rs:304:33 | LL | asm!("", out("vs48") _, out("v16") _); | ------------- ^^^^^^^^^^^^ register `v16` @@ -581,7 +581,7 @@ LL | asm!("", out("vs48") _, out("v16") _); | register `vs48` error: register `v17` conflicts with register `vs49` - --> $DIR/bad-reg.rs:304:33 + --> $DIR/bad-reg.rs:306:33 | LL | asm!("", out("vs49") _, out("v17") _); | ------------- ^^^^^^^^^^^^ register `v17` @@ -589,7 +589,7 @@ LL | asm!("", out("vs49") _, out("v17") _); | register `vs49` error: register `v18` conflicts with register `vs50` - --> $DIR/bad-reg.rs:306:33 + --> $DIR/bad-reg.rs:308:33 | LL | asm!("", out("vs50") _, out("v18") _); | ------------- ^^^^^^^^^^^^ register `v18` @@ -597,7 +597,7 @@ LL | asm!("", out("vs50") _, out("v18") _); | register `vs50` error: register `v19` conflicts with register `vs51` - --> $DIR/bad-reg.rs:308:33 + --> $DIR/bad-reg.rs:310:33 | LL | asm!("", out("vs51") _, out("v19") _); | ------------- ^^^^^^^^^^^^ register `v19` @@ -605,7 +605,7 @@ LL | asm!("", out("vs51") _, out("v19") _); | register `vs51` error: register `v20` conflicts with register `vs52` - --> $DIR/bad-reg.rs:310:33 + --> $DIR/bad-reg.rs:312:33 | LL | asm!("", out("vs52") _, out("v20") _); | ------------- ^^^^^^^^^^^^ register `v20` @@ -613,7 +613,7 @@ LL | asm!("", out("vs52") _, out("v20") _); | register `vs52` error: register `v21` conflicts with register `vs53` - --> $DIR/bad-reg.rs:312:33 + --> $DIR/bad-reg.rs:314:33 | LL | asm!("", out("vs53") _, out("v21") _); | ------------- ^^^^^^^^^^^^ register `v21` @@ -621,7 +621,7 @@ LL | asm!("", out("vs53") _, out("v21") _); | register `vs53` error: register `v22` conflicts with register `vs54` - --> $DIR/bad-reg.rs:314:33 + --> $DIR/bad-reg.rs:316:33 | LL | asm!("", out("vs54") _, out("v22") _); | ------------- ^^^^^^^^^^^^ register `v22` @@ -629,7 +629,7 @@ LL | asm!("", out("vs54") _, out("v22") _); | register `vs54` error: register `v23` conflicts with register `vs55` - --> $DIR/bad-reg.rs:316:33 + --> $DIR/bad-reg.rs:318:33 | LL | asm!("", out("vs55") _, out("v23") _); | ------------- ^^^^^^^^^^^^ register `v23` @@ -637,7 +637,7 @@ LL | asm!("", out("vs55") _, out("v23") _); | register `vs55` error: register `v24` conflicts with register `vs56` - --> $DIR/bad-reg.rs:318:33 + --> $DIR/bad-reg.rs:320:33 | LL | asm!("", out("vs56") _, out("v24") _); | ------------- ^^^^^^^^^^^^ register `v24` @@ -645,7 +645,7 @@ LL | asm!("", out("vs56") _, out("v24") _); | register `vs56` error: register `v25` conflicts with register `vs57` - --> $DIR/bad-reg.rs:320:33 + --> $DIR/bad-reg.rs:322:33 | LL | asm!("", out("vs57") _, out("v25") _); | ------------- ^^^^^^^^^^^^ register `v25` @@ -653,7 +653,7 @@ LL | asm!("", out("vs57") _, out("v25") _); | register `vs57` error: register `v26` conflicts with register `vs58` - --> $DIR/bad-reg.rs:322:33 + --> $DIR/bad-reg.rs:324:33 | LL | asm!("", out("vs58") _, out("v26") _); | ------------- ^^^^^^^^^^^^ register `v26` @@ -661,7 +661,7 @@ LL | asm!("", out("vs58") _, out("v26") _); | register `vs58` error: register `v27` conflicts with register `vs59` - --> $DIR/bad-reg.rs:324:33 + --> $DIR/bad-reg.rs:326:33 | LL | asm!("", out("vs59") _, out("v27") _); | ------------- ^^^^^^^^^^^^ register `v27` @@ -669,7 +669,7 @@ LL | asm!("", out("vs59") _, out("v27") _); | register `vs59` error: register `v28` conflicts with register `vs60` - --> $DIR/bad-reg.rs:326:33 + --> $DIR/bad-reg.rs:328:33 | LL | asm!("", out("vs60") _, out("v28") _); | ------------- ^^^^^^^^^^^^ register `v28` @@ -677,7 +677,7 @@ LL | asm!("", out("vs60") _, out("v28") _); | register `vs60` error: register `v29` conflicts with register `vs61` - --> $DIR/bad-reg.rs:328:33 + --> $DIR/bad-reg.rs:330:33 | LL | asm!("", out("vs61") _, out("v29") _); | ------------- ^^^^^^^^^^^^ register `v29` @@ -685,7 +685,7 @@ LL | asm!("", out("vs61") _, out("v29") _); | register `vs61` error: register `v30` conflicts with register `vs62` - --> $DIR/bad-reg.rs:330:33 + --> $DIR/bad-reg.rs:332:33 | LL | asm!("", out("vs62") _, out("v30") _); | ------------- ^^^^^^^^^^^^ register `v30` @@ -693,21 +693,27 @@ LL | asm!("", out("vs62") _, out("v30") _); | register `vs62` error: register `v31` conflicts with register `vs63` - --> $DIR/bad-reg.rs:332:33 + --> $DIR/bad-reg.rs:334:33 | LL | asm!("", out("vs63") _, out("v31") _); | ------------- ^^^^^^^^^^^^ register `v31` | | | register `vs63` +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:63:27 + --> $DIR/bad-reg.rs:65:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -715,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:66:28 + --> $DIR/bad-reg.rs:68:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -723,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:74:35 + --> $DIR/bad-reg.rs:76:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -731,7 +737,7 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:104:28 + --> $DIR/bad-reg.rs:106:28 | LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -739,7 +745,7 @@ LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:107:29 + --> $DIR/bad-reg.rs:109:29 | LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available | ^ @@ -747,7 +753,7 @@ LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:114:36 + --> $DIR/bad-reg.rs:116:36 | LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available | ^ @@ -755,7 +761,7 @@ LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is ava = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:137:27 + --> $DIR/bad-reg.rs:139:27 | LL | asm!("", in("cr") x); | ^ @@ -763,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:140:28 + --> $DIR/bad-reg.rs:142:28 | LL | asm!("", out("cr") x); | ^ @@ -771,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:143:33 + --> $DIR/bad-reg.rs:145:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -779,7 +785,7 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:150:28 + --> $DIR/bad-reg.rs:152:28 | LL | asm!("", in("ctr") x); | ^ @@ -787,7 +793,7 @@ LL | asm!("", in("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:153:29 + --> $DIR/bad-reg.rs:155:29 | LL | asm!("", out("ctr") x); | ^ @@ -795,7 +801,7 @@ LL | asm!("", out("ctr") x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:156:34 + --> $DIR/bad-reg.rs:158:34 | LL | asm!("/* {} */", in(ctr) x); | ^ @@ -803,7 +809,7 @@ LL | asm!("/* {} */", in(ctr) x); = note: register class `ctr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:163:27 + --> $DIR/bad-reg.rs:165:27 | LL | asm!("", in("lr") x); | ^ @@ -811,7 +817,7 @@ LL | asm!("", in("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:166:28 + --> $DIR/bad-reg.rs:168:28 | LL | asm!("", out("lr") x); | ^ @@ -819,7 +825,7 @@ LL | asm!("", out("lr") x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:169:33 + --> $DIR/bad-reg.rs:171:33 | LL | asm!("/* {} */", in(lr) x); | ^ @@ -827,7 +833,7 @@ LL | asm!("/* {} */", in(lr) x); = note: register class `lr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:176:28 + --> $DIR/bad-reg.rs:178:28 | LL | asm!("", in("xer") x); | ^ @@ -835,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:179:29 + --> $DIR/bad-reg.rs:181:29 | LL | asm!("", out("xer") x); | ^ @@ -843,12 +849,18 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:182:34 + --> $DIR/bad-reg.rs:184:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 112 previous errors +error: cannot use register `spe_acc`: spe_acc is only available on spe targets + --> $DIR/bad-reg.rs:338:18 + | +LL | asm!("", out("spe_acc") _); + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 114 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr b/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr new file mode 100644 index 000000000000..2b4657bf358e --- /dev/null +++ b/tests/ui/asm/powerpc/bad-reg.powerpcspe.stderr @@ -0,0 +1,938 @@ +error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:38:18 + | +LL | asm!("", out("sp") _); + | ^^^^^^^^^^^ + +error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:40:18 + | +LL | asm!("", out("r2") _); + | ^^^^^^^^^^^ + +error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:46:18 + | +LL | asm!("", out("r30") _); + | ^^^^^^^^^^^^ + +error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:48:18 + | +LL | asm!("", out("fp") _); + | ^^^^^^^^^^^ + +error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:50:18 + | +LL | asm!("", out("vrsave") _); + | ^^^^^^^^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:139:18 + | +LL | asm!("", in("cr") x); + | ^^^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:142:18 + | +LL | asm!("", out("cr") x); + | ^^^^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:145:26 + | +LL | asm!("/* {} */", in(cr) x); + | ^^^^^^^^ + +error: register class `cr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:148:26 + | +LL | asm!("/* {} */", out(cr) _); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:152:18 + | +LL | asm!("", in("ctr") x); + | ^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:155:18 + | +LL | asm!("", out("ctr") x); + | ^^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:158:26 + | +LL | asm!("/* {} */", in(ctr) x); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:161:26 + | +LL | asm!("/* {} */", out(ctr) _); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:165:18 + | +LL | asm!("", in("lr") x); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:168:18 + | +LL | asm!("", out("lr") x); + | ^^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:171:26 + | +LL | asm!("/* {} */", in(lr) x); + | ^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:174:26 + | +LL | asm!("/* {} */", out(lr) _); + | ^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:178:18 + | +LL | asm!("", in("xer") x); + | ^^^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:181:18 + | +LL | asm!("", out("xer") x); + | ^^^^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:184:26 + | +LL | asm!("/* {} */", in(xer) x); + | ^^^^^^^^^ + +error: register class `xer` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:187:26 + | +LL | asm!("/* {} */", out(xer) _); + | ^^^^^^^^^^ + +error: register `cr0` conflicts with register `cr` + --> $DIR/bad-reg.rs:191:31 + | +LL | asm!("", out("cr") _, out("cr0") _); + | ----------- ^^^^^^^^^^^^ register `cr0` + | | + | register `cr` + +error: register `cr1` conflicts with register `cr` + --> $DIR/bad-reg.rs:193:31 + | +LL | asm!("", out("cr") _, out("cr1") _); + | ----------- ^^^^^^^^^^^^ register `cr1` + | | + | register `cr` + +error: register `cr2` conflicts with register `cr` + --> $DIR/bad-reg.rs:195:31 + | +LL | asm!("", out("cr") _, out("cr2") _); + | ----------- ^^^^^^^^^^^^ register `cr2` + | | + | register `cr` + +error: register `cr3` conflicts with register `cr` + --> $DIR/bad-reg.rs:197:31 + | +LL | asm!("", out("cr") _, out("cr3") _); + | ----------- ^^^^^^^^^^^^ register `cr3` + | | + | register `cr` + +error: register `cr4` conflicts with register `cr` + --> $DIR/bad-reg.rs:199:31 + | +LL | asm!("", out("cr") _, out("cr4") _); + | ----------- ^^^^^^^^^^^^ register `cr4` + | | + | register `cr` + +error: register `cr5` conflicts with register `cr` + --> $DIR/bad-reg.rs:201:31 + | +LL | asm!("", out("cr") _, out("cr5") _); + | ----------- ^^^^^^^^^^^^ register `cr5` + | | + | register `cr` + +error: register `cr6` conflicts with register `cr` + --> $DIR/bad-reg.rs:203:31 + | +LL | asm!("", out("cr") _, out("cr6") _); + | ----------- ^^^^^^^^^^^^ register `cr6` + | | + | register `cr` + +error: register `cr7` conflicts with register `cr` + --> $DIR/bad-reg.rs:205:31 + | +LL | asm!("", out("cr") _, out("cr7") _); + | ----------- ^^^^^^^^^^^^ register `cr7` + | | + | register `cr` + +error: register `vs0` conflicts with register `f0` + --> $DIR/bad-reg.rs:208:31 + | +LL | asm!("", out("f0") _, out("vs0") _); + | ----------- ^^^^^^^^^^^^ register `vs0` + | | + | register `f0` + +error: register `vs1` conflicts with register `f1` + --> $DIR/bad-reg.rs:210:31 + | +LL | asm!("", out("f1") _, out("vs1") _); + | ----------- ^^^^^^^^^^^^ register `vs1` + | | + | register `f1` + +error: register `vs2` conflicts with register `f2` + --> $DIR/bad-reg.rs:212:31 + | +LL | asm!("", out("f2") _, out("vs2") _); + | ----------- ^^^^^^^^^^^^ register `vs2` + | | + | register `f2` + +error: register `vs3` conflicts with register `f3` + --> $DIR/bad-reg.rs:214:31 + | +LL | asm!("", out("f3") _, out("vs3") _); + | ----------- ^^^^^^^^^^^^ register `vs3` + | | + | register `f3` + +error: register `vs4` conflicts with register `f4` + --> $DIR/bad-reg.rs:216:31 + | +LL | asm!("", out("f4") _, out("vs4") _); + | ----------- ^^^^^^^^^^^^ register `vs4` + | | + | register `f4` + +error: register `vs5` conflicts with register `f5` + --> $DIR/bad-reg.rs:218:31 + | +LL | asm!("", out("f5") _, out("vs5") _); + | ----------- ^^^^^^^^^^^^ register `vs5` + | | + | register `f5` + +error: register `vs6` conflicts with register `f6` + --> $DIR/bad-reg.rs:220:31 + | +LL | asm!("", out("f6") _, out("vs6") _); + | ----------- ^^^^^^^^^^^^ register `vs6` + | | + | register `f6` + +error: register `vs7` conflicts with register `f7` + --> $DIR/bad-reg.rs:222:31 + | +LL | asm!("", out("f7") _, out("vs7") _); + | ----------- ^^^^^^^^^^^^ register `vs7` + | | + | register `f7` + +error: register `vs8` conflicts with register `f8` + --> $DIR/bad-reg.rs:224:31 + | +LL | asm!("", out("f8") _, out("vs8") _); + | ----------- ^^^^^^^^^^^^ register `vs8` + | | + | register `f8` + +error: register `vs9` conflicts with register `f9` + --> $DIR/bad-reg.rs:226:31 + | +LL | asm!("", out("f9") _, out("vs9") _); + | ----------- ^^^^^^^^^^^^ register `vs9` + | | + | register `f9` + +error: register `vs10` conflicts with register `f10` + --> $DIR/bad-reg.rs:228:32 + | +LL | asm!("", out("f10") _, out("vs10") _); + | ------------ ^^^^^^^^^^^^^ register `vs10` + | | + | register `f10` + +error: register `vs11` conflicts with register `f11` + --> $DIR/bad-reg.rs:230:32 + | +LL | asm!("", out("f11") _, out("vs11") _); + | ------------ ^^^^^^^^^^^^^ register `vs11` + | | + | register `f11` + +error: register `vs12` conflicts with register `f12` + --> $DIR/bad-reg.rs:232:32 + | +LL | asm!("", out("f12") _, out("vs12") _); + | ------------ ^^^^^^^^^^^^^ register `vs12` + | | + | register `f12` + +error: register `vs13` conflicts with register `f13` + --> $DIR/bad-reg.rs:234:32 + | +LL | asm!("", out("f13") _, out("vs13") _); + | ------------ ^^^^^^^^^^^^^ register `vs13` + | | + | register `f13` + +error: register `vs14` conflicts with register `f14` + --> $DIR/bad-reg.rs:236:32 + | +LL | asm!("", out("f14") _, out("vs14") _); + | ------------ ^^^^^^^^^^^^^ register `vs14` + | | + | register `f14` + +error: register `vs15` conflicts with register `f15` + --> $DIR/bad-reg.rs:238:32 + | +LL | asm!("", out("f15") _, out("vs15") _); + | ------------ ^^^^^^^^^^^^^ register `vs15` + | | + | register `f15` + +error: register `vs16` conflicts with register `f16` + --> $DIR/bad-reg.rs:240:32 + | +LL | asm!("", out("f16") _, out("vs16") _); + | ------------ ^^^^^^^^^^^^^ register `vs16` + | | + | register `f16` + +error: register `vs17` conflicts with register `f17` + --> $DIR/bad-reg.rs:242:32 + | +LL | asm!("", out("f17") _, out("vs17") _); + | ------------ ^^^^^^^^^^^^^ register `vs17` + | | + | register `f17` + +error: register `vs18` conflicts with register `f18` + --> $DIR/bad-reg.rs:244:32 + | +LL | asm!("", out("f18") _, out("vs18") _); + | ------------ ^^^^^^^^^^^^^ register `vs18` + | | + | register `f18` + +error: register `vs19` conflicts with register `f19` + --> $DIR/bad-reg.rs:246:32 + | +LL | asm!("", out("f19") _, out("vs19") _); + | ------------ ^^^^^^^^^^^^^ register `vs19` + | | + | register `f19` + +error: register `vs20` conflicts with register `f20` + --> $DIR/bad-reg.rs:248:32 + | +LL | asm!("", out("f20") _, out("vs20") _); + | ------------ ^^^^^^^^^^^^^ register `vs20` + | | + | register `f20` + +error: register `vs21` conflicts with register `f21` + --> $DIR/bad-reg.rs:250:32 + | +LL | asm!("", out("f21") _, out("vs21") _); + | ------------ ^^^^^^^^^^^^^ register `vs21` + | | + | register `f21` + +error: register `vs22` conflicts with register `f22` + --> $DIR/bad-reg.rs:252:32 + | +LL | asm!("", out("f22") _, out("vs22") _); + | ------------ ^^^^^^^^^^^^^ register `vs22` + | | + | register `f22` + +error: register `vs23` conflicts with register `f23` + --> $DIR/bad-reg.rs:254:32 + | +LL | asm!("", out("f23") _, out("vs23") _); + | ------------ ^^^^^^^^^^^^^ register `vs23` + | | + | register `f23` + +error: register `vs24` conflicts with register `f24` + --> $DIR/bad-reg.rs:256:32 + | +LL | asm!("", out("f24") _, out("vs24") _); + | ------------ ^^^^^^^^^^^^^ register `vs24` + | | + | register `f24` + +error: register `vs25` conflicts with register `f25` + --> $DIR/bad-reg.rs:258:32 + | +LL | asm!("", out("f25") _, out("vs25") _); + | ------------ ^^^^^^^^^^^^^ register `vs25` + | | + | register `f25` + +error: register `vs26` conflicts with register `f26` + --> $DIR/bad-reg.rs:260:32 + | +LL | asm!("", out("f26") _, out("vs26") _); + | ------------ ^^^^^^^^^^^^^ register `vs26` + | | + | register `f26` + +error: register `vs27` conflicts with register `f27` + --> $DIR/bad-reg.rs:262:32 + | +LL | asm!("", out("f27") _, out("vs27") _); + | ------------ ^^^^^^^^^^^^^ register `vs27` + | | + | register `f27` + +error: register `vs28` conflicts with register `f28` + --> $DIR/bad-reg.rs:264:32 + | +LL | asm!("", out("f28") _, out("vs28") _); + | ------------ ^^^^^^^^^^^^^ register `vs28` + | | + | register `f28` + +error: register `vs29` conflicts with register `f29` + --> $DIR/bad-reg.rs:266:32 + | +LL | asm!("", out("f29") _, out("vs29") _); + | ------------ ^^^^^^^^^^^^^ register `vs29` + | | + | register `f29` + +error: register `vs30` conflicts with register `f30` + --> $DIR/bad-reg.rs:268:32 + | +LL | asm!("", out("f30") _, out("vs30") _); + | ------------ ^^^^^^^^^^^^^ register `vs30` + | | + | register `f30` + +error: register `vs31` conflicts with register `f31` + --> $DIR/bad-reg.rs:270:32 + | +LL | asm!("", out("f31") _, out("vs31") _); + | ------------ ^^^^^^^^^^^^^ register `vs31` + | | + | register `f31` + +error: register `v0` conflicts with register `vs32` + --> $DIR/bad-reg.rs:272:33 + | +LL | asm!("", out("vs32") _, out("v0") _); + | ------------- ^^^^^^^^^^^ register `v0` + | | + | register `vs32` + +error: register `v1` conflicts with register `vs33` + --> $DIR/bad-reg.rs:274:33 + | +LL | asm!("", out("vs33") _, out("v1") _); + | ------------- ^^^^^^^^^^^ register `v1` + | | + | register `vs33` + +error: register `v2` conflicts with register `vs34` + --> $DIR/bad-reg.rs:276:33 + | +LL | asm!("", out("vs34") _, out("v2") _); + | ------------- ^^^^^^^^^^^ register `v2` + | | + | register `vs34` + +error: register `v3` conflicts with register `vs35` + --> $DIR/bad-reg.rs:278:33 + | +LL | asm!("", out("vs35") _, out("v3") _); + | ------------- ^^^^^^^^^^^ register `v3` + | | + | register `vs35` + +error: register `v4` conflicts with register `vs36` + --> $DIR/bad-reg.rs:280:33 + | +LL | asm!("", out("vs36") _, out("v4") _); + | ------------- ^^^^^^^^^^^ register `v4` + | | + | register `vs36` + +error: register `v5` conflicts with register `vs37` + --> $DIR/bad-reg.rs:282:33 + | +LL | asm!("", out("vs37") _, out("v5") _); + | ------------- ^^^^^^^^^^^ register `v5` + | | + | register `vs37` + +error: register `v6` conflicts with register `vs38` + --> $DIR/bad-reg.rs:284:33 + | +LL | asm!("", out("vs38") _, out("v6") _); + | ------------- ^^^^^^^^^^^ register `v6` + | | + | register `vs38` + +error: register `v7` conflicts with register `vs39` + --> $DIR/bad-reg.rs:286:33 + | +LL | asm!("", out("vs39") _, out("v7") _); + | ------------- ^^^^^^^^^^^ register `v7` + | | + | register `vs39` + +error: register `v8` conflicts with register `vs40` + --> $DIR/bad-reg.rs:288:33 + | +LL | asm!("", out("vs40") _, out("v8") _); + | ------------- ^^^^^^^^^^^ register `v8` + | | + | register `vs40` + +error: register `v9` conflicts with register `vs41` + --> $DIR/bad-reg.rs:290:33 + | +LL | asm!("", out("vs41") _, out("v9") _); + | ------------- ^^^^^^^^^^^ register `v9` + | | + | register `vs41` + +error: register `v10` conflicts with register `vs42` + --> $DIR/bad-reg.rs:292:33 + | +LL | asm!("", out("vs42") _, out("v10") _); + | ------------- ^^^^^^^^^^^^ register `v10` + | | + | register `vs42` + +error: register `v11` conflicts with register `vs43` + --> $DIR/bad-reg.rs:294:33 + | +LL | asm!("", out("vs43") _, out("v11") _); + | ------------- ^^^^^^^^^^^^ register `v11` + | | + | register `vs43` + +error: register `v12` conflicts with register `vs44` + --> $DIR/bad-reg.rs:296:33 + | +LL | asm!("", out("vs44") _, out("v12") _); + | ------------- ^^^^^^^^^^^^ register `v12` + | | + | register `vs44` + +error: register `v13` conflicts with register `vs45` + --> $DIR/bad-reg.rs:298:33 + | +LL | asm!("", out("vs45") _, out("v13") _); + | ------------- ^^^^^^^^^^^^ register `v13` + | | + | register `vs45` + +error: register `v14` conflicts with register `vs46` + --> $DIR/bad-reg.rs:300:33 + | +LL | asm!("", out("vs46") _, out("v14") _); + | ------------- ^^^^^^^^^^^^ register `v14` + | | + | register `vs46` + +error: register `v15` conflicts with register `vs47` + --> $DIR/bad-reg.rs:302:33 + | +LL | asm!("", out("vs47") _, out("v15") _); + | ------------- ^^^^^^^^^^^^ register `v15` + | | + | register `vs47` + +error: register `v16` conflicts with register `vs48` + --> $DIR/bad-reg.rs:304:33 + | +LL | asm!("", out("vs48") _, out("v16") _); + | ------------- ^^^^^^^^^^^^ register `v16` + | | + | register `vs48` + +error: register `v17` conflicts with register `vs49` + --> $DIR/bad-reg.rs:306:33 + | +LL | asm!("", out("vs49") _, out("v17") _); + | ------------- ^^^^^^^^^^^^ register `v17` + | | + | register `vs49` + +error: register `v18` conflicts with register `vs50` + --> $DIR/bad-reg.rs:308:33 + | +LL | asm!("", out("vs50") _, out("v18") _); + | ------------- ^^^^^^^^^^^^ register `v18` + | | + | register `vs50` + +error: register `v19` conflicts with register `vs51` + --> $DIR/bad-reg.rs:310:33 + | +LL | asm!("", out("vs51") _, out("v19") _); + | ------------- ^^^^^^^^^^^^ register `v19` + | | + | register `vs51` + +error: register `v20` conflicts with register `vs52` + --> $DIR/bad-reg.rs:312:33 + | +LL | asm!("", out("vs52") _, out("v20") _); + | ------------- ^^^^^^^^^^^^ register `v20` + | | + | register `vs52` + +error: register `v21` conflicts with register `vs53` + --> $DIR/bad-reg.rs:314:33 + | +LL | asm!("", out("vs53") _, out("v21") _); + | ------------- ^^^^^^^^^^^^ register `v21` + | | + | register `vs53` + +error: register `v22` conflicts with register `vs54` + --> $DIR/bad-reg.rs:316:33 + | +LL | asm!("", out("vs54") _, out("v22") _); + | ------------- ^^^^^^^^^^^^ register `v22` + | | + | register `vs54` + +error: register `v23` conflicts with register `vs55` + --> $DIR/bad-reg.rs:318:33 + | +LL | asm!("", out("vs55") _, out("v23") _); + | ------------- ^^^^^^^^^^^^ register `v23` + | | + | register `vs55` + +error: register `v24` conflicts with register `vs56` + --> $DIR/bad-reg.rs:320:33 + | +LL | asm!("", out("vs56") _, out("v24") _); + | ------------- ^^^^^^^^^^^^ register `v24` + | | + | register `vs56` + +error: register `v25` conflicts with register `vs57` + --> $DIR/bad-reg.rs:322:33 + | +LL | asm!("", out("vs57") _, out("v25") _); + | ------------- ^^^^^^^^^^^^ register `v25` + | | + | register `vs57` + +error: register `v26` conflicts with register `vs58` + --> $DIR/bad-reg.rs:324:33 + | +LL | asm!("", out("vs58") _, out("v26") _); + | ------------- ^^^^^^^^^^^^ register `v26` + | | + | register `vs58` + +error: register `v27` conflicts with register `vs59` + --> $DIR/bad-reg.rs:326:33 + | +LL | asm!("", out("vs59") _, out("v27") _); + | ------------- ^^^^^^^^^^^^ register `v27` + | | + | register `vs59` + +error: register `v28` conflicts with register `vs60` + --> $DIR/bad-reg.rs:328:33 + | +LL | asm!("", out("vs60") _, out("v28") _); + | ------------- ^^^^^^^^^^^^ register `v28` + | | + | register `vs60` + +error: register `v29` conflicts with register `vs61` + --> $DIR/bad-reg.rs:330:33 + | +LL | asm!("", out("vs61") _, out("v29") _); + | ------------- ^^^^^^^^^^^^ register `v29` + | | + | register `vs61` + +error: register `v30` conflicts with register `vs62` + --> $DIR/bad-reg.rs:332:33 + | +LL | asm!("", out("vs62") _, out("v30") _); + | ------------- ^^^^^^^^^^^^ register `v30` + | | + | register `vs62` + +error: register `v31` conflicts with register `vs63` + --> $DIR/bad-reg.rs:334:33 + | +LL | asm!("", out("vs63") _, out("v31") _); + | ------------- ^^^^^^^^^^^^ register `v31` + | | + | register `vs63` + +error: register class `spe_acc` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:340:26 + | +LL | asm!("/* {} */", out(spe_acc) _); + | ^^^^^^^^^^^^^^ + +error: cannot use register `r13`: r13 is a reserved register on this target + --> $DIR/bad-reg.rs:42:18 + | +LL | asm!("", out("r13") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:44:18 + | +LL | asm!("", out("r29") _); + | ^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:55:18 + | +LL | asm!("", in("v0") v32x4); // requires altivec + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:57:18 + | +LL | asm!("", out("v0") v32x4); // requires altivec + | ^^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:59:18 + | +LL | asm!("", in("v0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:62:18 + | +LL | asm!("", out("v0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:65:18 + | +LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:68:18 + | +LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:71:26 + | +LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:73:26 + | +LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx + | ^^^^^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:76:26 + | +LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^ + +error: register class `vreg` requires at least one of the following target features: altivec, vsx + --> $DIR/bad-reg.rs:79:26 + | +LL | asm!("/* {} */", out(vreg) _); // requires altivec + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:98:18 + | +LL | asm!("", in("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:100:18 + | +LL | asm!("", out("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:102:18 + | +LL | asm!("", in("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:104:18 + | +LL | asm!("", out("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:106:18 + | +LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:109:18 + | +LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:112:26 + | +LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:114:26 + | +LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:116:26 + | +LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:119:26 + | +LL | asm!("/* {} */", out(vsreg) _); // requires vsx + | ^^^^^^^^^^^^ + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:139:27 + | +LL | asm!("", in("cr") x); + | ^ + | + = note: register class `cr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:142:28 + | +LL | asm!("", out("cr") x); + | ^ + | + = note: register class `cr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:145:33 + | +LL | asm!("/* {} */", in(cr) x); + | ^ + | + = note: register class `cr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:152:28 + | +LL | asm!("", in("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:155:29 + | +LL | asm!("", out("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:158:34 + | +LL | asm!("/* {} */", in(ctr) x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:165:27 + | +LL | asm!("", in("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:168:28 + | +LL | asm!("", out("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:171:33 + | +LL | asm!("/* {} */", in(lr) x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:178:28 + | +LL | asm!("", in("xer") x); + | ^ + | + = note: register class `xer` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:181:29 + | +LL | asm!("", out("xer") x); + | ^ + | + = note: register class `xer` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:184:34 + | +LL | asm!("/* {} */", in(xer) x); + | ^ + | + = note: register class `xer` supports these types: + +error: aborting due to 128 previous errors + diff --git a/tests/ui/asm/powerpc/bad-reg.rs b/tests/ui/asm/powerpc/bad-reg.rs index 7ceae5c6d8d3..c06dcf668d1b 100644 --- a/tests/ui/asm/powerpc/bad-reg.rs +++ b/tests/ui/asm/powerpc/bad-reg.rs @@ -1,5 +1,5 @@ //@ add-minicore -//@ revisions: powerpc powerpc64 powerpc64le aix64 +//@ revisions: powerpc powerpc64 powerpc64le aix64 powerpcspe //@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu //@[powerpc] needs-llvm-components: powerpc //@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu @@ -8,6 +8,8 @@ //@[powerpc64le] needs-llvm-components: powerpc //@[aix64] compile-flags: --target powerpc64-ibm-aix //@[aix64] needs-llvm-components: powerpc +//@[powerpcspe] compile-flags: --target powerpc-unknown-linux-gnuspe +//@[powerpcspe] needs-llvm-components: powerpc //@ ignore-backends: gcc // ignore-tidy-linelength @@ -40,7 +42,7 @@ fn f() { asm!("", out("r13") _); //~^ ERROR cannot use register `r13`: r13 is a reserved register on this target asm!("", out("r29") _); - //[powerpc]~^ ERROR cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm + //[powerpc,powerpcspe]~^ ERROR cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm asm!("", out("r30") _); //~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm asm!("", out("fp") _); @@ -51,31 +53,31 @@ fn f() { // vreg asm!("", out("v0") _); // always ok asm!("", in("v0") v32x4); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx asm!("", out("v0") v32x4); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx asm!("", in("v0") v64x2); // requires vsx - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64]~^^ ERROR `vsx` target feature is not enabled asm!("", out("v0") v64x2); // requires vsx - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64]~^^ ERROR `vsx` target feature is not enabled asm!("", in("v0") x); // FIXME: should be ok if vsx is available - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("", out("v0") x); // FIXME: should be ok if vsx is available - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", in(vreg) v32x4); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx asm!("/* {} */", in(vreg) v64x2); // requires vsx - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64]~^^ ERROR `vsx` target feature is not enabled asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", out(vreg) _); // requires altivec - //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx + //[powerpc,powerpcspe]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx // v20-v31 (vs52-vs63) are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). asm!("", out("v20") _); asm!("", out("v21") _); @@ -94,28 +96,28 @@ fn f() { // vsreg asm!("", out("vs0") _); // always ok asm!("", in("vs0") v32x4); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", out("vs0") v32x4); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", in("vs0") v64x2); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", out("vs0") v64x2); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("", in("vs0") x); // FIXME: should be ok if vsx is available - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("", out("vs0") x); // FIXME: should be ok if vsx is available - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", in(vsreg) v32x4); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("/* {} */", in(vsreg) v64x2); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", out(vsreg) _); // requires vsx - //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc,powerpcspe,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature // v20-v31 (vs52-vs63) are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). asm!("", out("vs52") _); @@ -331,5 +333,11 @@ fn f() { //~^ ERROR register `v30` conflicts with register `vs62` asm!("", out("vs63") _, out("v31") _); //~^ ERROR register `v31` conflicts with register `vs63` + + // powerpc-*spe target specific tests + asm!("", out("spe_acc") _); + //[aix64,powerpc,powerpc64,powerpc64le]~^ ERROR cannot use register `spe_acc`: spe_acc is only available on spe targets + asm!("/* {} */", out(spe_acc) _); + //~^ ERROR can only be used as a clobber } } diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr index 897f872ae72a..8e2da4dcc2a4 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -282,7 +282,7 @@ error: type `u8` cannot be used with this register class LL | asm!("", in("v0") b); | ^ | - = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class --> $DIR/bad-reg.rs:95:28 @@ -290,7 +290,7 @@ error: type `u8` cannot be used with this register class LL | asm!("", out("v0") b); | ^ | - = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `u8` cannot be used with this register class --> $DIR/bad-reg.rs:108:35 @@ -298,7 +298,7 @@ error: type `u8` cannot be used with this register class LL | asm!("/* {} */", in(vreg) b); | ^ | - = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + = note: register class `vreg` supports these types: i32, f16, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f16x8, f32x4, f64x2 error: type `i32` cannot be used with this register class --> $DIR/bad-reg.rs:120:27 diff --git a/tests/ui/asm/unpretty-expanded.stdout b/tests/ui/asm/unpretty-expanded.stdout index 7678f6bc3450..ce636c150c1c 100644 --- a/tests/ui/asm/unpretty-expanded.stdout +++ b/tests/ui/asm/unpretty-expanded.stdout @@ -1,6 +1,5 @@ #![feature(prelude_import)] #![no_std] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/asm/x86_64/global_asm_escape.rs b/tests/ui/asm/x86_64/global_asm_escape.rs new file mode 100644 index 000000000000..59214e958a85 --- /dev/null +++ b/tests/ui/asm/x86_64/global_asm_escape.rs @@ -0,0 +1,17 @@ +//@ run-pass +//@ only-x86_64-unknown-linux-gnu +//@ ignore-backends: gcc + +// https://github.com/rust-lang/rust/issues/151950 + +unsafe extern "C" { + #[link_name = "exit@GLIBC_2.2.5"] + safe fn exit(status: i32) -> !; + safe fn my_exit(status: i32) -> !; +} + +core::arch::global_asm!(".global my_exit", "my_exit:", "jmp {}", sym exit); + +fn main() { + my_exit(0); +} diff --git a/tests/ui/asm/x86_64/naked_asm_escape.rs b/tests/ui/asm/x86_64/naked_asm_escape.rs new file mode 100644 index 000000000000..57962993ef91 --- /dev/null +++ b/tests/ui/asm/x86_64/naked_asm_escape.rs @@ -0,0 +1,32 @@ +//@ build-fail +//@ only-x86_64-unknown-linux-gnu +//@ dont-check-compiler-stderr +//@ dont-check-compiler-stdout +//@ ignore-backends: gcc + +// https://github.com/rust-lang/rust/issues/151950 + +unsafe extern "C" { + #[link_name = "memset]; mov eax, 1; #"] + unsafe fn inject(); +} + +#[unsafe(export_name = "memset]; mov eax, 1; #")] +extern "C" fn inject_() {} + +#[unsafe(naked)] +extern "C" fn print_0() -> usize { + core::arch::naked_asm!("lea rax, [{}]", "ret", sym inject) +} + +#[unsafe(naked)] +extern "C" fn print_1() -> usize { + core::arch::naked_asm!("lea rax, [{}]", "ret", sym inject_) +} + +fn main() { + dbg!(print_0()); + dbg!(print_1()); +} + +//~? ERROR linking diff --git a/tests/ui/asm/x86_64/type-check-2.stderr b/tests/ui/asm/x86_64/type-check-2.stderr index d5c5a3ff1f84..e5d39b2fbd05 100644 --- a/tests/ui/asm/x86_64/type-check-2.stderr +++ b/tests/ui/asm/x86_64/type-check-2.stderr @@ -21,7 +21,6 @@ LL | asm!("{}", in(reg) vec![0]); | ^^^^^^^ | = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot use value of type `(i32, i32, i32)` for inline assembly --> $DIR/type-check-2.rs:52:28 diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs b/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs deleted file mode 100644 index 2ff5a0353a0a..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.rs +++ /dev/null @@ -1,29 +0,0 @@ -// We used to say "ambiguous associated type" on ambiguous associated consts. -// Ensure that we now use the correct label. - -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] -#![allow(incomplete_features)] - -trait Trait0: Parent0 + Parent0 {} -trait Parent0 { - #[type_const] - const K: (); -} - -fn take0(_: impl Trait0) {} -//~^ ERROR ambiguous associated constant `K` in bounds of `Trait0` - -trait Trait1: Parent1 + Parent2 {} -trait Parent1 { - #[type_const] - const C: i32; -} -trait Parent2 { - #[type_const] - const C: &'static str; -} - -fn take1(_: impl Trait1) {} -//~^ ERROR ambiguous associated constant `C` in bounds of `Trait1` - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr deleted file mode 100644 index 3541664d1c6a..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0222]: ambiguous associated constant `K` in bounds of `Trait0` - --> $DIR/assoc-const-eq-ambiguity.rs:13:25 - | -LL | const K: (); - | ----------- - | | - | ambiguous `K` from `Parent0` - | ambiguous `K` from `Parent0` -... -LL | fn take0(_: impl Trait0) {} - | ^^^^^^^^^^ ambiguous associated constant `K` - | - = help: consider introducing a new type parameter `T` and adding `where` constraints: - where - T: Trait0, - T: Parent0::K = { () }, - T: Parent0::K = { () } - -error[E0222]: ambiguous associated constant `C` in bounds of `Trait1` - --> $DIR/assoc-const-eq-ambiguity.rs:26:25 - | -LL | const C: i32; - | ------------ ambiguous `C` from `Parent1` -... -LL | const C: &'static str; - | --------------------- ambiguous `C` from `Parent2` -... -LL | fn take1(_: impl Trait1) {} - | ^^^^^^^ ambiguous associated constant `C` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0222`. diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs deleted file mode 100644 index 5232b895803e..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Check that we eventually catch types of assoc const bounds -// (containing late-bound vars) that are ill-formed. -#![feature( - associated_const_equality, - min_generic_const_args, - adt_const_params, - unsized_const_params, -)] -#![allow(incomplete_features)] - -use std::marker::ConstParamTy_; - -trait Trait { - #[type_const] - const K: T; -} - -fn take( - _: impl Trait< - < fn(&'a str) -> &'a str as Project>::Out as Discard>::Out, - K = { () } - >, -) {} -//~^^^^^ ERROR implementation of `Project` is not general enough -//~^^^^ ERROR higher-ranked subtype error -//~| ERROR higher-ranked subtype error - -trait Project { type Out; } -impl Project for fn(T) -> T { type Out = T; } - -trait Discard { type Out; } -impl Discard for T { type Out = (); } - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr deleted file mode 100644 index a0329e2b15d1..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 - | -LL | K = { () } - | ^^^^^^ - -error: higher-ranked subtype error - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13 - | -LL | K = { () } - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: implementation of `Project` is not general enough - --> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:19:13 - | -LL | _: impl Trait< - | _____________^ -LL | | < fn(&'a str) -> &'a str as Project>::Out as Discard>::Out, -LL | | K = { () } -LL | | >, - | |_____^ implementation of `Project` is not general enough - | - = note: `Project` would have to be implemented for the type `for<'a> fn(&'a str) -> &'a str` - = note: ...but `Project` is actually implemented for the type `fn(&'0 str) -> &'0 str`, for some specific lifetime `'0` - -error: aborting due to 3 previous errors - diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs deleted file mode 100644 index ef8077b9f44a..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Check that we don't reject non-escaping late-bound vars in the type of assoc const bindings. -// There's no reason why we should disallow them. -// -//@ check-pass - -#![feature( - associated_const_equality, - min_generic_const_args, - adt_const_params, - unsized_const_params, -)] -#![allow(incomplete_features)] - -use std::marker::ConstParamTy_; - -trait Trait { - #[type_const] - const K: T; -} - -fn take( - _: impl Trait< - fn(&'a str) -> &'a str as Discard>::Out, - K = { () } - >, -) {} - -trait Discard { type Out; } -impl Discard for T { type Out = (); } - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs b/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs deleted file mode 100644 index 22a03e47b2f7..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-const_evaluatable_unchecked.rs +++ /dev/null @@ -1,21 +0,0 @@ -// The impl of lint `const_evaluatable_unchecked` used to wrongly assume and `assert!` that -// successfully evaluating a type-system constant that has non-region args had to be an anon const. -// In the case below however we have a type-system assoc const (here: `<() as TraitA>::K`). -// -// issue: -//@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] -#![allow(incomplete_features)] - -pub trait TraitA { - #[type_const] - const K: u8 = 0; -} -pub trait TraitB {} - -impl TraitA for () {} -impl TraitB for () where (): TraitA {} - -fn check() where (): TraitB {} - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs deleted file mode 100644 index 1ab93ea596a7..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Detect and reject escaping late-bound generic params in -// the type of assoc consts used in an equality bound. -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] -#![allow(incomplete_features)] - -trait Trait<'a> { - #[type_const] - const K: &'a (); -} - -fn take(_: impl for<'r> Trait<'r, K = { &() }>) {} -//~^ ERROR the type of the associated constant `K` cannot capture late-bound generic parameters -//~| NOTE its type cannot capture the late-bound lifetime parameter `'r` -//~| NOTE the late-bound lifetime parameter `'r` is defined here -//~| NOTE `K` has type `&'r ()` - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr deleted file mode 100644 index d6a7eb6cfc7d..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error: the type of the associated constant `K` cannot capture late-bound generic parameters - --> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:11:35 - | -LL | fn take(_: impl for<'r> Trait<'r, K = { &() }>) {} - | -- ^ its type cannot capture the late-bound lifetime parameter `'r` - | | - | the late-bound lifetime parameter `'r` is defined here - | - = note: `K` has type `&'r ()` - -error: aborting due to 1 previous error - diff --git a/tests/ui/associated-consts/assoc-const-eq-missing.rs b/tests/ui/associated-consts/assoc-const-eq-missing.rs deleted file mode 100644 index f384927e4a34..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-missing.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![feature(associated_const_equality)] -#![allow(unused)] - -pub trait Foo { - const N: usize; -} - -pub struct Bar; - -impl Foo for Bar { - const N: usize = 3; -} - -fn foo1>() {} -//~^ ERROR associated constant `Z` not found for `Foo` -fn foo2>() {} -//~^ ERROR associated type `Z` not found for `Foo` -fn foo3>() {} -//~^ ERROR associated constant `Z` not found for `Foo` - -fn main() { - foo1::(); - foo2::(); - foo3::(); -} diff --git a/tests/ui/associated-consts/assoc-const-eq-missing.stderr b/tests/ui/associated-consts/assoc-const-eq-missing.stderr deleted file mode 100644 index 318c85dcfd6f..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-missing.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0220]: associated constant `Z` not found for `Foo` - --> $DIR/assoc-const-eq-missing.rs:14:16 - | -LL | fn foo1>() {} - | ^ help: there is an associated constant with a similar name: `N` - -error[E0220]: associated type `Z` not found for `Foo` - --> $DIR/assoc-const-eq-missing.rs:16:16 - | -LL | fn foo2>() {} - | ^ associated type `Z` not found - -error[E0220]: associated constant `Z` not found for `Foo` - --> $DIR/assoc-const-eq-missing.rs:18:16 - | -LL | fn foo3>() {} - | ^ help: there is an associated constant with a similar name: `N` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs deleted file mode 100644 index 0afb95a0b033..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Regression test for issue #108271. -// Detect and reject generic params in the type of assoc consts used in an equality bound. -#![feature( - associated_const_equality, - min_generic_const_args, - adt_const_params, - unsized_const_params, -)] -#![allow(incomplete_features)] - -use std::marker::ConstParamTy_; - -trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> { - #[type_const] - const K: &'a [T; N]; -} - -fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} -//~^ ERROR the type of the associated constant `K` must not depend on generic parameters -//~| NOTE its type must not depend on the lifetime parameter `'r` -//~| NOTE the lifetime parameter `'r` is defined here -//~| NOTE `K` has type `&'r [A; Q]` -//~| ERROR the type of the associated constant `K` must not depend on generic parameters -//~| NOTE its type must not depend on the type parameter `A` -//~| NOTE the type parameter `A` is defined here -//~| NOTE `K` has type `&'r [A; Q]` -//~| ERROR the type of the associated constant `K` must not depend on generic parameters -//~| NOTE its type must not depend on the const parameter `Q` -//~| NOTE the const parameter `Q` is defined here -//~| NOTE `K` has type `&'r [A; Q]` - -trait Project: ConstParamTy_ { - #[type_const] - const SELF: Self; -} - -fn take1(_: impl Project) {} -//~^ ERROR the type of the associated constant `SELF` must not depend on `impl Trait` -//~| NOTE its type must not depend on `impl Trait` -//~| NOTE the `impl Trait` is specified here - -fn take2>(_: P) {} -//~^ ERROR the type of the associated constant `SELF` must not depend on generic parameters -//~| NOTE its type must not depend on the type parameter `P` -//~| NOTE the type parameter `P` is defined here -//~| NOTE `SELF` has type `P` - -trait Iface<'r>: ConstParamTy_ { - //~^ NOTE the lifetime parameter `'r` is defined here - //~| NOTE the lifetime parameter `'r` is defined here - type Assoc: Trait<'r, Self, Q, K = { loop {} }> - //~^ ERROR the type of the associated constant `K` must not depend on generic parameters - //~| ERROR the type of the associated constant `K` must not depend on generic parameters - //~| NOTE its type must not depend on the lifetime parameter `'r` - //~| NOTE `K` has type `&'r [Self; Q]` - //~| ERROR the type of the associated constant `K` must not depend on `Self` - //~| NOTE its type must not depend on `Self` - //~| NOTE `K` has type `&'r [Self; Q]` - //~| ERROR the type of the associated constant `K` must not depend on generic parameters - //~| NOTE its type must not depend on the const parameter `Q` - //~| NOTE the const parameter `Q` is defined here - //~| NOTE `K` has type `&'r [Self; Q]` - //~| NOTE its type must not depend on the lifetime parameter `'r` - //~| NOTE `K` has type `&'r [Self; Q]` - //~| ERROR the type of the associated constant `K` must not depend on `Self` - //~| NOTE its type must not depend on `Self` - //~| NOTE `K` has type `&'r [Self; Q]` - //~| ERROR the type of the associated constant `K` must not depend on generic parameters - //~| NOTE its type must not depend on the const parameter `Q` - //~| NOTE the const parameter `Q` is defined here - //~| NOTE `K` has type `&'r [Self; Q]` - //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - where - Self: Sized + 'r; -} - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr deleted file mode 100644 index 229dd10c0beb..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ /dev/null @@ -1,108 +0,0 @@ -error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 - | -LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | -- the lifetime parameter `'r` is defined here ^ its type must not depend on the lifetime parameter `'r` - | - = note: `K` has type `&'r [A; Q]` - -error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 - | -LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - the type parameter `A` is defined here ^ its type must not depend on the type parameter `A` - | - = note: `K` has type `&'r [A; Q]` - -error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:18:77 - | -LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(_: impl Trait<'r, A, Q, K = { loop {} }>) {} - | - ^ its type must not depend on the const parameter `Q` - | | - | the const parameter `Q` is defined here - | - = note: `K` has type `&'r [A; Q]` - -error: the type of the associated constant `SELF` must not depend on `impl Trait` - --> $DIR/assoc-const-eq-param-in-ty.rs:37:26 - | -LL | fn take1(_: impl Project) {} - | -------------^^^^------ - | | | - | | its type must not depend on `impl Trait` - | the `impl Trait` is specified here - -error: the type of the associated constant `SELF` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:42:21 - | -LL | fn take2>(_: P) {} - | - ^^^^ its type must not depend on the type parameter `P` - | | - | the type parameter `P` is defined here - | - = note: `SELF` has type `P` - -error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 - | -LL | trait Iface<'r>: ConstParamTy_ { - | -- the lifetime parameter `'r` is defined here -... -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> - | ^ its type must not depend on the lifetime parameter `'r` - | - = note: `K` has type `&'r [Self; Q]` - -error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 - | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> - | ^ its type must not depend on `Self` - | - = note: `K` has type `&'r [Self; Q]` - -error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 - | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> - | - ^ its type must not depend on the const parameter `Q` - | | - | the const parameter `Q` is defined here - | - = note: `K` has type `&'r [Self; Q]` - -error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 - | -LL | trait Iface<'r>: ConstParamTy_ { - | -- the lifetime parameter `'r` is defined here -... -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> - | ^ its type must not depend on the lifetime parameter `'r` - | - = note: `K` has type `&'r [Self; Q]` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: the type of the associated constant `K` must not depend on `Self` - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 - | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> - | ^ its type must not depend on `Self` - | - = note: `K` has type `&'r [Self; Q]` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: the type of the associated constant `K` must not depend on generic parameters - --> $DIR/assoc-const-eq-param-in-ty.rs:51:52 - | -LL | type Assoc: Trait<'r, Self, Q, K = { loop {} }> - | - ^ its type must not depend on the const parameter `Q` - | | - | the const parameter `Q` is defined here - | - = note: `K` has type `&'r [Self; Q]` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 11 previous errors - diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs deleted file mode 100644 index d9b8a8cd43d7..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Regression test for issue #118040. -// Ensure that we support assoc const eq bounds where the assoc const comes from a supertrait. - -//@ check-pass - -#![feature( - associated_const_equality, - min_generic_const_args, - adt_const_params, - unsized_const_params, -)] -#![allow(incomplete_features)] - -use std::marker::ConstParamTy_; - -trait Trait: SuperTrait {} -trait SuperTrait: SuperSuperTrait {} -trait SuperSuperTrait { - #[type_const] - const K: T; -} - -fn take(_: impl Trait) {} - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs b/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs deleted file mode 100644 index 41857eca87de..000000000000 --- a/tests/ui/associated-consts/assoc-const-eq-ty-alias-noninteracting.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Regression test for issue #112560. -// Respect the fact that (associated) types and constants live in different namespaces and -// therefore equality bounds involving identically named associated items don't conflict if -// their kind (type vs. const) differs. This obviously extends to supertraits. - -//@ check-pass - -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] -#![allow(incomplete_features)] - -trait Trait: SuperTrait { - type N; - type Q; - - #[type_const] - const N: usize; -} - -trait SuperTrait { - #[type_const] - const Q: &'static str; -} - -fn take0(_: impl Trait) {} - -fn take1(_: impl Trait) {} - -fn main() {} diff --git a/tests/ui/associated-consts/assoc-const.rs b/tests/ui/associated-consts/assoc-const.rs deleted file mode 100644 index 4eed8bba53b1..000000000000 --- a/tests/ui/associated-consts/assoc-const.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ run-pass -#![feature(associated_const_equality, min_generic_const_args)] -#![allow(unused, incomplete_features)] - -pub trait Foo { - #[type_const] - const N: usize; -} - -pub struct Bar; - -impl Foo for Bar { - #[type_const] - const N: usize = 3; -} - -const TEST:usize = 3; - - -fn foo>() {} - -fn main() { - foo::() -} diff --git a/tests/ui/associated-consts/associated-const-access.rs b/tests/ui/associated-consts/associated-const-access.rs new file mode 100644 index 000000000000..d6508d4922ae --- /dev/null +++ b/tests/ui/associated-consts/associated-const-access.rs @@ -0,0 +1,14 @@ +//! regression test for +//@ run-pass + + +struct Foo; + +impl Foo { + const FOO: [i32; 3] = [0; 3]; +} + +pub fn main() { + let foo = Foo::FOO; + assert_eq!(foo, [0i32, 0, 0]); +} diff --git a/tests/ui/associated-consts/associated-const-in-trait.rs b/tests/ui/associated-consts/associated-const-in-trait.rs index 4d88f4ff5316..6b0b43feb109 100644 --- a/tests/ui/associated-consts/associated-const-in-trait.rs +++ b/tests/ui/associated-consts/associated-const-in-trait.rs @@ -7,8 +7,6 @@ trait Trait { impl dyn Trait { //~^ ERROR the trait `Trait` is not dyn compatible [E0038] const fn n() -> usize { Self::N } - //~^ ERROR the trait `Trait` is not dyn compatible [E0038] - //~| ERROR the trait `Trait` is not dyn compatible } fn main() {} diff --git a/tests/ui/associated-consts/associated-const-in-trait.stderr b/tests/ui/associated-consts/associated-const-in-trait.stderr index fba7f53c097f..fb4a55110b4e 100644 --- a/tests/ui/associated-consts/associated-const-in-trait.stderr +++ b/tests/ui/associated-consts/associated-const-in-trait.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/associated-const-in-trait.rs:7:6 + --> $DIR/associated-const-in-trait.rs:7:10 | LL | impl dyn Trait { - | ^^^^^^^^^ `Trait` is not dyn compatible + | ^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit @@ -11,41 +11,9 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Trait { | ----- this trait is not dyn compatible... LL | const N: usize; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `N` = help: consider moving `N` to another trait -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/associated-const-in-trait.rs:9:29 - | -LL | const fn n() -> usize { Self::N } - | ^^^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/associated-const-in-trait.rs:4:11 - | -LL | trait Trait { - | ----- this trait is not dyn compatible... -LL | const N: usize; - | ^ ...because it contains this associated `const` - = help: consider moving `N` to another trait - -error[E0038]: the trait `Trait` is not dyn compatible - --> $DIR/associated-const-in-trait.rs:9:29 - | -LL | const fn n() -> usize { Self::N } - | ^^^^^^^ `Trait` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $DIR/associated-const-in-trait.rs:4:11 - | -LL | trait Trait { - | ----- this trait is not dyn compatible... -LL | const N: usize; - | ^ ...because it contains this associated `const` - = help: consider moving `N` to another trait - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr index 40f5f889f361..8b38905e1c57 100644 --- a/tests/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/tests/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -23,8 +23,6 @@ note: erroneous constant encountered | LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered --> $DIR/defaults-not-assumed-fail.rs:34:5 @@ -33,7 +31,6 @@ LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - = note: this note originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/associated-consts/equality-unused-issue-126729.rs b/tests/ui/associated-consts/equality-unused-issue-126729.rs deleted file mode 100644 index 35b49314b5f5..000000000000 --- a/tests/ui/associated-consts/equality-unused-issue-126729.rs +++ /dev/null @@ -1,53 +0,0 @@ -//@ check-pass - -#![feature(associated_const_equality, min_generic_const_args)] -#![allow(incomplete_features)] -#![deny(dead_code)] - -trait Tr { - #[type_const] - const I: i32; -} - -impl Tr for () { - #[type_const] - const I: i32 = 1; -} - -fn foo() -> impl Tr {} - -trait Tr2 { - #[type_const] - const J: i32; - #[type_const] - const K: i32; -} - -impl Tr2 for () { - #[type_const] - const J: i32 = 1; - #[type_const] - const K: i32 = 1; -} - -fn foo2() -> impl Tr2 {} - -mod t { - pub trait Tr3 { - #[type_const] - const L: i32; - } - - impl Tr3 for () { - #[type_const] - const L: i32 = 1; - } -} - -fn foo3() -> impl t::Tr3 {} - -fn main() { - foo(); - foo2(); - foo3(); -} diff --git a/tests/ui/associated-consts/issue-102335-const.rs b/tests/ui/associated-consts/issue-102335-const.rs deleted file mode 100644 index f9b816fd3bc9..000000000000 --- a/tests/ui/associated-consts/issue-102335-const.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![feature(associated_const_equality, min_generic_const_args)] -#![allow(incomplete_features)] - -trait T { - type A: S = 34>; - //~^ ERROR associated item constraints are not allowed here - //~| ERROR associated item constraints are not allowed here -} - -trait S { - #[type_const] - const C: i32; -} - -fn main() {} diff --git a/tests/ui/associated-consts/issue-110933.rs b/tests/ui/associated-consts/issue-110933.rs index 0284369f4d65..0115fb7d6e65 100644 --- a/tests/ui/associated-consts/issue-110933.rs +++ b/tests/ui/associated-consts/issue-110933.rs @@ -1,16 +1,15 @@ //@ check-pass -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] #![allow(incomplete_features)] pub trait Trait { - #[type_const] - const ASSOC: usize; + type const ASSOC: usize; } pub fn foo< T: Trait< - ASSOC = { + ASSOC = const { let a = 10_usize; let b: &'_ usize = &a; *b diff --git a/tests/ui/associated-consts/issue-93835.rs b/tests/ui/associated-consts/issue-93835.rs deleted file mode 100644 index d6c2acaa9edc..000000000000 --- a/tests/ui/associated-consts/issue-93835.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(type_ascription)] - -fn e() { - type_ascribe!(p, a>); - //~^ ERROR cannot find type `a` in this scope - //~| ERROR cannot find value - //~| ERROR associated const equality - //~| ERROR cannot find trait `p` in this scope - //~| ERROR associated const equality -} - -fn main() {} diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs deleted file mode 100644 index 7f3304f07656..000000000000 --- a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![feature(associated_const_equality, min_generic_const_args)] -#![allow(incomplete_features)] - -// Issue 110549 - -pub trait TraitWAssocConst { - #[type_const] - const A: usize; -} - -fn foo>() {} - -fn bar() { - foo::(); - //~^ ERROR type mismatch resolving `::A == 32` -} - -fn main() {} diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs new file mode 100644 index 000000000000..cb0b8a102eb4 --- /dev/null +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.rs @@ -0,0 +1,19 @@ +#![feature(generic_const_exprs)] +//~^ WARN the feature `generic_const_exprs` is incomplete +#![feature(min_generic_const_args)] +//~^ WARN the feature `min_generic_const_args` is incomplete +#![feature(inherent_associated_types)] +//~^ WARN the feature `inherent_associated_types` is incomplete + +struct OnDiskDirEntry<'a>(&'a ()); + +impl<'a> OnDiskDirEntry<'a> { + type const LFN_FRAGMENT_LEN: i64 = 2; + + fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { + //~^ ERROR the constant `2` is not of type `usize` + loop {} + } +} + +fn main() {} diff --git a/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr new file mode 100644 index 000000000000..b69a1b7fd7de --- /dev/null +++ b/tests/ui/associated-consts/type-const-in-array-len-wrong-type.stderr @@ -0,0 +1,35 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-const-in-array-len-wrong-type.rs:1:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-const-in-array-len-wrong-type.rs:3:12 + | +LL | #![feature(min_generic_const_args)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + +warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-const-in-array-len-wrong-type.rs:5:12 + | +LL | #![feature(inherent_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 for more information + +error: the constant `2` is not of type `usize` + --> $DIR/type-const-in-array-len-wrong-type.rs:13:26 + | +LL | fn lfn_contents() -> [char; Self::LFN_FRAGMENT_LEN] { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i64` + | + = note: the length of array `[char; 2]` must be type `usize` + +error: aborting due to 1 previous error; 3 warnings emitted + diff --git a/tests/ui/associated-consts/type-const-in-array-len.rs b/tests/ui/associated-consts/type-const-in-array-len.rs new file mode 100644 index 000000000000..d33eacaade2d --- /dev/null +++ b/tests/ui/associated-consts/type-const-in-array-len.rs @@ -0,0 +1,38 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +//~^ WARN the feature `min_generic_const_args` is incomplete +#![feature(inherent_associated_types)] +//~^ WARN the feature `inherent_associated_types` is incomplete + +// Test case from #138226: generic impl with multiple type parameters +struct Foo(A, B); +impl Foo { + type const LEN: usize = 4; + + fn foo() { + let _ = [5; Self::LEN]; + } +} + +// Test case from #138226: generic impl with const parameter +struct Bar; +impl Bar { + type const LEN: usize = 4; + + fn bar() { + let _ = [0; Self::LEN]; + } +} + +// Test case from #150960: non-generic impl with const block +struct Baz; +impl Baz { + type const LEN: usize = 4; + + fn baz() { + let _ = [0; { Self::LEN }]; + } +} + +fn main() {} diff --git a/tests/ui/associated-consts/type-const-in-array-len.stderr b/tests/ui/associated-consts/type-const-in-array-len.stderr new file mode 100644 index 000000000000..546995d13a0a --- /dev/null +++ b/tests/ui/associated-consts/type-const-in-array-len.stderr @@ -0,0 +1,19 @@ +warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-const-in-array-len.rs:3:12 + | +LL | #![feature(min_generic_const_args)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-const-in-array-len.rs:5:12 + | +LL | #![feature(inherent_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 for more information + +warning: 2 warnings emitted + diff --git a/tests/ui/associated-inherent-types/inference-fail.stderr b/tests/ui/associated-inherent-types/inference-fail.stderr index bf329c69e99c..12cc3ae7960c 100644 --- a/tests/ui/associated-inherent-types/inference-fail.stderr +++ b/tests/ui/associated-inherent-types/inference-fail.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/inference-fail.rs:10:12 | LL | let _: S<_>::P = (); - | ^^^^^^^ cannot infer type for type parameter `T` + | ^^^^^^^ cannot infer type error: aborting due to 1 previous error diff --git a/tests/ui/associated-item/issue-48027.stderr b/tests/ui/associated-item/issue-48027.stderr index e5c1ced93413..7abcabc1c79d 100644 --- a/tests/ui/associated-item/issue-48027.stderr +++ b/tests/ui/associated-item/issue-48027.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/issue-48027.rs:6:6 + --> $DIR/issue-48027.rs:6:10 | LL | impl dyn Bar {} - | ^^^^^^^ `Bar` is not dyn compatible + | ^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Bar { | --- this trait is not dyn compatible... LL | const X: usize; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `X` = help: consider moving `X` to another trait error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type diff --git a/tests/ui/associated-item/issue-87638.stderr b/tests/ui/associated-item/issue-87638.stderr index cf6083444b0e..cce20318a23b 100644 --- a/tests/ui/associated-item/issue-87638.stderr +++ b/tests/ui/associated-item/issue-87638.stderr @@ -5,10 +5,13 @@ LL | type Target; | ------------ associated type `Target` defined here ... LL | let _: ::Output; - | ^^^^^^ - | | - | not found in `Trait` - | help: maybe you meant this associated type: `Target` + | ^^^^^^ not found in `Trait` + | +help: maybe you meant this associated type + | +LL - let _: ::Output; +LL + let _: ::Target; + | error[E0576]: cannot find method or associated constant `BAR` in trait `Trait` --> $DIR/issue-87638.rs:20:27 @@ -17,10 +20,13 @@ LL | const FOO: usize; | ----------------- associated constant `FOO` defined here ... LL | let _ = ::BAR; - | ^^^ - | | - | not found in `Trait` - | help: maybe you meant this associated constant: `FOO` + | ^^^ not found in `Trait` + | +help: maybe you meant this associated constant + | +LL - let _ = ::BAR; +LL + let _ = ::FOO; + | error: aborting due to 2 previous errors diff --git a/tests/ui/associated-type-bounds/const-projection-err.gce.stderr b/tests/ui/associated-type-bounds/const-projection-err.gce.stderr deleted file mode 100644 index 9ad851d188d3..000000000000 --- a/tests/ui/associated-type-bounds/const-projection-err.gce.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0271]: type mismatch resolving `::A == 1` - --> $DIR/const-projection-err.rs:16:11 - | -LL | foo::(); - | ^ expected `0`, found `1` - | -note: required by a bound in `foo` - --> $DIR/const-projection-err.rs:13:28 - | -LL | fn foo>() {} - | ^^^^^ required by this bound in `foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-type-bounds/const-projection-err.rs b/tests/ui/associated-type-bounds/const-projection-err.rs deleted file mode 100644 index 80845ec3ee86..000000000000 --- a/tests/ui/associated-type-bounds/const-projection-err.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ revisions: stock gce - -#![feature(associated_const_equality, min_generic_const_args)] -#![allow(incomplete_features)] - -#![cfg_attr(gce, feature(generic_const_exprs))] - -trait TraitWAssocConst { - #[type_const] - const A: usize; -} - -fn foo>() {} - -fn bar>() { - foo::(); - //~^ ERROR type mismatch resolving `::A == 1` -} - -fn main() {} diff --git a/tests/ui/associated-type-bounds/const-projection-err.stock.stderr b/tests/ui/associated-type-bounds/const-projection-err.stock.stderr deleted file mode 100644 index 0cacec26aaee..000000000000 --- a/tests/ui/associated-type-bounds/const-projection-err.stock.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0271]: type mismatch resolving `::A == 1` - --> $DIR/const-projection-err.rs:16:11 - | -LL | foo::(); - | ^ expected `1`, found `0` - | - = note: expected constant `1` - found constant `0` -note: required by a bound in `foo` - --> $DIR/const-projection-err.rs:13:28 - | -LL | fn foo>() {} - | ^^^^^ required by this bound in `foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs index 72c1ab559bdf..56403fdf6630 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs @@ -1,7 +1,6 @@ //@ edition: 2024 #![feature( - associated_const_equality, min_generic_const_args, type_alias_impl_trait, return_type_notation @@ -51,8 +50,7 @@ fn mismatch_2() -> impl Iterator { trait Trait { type Gat; - #[type_const] - const ASSOC: i32; + type const ASSOC: i32; fn foo() -> impl Sized; } @@ -60,8 +58,7 @@ trait Trait { impl Trait for () { type Gat = (); - #[type_const] - const ASSOC: i32 = 3; + type const ASSOC: i32 = 3; fn foo() {} } @@ -69,8 +66,7 @@ impl Trait for () { impl Trait for u32 { type Gat = (); - #[type_const] - const ASSOC: i32 = 4; + type const ASSOC: i32 = 4; fn foo() -> u32 { 42 @@ -81,20 +77,21 @@ fn uncallable(_: impl Iterator) {} fn uncallable_const(_: impl Trait) {} -fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} +fn uncallable_rtn( + _: impl Trait, foo(..): Trait> +) {} type MustFail = dyn Iterator; //~^ ERROR [E0719] -//~| ERROR conflicting associated type bounds +//~| ERROR conflicting associated type bindings trait Trait2 { - #[type_const] - const ASSOC: u32; + type const ASSOC: u32; } type MustFail2 = dyn Trait2; //~^ ERROR [E0719] -//~| ERROR conflicting associated type bounds +//~| ERROR conflicting associated constant bindings type MustFail3 = dyn Iterator; //~^ ERROR [E0719] diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr index a54425c3a295..e6bf93970d0a 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:15:5 + --> $DIR/duplicate-bound-err.rs:14:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -10,7 +10,7 @@ LL | iter::empty::() | +++++ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:19:5 + --> $DIR/duplicate-bound-err.rs:18:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -21,7 +21,7 @@ LL | iter::empty::() | +++++ error[E0282]: type annotations needed - --> $DIR/duplicate-bound-err.rs:23:5 + --> $DIR/duplicate-bound-err.rs:22:5 | LL | iter::empty() | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` @@ -32,7 +32,7 @@ LL | iter::empty::() | +++++ error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:27:51 + --> $DIR/duplicate-bound-err.rs:26:51 | LL | type Tait1> = impl Copy; | ^^^^^^^^^ @@ -40,7 +40,7 @@ LL | type Tait1> = impl Copy; = note: `Tait1` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:29:51 + --> $DIR/duplicate-bound-err.rs:28:51 | LL | type Tait2> = impl Copy; | ^^^^^^^^^ @@ -48,7 +48,7 @@ LL | type Tait2> = impl Copy; = note: `Tait2` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:31:57 + --> $DIR/duplicate-bound-err.rs:30:57 | LL | type Tait3> = impl Copy; | ^^^^^^^^^ @@ -56,7 +56,7 @@ LL | type Tait3> = impl Copy; = note: `Tait3` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:34:14 + --> $DIR/duplicate-bound-err.rs:33:14 | LL | type Tait4 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | type Tait4 = impl Iterator; = note: `Tait4` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:36:14 + --> $DIR/duplicate-bound-err.rs:35:14 | LL | type Tait5 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | type Tait5 = impl Iterator; = note: `Tait5` must be used in combination with a concrete type within the same crate error: unconstrained opaque type - --> $DIR/duplicate-bound-err.rs:38:14 + --> $DIR/duplicate-bound-err.rs:37:14 | LL | type Tait6 = impl Iterator; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | type Tait6 = impl Iterator; = note: `Tait6` must be used in combination with a concrete type within the same crate error[E0277]: `*const ()` cannot be sent between threads safely - --> $DIR/duplicate-bound-err.rs:41:18 + --> $DIR/duplicate-bound-err.rs:40:18 | LL | fn mismatch() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely @@ -91,7 +91,7 @@ LL | iter::empty::<*const ()>() = help: the trait `Send` is not implemented for `*const ()` error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/duplicate-bound-err.rs:46:20 + --> $DIR/duplicate-bound-err.rs:45:20 | LL | fn mismatch_2() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` @@ -100,7 +100,7 @@ LL | iter::empty::() | ----------------------- return type was inferred to be `std::iter::Empty` here error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:110:17 + --> $DIR/duplicate-bound-err.rs:107:17 | LL | fn foo() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -108,16 +108,28 @@ LL | fn foo() -> impl Iterator { LL | [2u32].into_iter() | ------------------ return type was inferred to be `std::array::IntoIter` here +error[E0271]: expected `impl Iterator` to be an iterator that yields `i32`, but it yields `u32` + --> $DIR/duplicate-bound-err.rs:107:17 + | +LL | fn foo() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` + | +note: required by a bound in `Trait3::foo::{anon_assoc#0}` + --> $DIR/duplicate-bound-err.rs:103:31 + | +LL | fn foo() -> impl Iterator; + | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}` + error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:86:42 + --> $DIR/duplicate-bound-err.rs:84:42 | LL | type MustFail = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here | | | `Item` bound here first -error: conflicting associated type bounds for `Item` - --> $DIR/duplicate-bound-err.rs:86:17 +error: conflicting associated type bindings for `Item` + --> $DIR/duplicate-bound-err.rs:84:17 | LL | type MustFail = dyn Iterator; | ^^^^^^^^^^^^^----------^^----------^ @@ -126,15 +138,15 @@ LL | type MustFail = dyn Iterator; | `Item` is specified to be `i32` here error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:95:43 + --> $DIR/duplicate-bound-err.rs:92:43 | LL | type MustFail2 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here | | | `ASSOC` bound here first -error: conflicting associated type bounds for `ASSOC` - --> $DIR/duplicate-bound-err.rs:95:18 +error: conflicting associated constant bindings for `ASSOC` + --> $DIR/duplicate-bound-err.rs:92:18 | LL | type MustFail2 = dyn Trait2; | ^^^^^^^^^^^------------^^------------^ @@ -143,7 +155,7 @@ LL | type MustFail2 = dyn Trait2; | `ASSOC` is specified to be `3` here error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate-bound-err.rs:99:43 + --> $DIR/duplicate-bound-err.rs:96:43 | LL | type MustFail3 = dyn Iterator; | ---------- ^^^^^^^^^^ re-bound here @@ -151,27 +163,15 @@ LL | type MustFail3 = dyn Iterator; | `Item` bound here first error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified - --> $DIR/duplicate-bound-err.rs:102:43 + --> $DIR/duplicate-bound-err.rs:99:43 | LL | type MustFail4 = dyn Trait2; | ------------ ^^^^^^^^^^^^ re-bound here | | | `ASSOC` bound here first -error[E0271]: expected `impl Iterator` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:110:17 - | -LL | fn foo() -> impl Iterator { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` - | -note: required by a bound in `Trait3::foo::{anon_assoc#0}` - --> $DIR/duplicate-bound-err.rs:106:31 - | -LL | fn foo() -> impl Iterator; - | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}` - error[E0271]: expected `Empty` to be an iterator that yields `i32`, but it yields `u32` - --> $DIR/duplicate-bound-err.rs:118:16 + --> $DIR/duplicate-bound-err.rs:115:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` @@ -179,13 +179,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:80:32 + --> $DIR/duplicate-bound-err.rs:76:32 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: expected `Empty` to be an iterator that yields `u32`, but it yields `i32` - --> $DIR/duplicate-bound-err.rs:119:16 + --> $DIR/duplicate-bound-err.rs:116:16 | LL | uncallable(iter::empty::()); | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32` @@ -193,13 +193,13 @@ LL | uncallable(iter::empty::()); | required by a bound introduced by this call | note: required by a bound in `uncallable` - --> $DIR/duplicate-bound-err.rs:80:44 + --> $DIR/duplicate-bound-err.rs:76:44 | LL | fn uncallable(_: impl Iterator) {} | ^^^^^^^^^^ required by this bound in `uncallable` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:120:22 + --> $DIR/duplicate-bound-err.rs:117:22 | LL | uncallable_const(()); | ---------------- ^^ expected `4`, found `3` @@ -209,13 +209,13 @@ LL | uncallable_const(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:82:46 + --> $DIR/duplicate-bound-err.rs:78:46 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:121:22 + --> $DIR/duplicate-bound-err.rs:118:22 | LL | uncallable_const(4u32); | ---------------- ^^^^ expected `3`, found `4` @@ -225,13 +225,13 @@ LL | uncallable_const(4u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_const` - --> $DIR/duplicate-bound-err.rs:82:35 + --> $DIR/duplicate-bound-err.rs:78:35 | LL | fn uncallable_const(_: impl Trait) {} | ^^^^^^^^^ required by this bound in `uncallable_const` error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` - --> $DIR/duplicate-bound-err.rs:122:20 + --> $DIR/duplicate-bound-err.rs:119:20 | LL | uncallable_rtn(()); | -------------- ^^ expected `4`, found `3` @@ -241,13 +241,15 @@ LL | uncallable_rtn(()); = note: expected constant `4` found constant `3` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:84:75 + --> $DIR/duplicate-bound-err.rs:81:61 | -LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} - | ^^^^^^^^^ required by this bound in `uncallable_rtn` +LL | fn uncallable_rtn( + | -------------- required by a bound in this function +LL | _: impl Trait, foo(..): Trait> + | ^^^^^^^^^ required by this bound in `uncallable_rtn` error[E0271]: type mismatch resolving `::ASSOC == 3` - --> $DIR/duplicate-bound-err.rs:123:20 + --> $DIR/duplicate-bound-err.rs:120:20 | LL | uncallable_rtn(17u32); | -------------- ^^^^^ expected `3`, found `4` @@ -257,10 +259,12 @@ LL | uncallable_rtn(17u32); = note: expected constant `3` found constant `4` note: required by a bound in `uncallable_rtn` - --> $DIR/duplicate-bound-err.rs:84:48 + --> $DIR/duplicate-bound-err.rs:81:34 | -LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} - | ^^^^^^^^^ required by this bound in `uncallable_rtn` +LL | fn uncallable_rtn( + | -------------- required by a bound in this function +LL | _: impl Trait, foo(..): Trait> + | ^^^^^^^^^ required by this bound in `uncallable_rtn` error: aborting due to 25 previous errors diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs index 3f40e429260f..39cfa9db072c 100644 --- a/tests/ui/associated-type-bounds/duplicate-bound.rs +++ b/tests/ui/associated-type-bounds/duplicate-bound.rs @@ -1,7 +1,7 @@ //@ edition: 2024 //@ run-pass -#![feature(associated_const_equality, min_generic_const_args, return_type_notation)] +#![feature(min_generic_const_args, return_type_notation)] #![expect(incomplete_features)] #![allow(dead_code, refining_impl_trait_internal, type_alias_bounds)] @@ -189,8 +189,7 @@ trait Tra3 { trait Trait { type Gat; - #[type_const] - const ASSOC: i32; + type const ASSOC: i32; fn foo() -> impl Sized; } @@ -198,8 +197,7 @@ trait Trait { impl Trait for () { type Gat = (); - #[type_const] - const ASSOC: i32 = 3; + type const ASSOC: i32 = 3; fn foo() {} } @@ -224,7 +222,9 @@ fn uncallable_const(_: impl Trait) {} fn callable_const(_: impl Trait) {} -fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} +fn uncallable_rtn( + _: impl Trait, foo(..): Trait> +) {} fn callable_rtn(_: impl Trait) {} diff --git a/tests/ui/associated-type-bounds/issue-99828.stderr b/tests/ui/associated-type-bounds/issue-99828.stderr deleted file mode 100644 index 132d5251987b..000000000000 --- a/tests/ui/associated-type-bounds/issue-99828.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0658]: associated const equality is incomplete - --> $DIR/issue-99828.rs:1:43 - | -LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { - | ^^^^^^^^^ - | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` 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: expected type, found constant - --> $DIR/issue-99828.rs:1:50 - | -LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { - | ---- ^^ unexpected constant - | | - | expected a type because of this associated type - | -note: the associated type is defined here - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - -error: expected type, found constant - --> $DIR/issue-99828.rs:1:50 - | -LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { - | ---- ^^ unexpected constant - | | - | expected a type because of this associated type - | -note: the associated type is defined here - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr index ad97df377b75..54bcef455746 100644 --- a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr +++ b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr @@ -2,7 +2,7 @@ error[E0191]: the value of the associated types `Item` and `IntoIter` in `IntoIt --> $DIR/overlaping-bound-suggestion.rs:7:13 | LL | inner: >::IntoIterator as Item>::Core, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated types: `IntoIterator, Item = Type, IntoIter = Type>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated types: `IntoIterator, Item = /* Type */, IntoIter = /* Type */>` error: aborting due to 1 previous error diff --git a/tests/ui/associated-type-bounds/return-type-notation/trait-alias.rs b/tests/ui/associated-type-bounds/return-type-notation/trait-alias.rs new file mode 100644 index 000000000000..88f60a72afa1 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/trait-alias.rs @@ -0,0 +1,13 @@ +// Regression test for . +//@ check-pass +#![feature(return_type_notation, trait_alias)] + +trait Tr { + fn f() -> impl Sized; +} + +trait Al = Tr; + +fn f>() {} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout index 7499df5be5da..c53491a6747c 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout +++ b/tests/ui/associated-type-bounds/return-type-notation/unpretty-parenthesized.stdout @@ -1,5 +1,4 @@ #![feature(prelude_import)] -#[macro_use] extern crate std; #[prelude_import] use std::prelude::rust_2021::*; diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr index 21bc37bb3ea2..3b89ed66b355 100644 --- a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr +++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr @@ -6,6 +6,8 @@ LL | const N: C::M = 4u8; | = note: expected associated type `::M` found type `u8` + = note: the associated type `::M` is defined as `u8` in the implementation, but the where-bound `C` shadows this definition + see issue #152409 for more information help: consider constraining the associated type `::M` to `u8` | LL | impl> U for u16 { diff --git a/tests/ui/associated-type-bounds/trait-alias-bound-vars.rs b/tests/ui/associated-type-bounds/trait-alias-bound-vars.rs new file mode 100644 index 000000000000..4644cee21008 --- /dev/null +++ b/tests/ui/associated-type-bounds/trait-alias-bound-vars.rs @@ -0,0 +1,14 @@ +// Check that we're successfully collecting bound vars behind trait aliases. +// Regression test for . +//@ check-pass +//@ needs-rustc-debug-assertions +#![feature(trait_alias)] + +trait A<'a> { type X; } +trait B: for<'a> A<'a> {} +trait C = B; + +fn f() where T: C {} +fn g() where T: C A<'r>> {} + +fn main() {} diff --git a/tests/ui/associated-types/associated-type-as-value.rs b/tests/ui/associated-types/associated-type-as-value.rs new file mode 100644 index 000000000000..ddc808236658 --- /dev/null +++ b/tests/ui/associated-types/associated-type-as-value.rs @@ -0,0 +1,7 @@ +//! regression test for + +fn foo() { + T::Item; //~ ERROR no associated item named `Item` found +} + +fn main() { } diff --git a/tests/ui/associated-types/associated-type-as-value.stderr b/tests/ui/associated-types/associated-type-as-value.stderr new file mode 100644 index 000000000000..c553582b3907 --- /dev/null +++ b/tests/ui/associated-types/associated-type-as-value.stderr @@ -0,0 +1,11 @@ +error[E0599]: no associated item named `Item` found for type parameter `T` in the current scope + --> $DIR/associated-type-as-value.rs:4:8 + | +LL | fn foo() { + | - associated item `Item` not found for this type parameter +LL | T::Item; + | ^^^^ associated item not found in `T` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/associated-types/associated-type-const-nomalization.rs b/tests/ui/associated-types/associated-type-const-nomalization.rs new file mode 100644 index 000000000000..b7951ba9a435 --- /dev/null +++ b/tests/ui/associated-types/associated-type-const-nomalization.rs @@ -0,0 +1,15 @@ +//! regression test for +//@ check-pass + +trait Mirror { + type It; +} + +impl Mirror for T { + type It = Self; +} + +fn main() { + let c: ::It = 5; + const CCCC: ::It = 5; +} diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-const.rs b/tests/ui/associated-types/associated-type-where-non-lifetime-const.rs new file mode 100644 index 000000000000..31bf139e39cd --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-const.rs @@ -0,0 +1,13 @@ +//! regression test for #148627 + +#![feature(associated_type_defaults)] + +trait Trait { + type Assoc2 + = () + where + for [(); C]: Copy; + //~^ ERROR: only lifetime parameters can be used in this context +} + +fn main() {} diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-const.stderr b/tests/ui/associated-types/associated-type-where-non-lifetime-const.stderr new file mode 100644 index 000000000000..bd1d6e13893a --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-const.stderr @@ -0,0 +1,13 @@ +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/associated-type-where-non-lifetime-const.rs:9:19 + | +LL | for [(); C]: Copy; + | ^ + | + = note: see issue #108185 for more information + = help: add `#![feature(non_lifetime_binders)]` 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: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-type.rs b/tests/ui/associated-types/associated-type-where-non-lifetime-type.rs new file mode 100644 index 000000000000..d4624619e6d8 --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-type.rs @@ -0,0 +1,18 @@ +//! regression test for #149233 + +trait Foo { + type Bar<'a> + where + Self: Sized; + fn test(&self); +} +impl Foo for () { + type Bar<'a> + = () + where + for T:; + //~^ ERROR: only lifetime parameters can be used in this context + fn test(&self) {} +} + +fn main() {} diff --git a/tests/ui/associated-types/associated-type-where-non-lifetime-type.stderr b/tests/ui/associated-types/associated-type-where-non-lifetime-type.stderr new file mode 100644 index 000000000000..a8a71b929d95 --- /dev/null +++ b/tests/ui/associated-types/associated-type-where-non-lifetime-type.stderr @@ -0,0 +1,13 @@ +error[E0658]: only lifetime parameters can be used in this context + --> $DIR/associated-type-where-non-lifetime-type.rs:13:13 + | +LL | for T:; + | ^ + | + = note: see issue #108185 for more information + = help: add `#![feature(non_lifetime_binders)]` 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: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-types/associated-types-eq-1.stderr b/tests/ui/associated-types/associated-types-eq-1.stderr index 869583df644f..54e50f36fb6a 100644 --- a/tests/ui/associated-types/associated-types-eq-1.stderr +++ b/tests/ui/associated-types/associated-types-eq-1.stderr @@ -1,16 +1,13 @@ error[E0425]: cannot find type `A` in this scope --> $DIR/associated-types-eq-1.rs:10:12 | -LL | fn foo2(x: I) { - | - similarly named type parameter `I` defined here LL | let _: A = x.boo(); | ^ | -help: a type parameter with a similar name exists - | -LL - let _: A = x.boo(); -LL + let _: I = x.boo(); +help: you might have meant to use an associated type of the same name | +LL | let _: I::A = x.boo(); + | +++ help: you might be missing a type parameter | LL | fn foo2(x: I) { diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr index 19c34241e5f2..9be346516c89 100644 --- a/tests/ui/associated-types/associated-types-eq-2.stderr +++ b/tests/ui/associated-types/associated-types-eq-2.stderr @@ -7,8 +7,8 @@ LL | impl Tr3 for Bar { | |____^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -17,8 +17,8 @@ error[E0658]: associated const equality is incomplete LL | impl Tr3 for Qux { | ^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -27,8 +27,8 @@ error[E0658]: associated const equality is incomplete LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar { | ^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -37,8 +37,8 @@ error[E0658]: associated const equality is incomplete LL | impl Tr3 for Bar { | ^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0229]: associated item constraints are not allowed here diff --git a/tests/ui/associated-types/associated-types-incomplete-object.stderr b/tests/ui/associated-types/associated-types-incomplete-object.stderr index 0c9761afeb51..52aa6adc4695 100644 --- a/tests/ui/associated-types/associated-types-incomplete-object.stderr +++ b/tests/ui/associated-types/associated-types-incomplete-object.stderr @@ -5,7 +5,7 @@ LL | type B; | ------ `B` defined here ... LL | let b = &42isize as &dyn Foo; - | ^^^^^^^^^^^^ help: specify the associated type: `Foo` + | ^^^^^^^^^^^^ help: specify the associated type: `Foo` error[E0191]: the value of the associated type `A` in `Foo` must be specified --> $DIR/associated-types-incomplete-object.rs:26:30 @@ -14,7 +14,7 @@ LL | type A; | ------ `A` defined here ... LL | let c = &42isize as &dyn Foo; - | ^^^^^^^^^^^ help: specify the associated type: `Foo` + | ^^^^^^^^^^^ help: specify the associated type: `Foo` error[E0191]: the value of the associated types `A` and `B` in `Foo` must be specified --> $DIR/associated-types-incomplete-object.rs:29:30 @@ -25,7 +25,7 @@ LL | type B; | ------ `B` defined here ... LL | let d = &42isize as &dyn Foo; - | ^^^ help: specify the associated types: `Foo` + | ^^^ help: specify the associated types: `Foo` error: aborting due to 3 previous errors diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.rs b/tests/ui/associated-types/associated-types-overridden-binding-2.rs index 247724eaaf11..fe8041363246 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.rs +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.rs @@ -4,5 +4,5 @@ trait I32Iterator = Iterator; fn main() { let _: &dyn I32Iterator = &vec![42].into_iter(); - //~^ ERROR conflicting associated type bounds + //~^ ERROR conflicting associated type bindings } diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr index e96a2446b6ce..1594e5729781 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -1,4 +1,4 @@ -error: conflicting associated type bounds for `Item` +error: conflicting associated type bindings for `Item` --> $DIR/associated-types-overridden-binding-2.rs:6:13 | LL | trait I32Iterator = Iterator; diff --git a/tests/ui/associated-types/associated-types-overridden-binding.rs b/tests/ui/associated-types/associated-types-overridden-binding.rs index 333a3e30c7dc..82004f042ea1 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.rs +++ b/tests/ui/associated-types/associated-types-overridden-binding.rs @@ -8,5 +8,5 @@ trait U32Iterator = I32Iterator; //~ ERROR type annotations needed fn main() { let _: &dyn I32Iterator; - //~^ ERROR conflicting associated type bounds + //~^ ERROR conflicting associated type bindings } diff --git a/tests/ui/associated-types/associated-types-overridden-binding.stderr b/tests/ui/associated-types/associated-types-overridden-binding.stderr index 08ab9b63ee9f..d31b05065719 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding.stderr @@ -22,7 +22,7 @@ note: required by a bound in `I32Iterator` LL | trait I32Iterator = Iterator; | ^^^^^^^^^^ required by this bound in `I32Iterator` -error: conflicting associated type bounds for `Item` +error: conflicting associated type bindings for `Item` --> $DIR/associated-types-overridden-binding.rs:10:13 | LL | trait I32Iterator = Iterator; diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index 7d19ac85982a..d22d9ce659a7 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -75,6 +75,8 @@ LL | fn make() -> Self::Ty { 0u8 } found type `u8` = help: consider constraining the associated type ` as Tr>::Ty` to `u8` or calling a method that returns ` as Tr>::Ty` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type ` as Tr>::Ty` is defined as `u8` in the implementation, but the where-bound `A2` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:44:29 @@ -89,6 +91,8 @@ LL | fn make() -> Self::Ty { true } | = note: expected associated type ` as Tr>::Ty` found type `bool` + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B2` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:87:32 @@ -121,6 +125,8 @@ help: a method is available that returns ` as Tr>::Ty` | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B<()>` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:89:33 @@ -153,6 +159,8 @@ help: a method is available that returns ` as Tr>::Ty` | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B2<()>` shadows this definition + see issue #152409 for more information error: aborting due to 9 previous errors; 1 warning emitted diff --git a/tests/ui/associated-types/issue-19883.stderr b/tests/ui/associated-types/issue-19883.stderr index 35184e852cfe..435c2933e361 100644 --- a/tests/ui/associated-types/issue-19883.stderr +++ b/tests/ui/associated-types/issue-19883.stderr @@ -5,10 +5,13 @@ LL | type Output; | ------------ associated type `Output` defined here ... LL | >::Dst - | ^^^ - | | - | not found in `From` - | help: maybe you meant this associated type: `Output` + | ^^^ not found in `From` + | +help: maybe you meant this associated type + | +LL - >::Dst +LL + >::Output + | error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/issue-22037.stderr b/tests/ui/associated-types/issue-22037.stderr index b02dad97d354..0b5f18f81c0b 100644 --- a/tests/ui/associated-types/issue-22037.stderr +++ b/tests/ui/associated-types/issue-22037.stderr @@ -4,10 +4,13 @@ error[E0576]: cannot find associated type `X` in trait `A` LL | type Output; | ------------ associated type `Output` defined here LL | fn a(&self) -> ::X; - | ^ - | | - | not found in `A` - | help: maybe you meant this associated type: `Output` + | ^ not found in `A` + | +help: maybe you meant this associated type + | +LL - fn a(&self) -> ::X; +LL + fn a(&self) -> ::Output; + | error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/issue-23595-1.stderr b/tests/ui/associated-types/issue-23595-1.stderr index 694b68ef0901..8083355deb76 100644 --- a/tests/ui/associated-types/issue-23595-1.stderr +++ b/tests/ui/associated-types/issue-23595-1.stderr @@ -6,7 +6,7 @@ LL | type Value; LL | type ChildKey; | ------------- `ChildKey` defined here LL | type Children = dyn Index; - | ------------- `Children` defined here ^^^^^^^^^ help: specify the associated types: `Hierarchy` + | ------------- `Children` defined here ^^^^^^^^^ help: specify the associated types: `Hierarchy` error: aborting due to 1 previous error diff --git a/tests/ui/associated-types/issue-38821.rs b/tests/ui/associated-types/issue-38821.rs index 60d3b224a5bf..35c371235e64 100644 --- a/tests/ui/associated-types/issue-38821.rs +++ b/tests/ui/associated-types/issue-38821.rs @@ -32,16 +32,16 @@ pub trait Column: Expression {} //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied //~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied pub enum ColumnInsertValue where //~^ ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied Col: Column, Expr: Expression::Nullable>, -//~^ ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied -//~| ERROR the trait bound `::SqlType: NotNull` is not satisfied +//~^ ERROR the trait bound `::SqlType: IntoNullable` is not satisfied { Expression(Col, Expr), Default(Col), diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr index b03a3cf7f47e..07b146f8bfca 100644 --- a/tests/ui/associated-types/issue-38821.stderr +++ b/tests/ui/associated-types/issue-38821.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:35:1 + --> $DIR/issue-38821.rs:37:1 | LL | pub enum ColumnInsertValue where | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` @@ -16,8 +16,8 @@ help: consider extending the `where` clause, but there might be an alternative b LL | Expr: Expression::Nullable>, ::SqlType: NotNull | +++++++++++++++++++++++++++++++++++++ -error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 +error[E0277]: the trait bound `::SqlType: IntoNullable` is not satisfied + --> $DIR/issue-38821.rs:43:22 | LL | Expr: Expression::Nullable>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` @@ -82,10 +82,13 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:37:10 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -94,6 +97,18 @@ LL | impl IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here +note: required for `ColumnInsertValue` to implement `Debug` + --> $DIR/issue-38821.rs:37:10 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ +... +LL | Expr: Expression::Nullable>, + | ------------------------------------------------ unsatisfied trait bound + = help: consider manually implementing `Debug` to avoid undesired bounds help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -118,10 +133,13 @@ LL | Expr: Expression::Nullable>, ::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:37:10 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ---- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -130,6 +148,17 @@ LL | impl IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here +note: required for `ColumnInsertValue` to implement `Copy` + --> $DIR/issue-38821.rs:37:10 + | +LL | #[derive(Debug, Copy, Clone)] + | ---- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ +... +LL | Expr: Expression::Nullable>, + | ------------------------------------------------ unsatisfied trait bound help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -183,10 +212,13 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:37:10 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -195,6 +227,18 @@ LL | impl IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here +note: required for `ColumnInsertValue` to implement `Clone` + --> $DIR/issue-38821.rs:37:10 + | +LL | #[derive(Debug, Copy, Clone)] + | ----- in this derive macro expansion +... +LL | pub enum ColumnInsertValue where + | ^^^^^^^^^^^^^^^^^ +... +LL | Expr: Expression::Nullable>, + | ------------------------------------------------ unsatisfied trait bound + = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting the associated type | LL | Expr: Expression::Nullable>, ::SqlType: NotNull, @@ -216,10 +260,10 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:23:10 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -245,10 +289,10 @@ LL | impl IntoNullable for T { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied - --> $DIR/issue-38821.rs:38:22 + --> $DIR/issue-38821.rs:23:23 | -LL | Expr: Expression::Nullable>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotNull` is not implemented for `::SqlType` +LL | #[derive(Debug, Copy, Clone)] + | ^^^^^ the trait `NotNull` is not implemented for `::SqlType` | note: required for `::SqlType` to implement `IntoNullable` --> $DIR/issue-38821.rs:9:18 @@ -257,7 +301,6 @@ LL | impl IntoNullable for T { | ------- ^^^^^^^^^^^^ ^ | | | unsatisfied trait bound introduced here - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the trait bound `::SqlType: NotNull` is not satisfied --> $DIR/issue-38821.rs:23:10 diff --git a/tests/ui/associated-types/normalization-generality-2.rs b/tests/ui/associated-types/normalization-generality-2.rs index 50287f9ee9b8..2a50f7e449ad 100644 --- a/tests/ui/associated-types/normalization-generality-2.rs +++ b/tests/ui/associated-types/normalization-generality-2.rs @@ -1,4 +1,7 @@ //@ build-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver // Ensures that we don't regress on "implementation is not general enough" when // normalizating under binders. Unlike `normalization-generality.rs`, this also produces diff --git a/tests/ui/associated-types/normalization-generality.rs b/tests/ui/associated-types/normalization-generality.rs index 35fcf53b6414..fca70bc7ec67 100644 --- a/tests/ui/associated-types/normalization-generality.rs +++ b/tests/ui/associated-types/normalization-generality.rs @@ -1,4 +1,7 @@ //@ build-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver // Ensures that we don't regress on "implementation is not general enough" when // normalizating under binders. diff --git a/tests/ui/associated-types/normalization-ice-issue-149746.rs b/tests/ui/associated-types/normalization-ice-issue-149746.rs new file mode 100644 index 000000000000..8932d321b7e5 --- /dev/null +++ b/tests/ui/associated-types/normalization-ice-issue-149746.rs @@ -0,0 +1,17 @@ +//@ edition: 2015..2021 +#![warn(rust_2021_incompatible_closure_captures)] +trait Owner { type Ty; } +impl Owner for () { type Ty = T; } +pub struct Warns { + _significant_drop: <() as Owner>::Ty, + //~^ ERROR expected a `FnMut()` closure, found `T` + field: String, +} +pub fn test(w: Warns) { + //~^ ERROR expected a `FnMut()` closure, found `T` + _ = || w.field + //~^ ERROR expected a `FnMut()` closure, found `T` + //~| ERROR expected a `FnMut()` closure, found `T` + //~| WARN: changes to closure capture in Rust 2021 will affect drop order +} +fn main() {} diff --git a/tests/ui/associated-types/normalization-ice-issue-149746.stderr b/tests/ui/associated-types/normalization-ice-issue-149746.stderr new file mode 100644 index 000000000000..7f983d6e14ae --- /dev/null +++ b/tests/ui/associated-types/normalization-ice-issue-149746.stderr @@ -0,0 +1,80 @@ +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:6:24 + | +LL | _significant_drop: <() as Owner>::Ty, + | ^^^^^^^^^^^^^^^^^^^^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` +help: consider restricting type parameter `T` with trait `FnMut` + | +LL | pub struct Warns { + | +++++++++ + +warning: changes to closure capture in Rust 2021 will affect drop order + --> $DIR/normalization-ice-issue-149746.rs:12:9 + | +LL | _ = || w.field + | ^^ ------- + | | | + | | in Rust 2018, `w` is dropped here, but in Rust 2021, only `w.field` will be dropped here as part of the closure + | in Rust 2018, this closure captures all of `w`, but in Rust 2021, it will only capture `w.field` + | + = note: for more information, see +note: the lint level is defined here + --> $DIR/normalization-ice-issue-149746.rs:2:9 + | +LL | #![warn(rust_2021_incompatible_closure_captures)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: add a dummy let to cause `w` to be fully captured + | +LL | _ = || { let _ = &w; w.field } + | +++++++++++++ + + +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:12:9 + | +LL | _ = || w.field + | ^^^^^^^^^^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` + +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:10:16 + | +LL | pub fn test(w: Warns) { + | ^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` + +error[E0277]: expected a `FnMut()` closure, found `T` + --> $DIR/normalization-ice-issue-149746.rs:12:9 + | +LL | _ = || w.field + | ^^^^^^^^^^ expected an `FnMut()` closure, found `T` + | + = note: wrap the `T` in a closure with no arguments: `|| { /* code */ }` +note: required by a bound in `Owner::Ty` + --> $DIR/normalization-ice-issue-149746.rs:3:26 + | +LL | trait Owner { type Ty; } + | ^^^^^^^ required by this bound in `Owner::Ty` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/param-env-shadowing-false-positive.rs b/tests/ui/associated-types/param-env-shadowing-false-positive.rs new file mode 100644 index 000000000000..41993f5cba19 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-false-positive.rs @@ -0,0 +1,17 @@ +// Regression test for issue #149910. +// The compiler previously incorrectly claimed that the local param-env bound +// shadowed the global impl, but they are actually the same. + +trait Trait { + type Assoc; +} + +impl Trait for T { + type Assoc = T; +} + +fn foo(x: T::Assoc) -> u32 { + x //~ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/param-env-shadowing-false-positive.stderr b/tests/ui/associated-types/param-env-shadowing-false-positive.stderr new file mode 100644 index 000000000000..64d7950f41ef --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-false-positive.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/param-env-shadowing-false-positive.rs:14:5 + | +LL | fn foo(x: T::Assoc) -> u32 { + | --- expected `u32` because of return type +LL | x + | ^ expected `u32`, found associated type + | + = note: expected type `u32` + found associated type `::Assoc` +help: consider constraining the associated type `::Assoc` to `u32` + | +LL | fn foo>(x: T::Assoc) -> u32 { + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/param-env-shadowing-gat.rs b/tests/ui/associated-types/param-env-shadowing-gat.rs new file mode 100644 index 000000000000..9dc91a1a1465 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-gat.rs @@ -0,0 +1,17 @@ +// Regression test for issue #149910. +// This ensures that the diagnostics logic handles Generic Associated Types (GATs) +// correctly without crashing (ICE). + +trait Trait { + type Assoc; +} + +impl Trait for T { + type Assoc = U; +} + +fn foo(x: T::Assoc) -> u32 { + x //~ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/param-env-shadowing-gat.stderr b/tests/ui/associated-types/param-env-shadowing-gat.stderr new file mode 100644 index 000000000000..02c024341724 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-gat.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/param-env-shadowing-gat.rs:14:5 + | +LL | fn foo(x: T::Assoc) -> u32 { + | --- expected `u32` because of return type +LL | x + | ^ expected `u32`, found associated type + | + = note: expected type `u32` + found associated type `::Assoc` +help: consider constraining the associated type `::Assoc` to `u32` + | +LL | fn foo = u32>>(x: T::Assoc) -> u32 { + | ++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.rs b/tests/ui/associated-types/param-env-shadowing-issue-149910.rs new file mode 100644 index 000000000000..368b80e66189 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.rs @@ -0,0 +1,17 @@ +// Regression test for issue #149910. +// We want to tell the user about param_env shadowing here. + +trait Trait { + type Assoc; +} + +impl Trait for T { + type Assoc = T; +} + +fn foo(x: T) -> T::Assoc { + x + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr new file mode 100644 index 000000000000..71ce456bfc1a --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/param-env-shadowing-issue-149910.rs:13:5 + | +LL | fn foo(x: T) -> T::Assoc { + | - -------- expected `::Assoc` because of return type + | | + | found this type parameter +LL | x + | ^ expected associated type, found type parameter `T` + | + = note: expected associated type `::Assoc` + found type parameter `T` + = note: the associated type `::Assoc` is defined as `T` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information +help: consider further restricting this bound + | +LL | fn foo>(x: T) -> T::Assoc { + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/substs-ppaux.normal.stderr b/tests/ui/associated-types/substs-ppaux.normal.stderr index aa2aca7426e1..b1c9ce3f22b6 100644 --- a/tests/ui/associated-types/substs-ppaux.normal.stderr +++ b/tests/ui/associated-types/substs-ppaux.normal.stderr @@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'_, '_, u8>` LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here error: aborting due to 5 previous errors diff --git a/tests/ui/associated-types/substs-ppaux.verbose.stderr b/tests/ui/associated-types/substs-ppaux.verbose.stderr index 23cf222a1d37..46cae5db56fd 100644 --- a/tests/ui/associated-types/substs-ppaux.verbose.stderr +++ b/tests/ui/associated-types/substs-ppaux.verbose.stderr @@ -88,7 +88,7 @@ note: required for `str` to implement `Foo<'?0, '?1, u8>` LL | impl<'a, 'b, T, S> Foo<'a, 'b, S> for T {} | - ^^^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here error: aborting due to 5 previous errors diff --git a/tests/ui/associated-types/suggest-assoc-type-from-bounds.rs b/tests/ui/associated-types/suggest-assoc-type-from-bounds.rs new file mode 100644 index 000000000000..8b349f325cd7 --- /dev/null +++ b/tests/ui/associated-types/suggest-assoc-type-from-bounds.rs @@ -0,0 +1,64 @@ +pub trait Trait { + type Assoc; +} + +fn f + Trait>() { + let _: Assoc = todo!(); //~ ERROR cannot find type `Assoc` in this scope +} + +pub trait Foo<'a> { + type A; +} + +pub mod inner { + pub trait Foo<'a> { + type A; + } +} + +fn g<'a, T: ::Foo<'a> + inner::Foo<'a>>() { + let _: A = todo!(); //~ ERROR cannot find type `A` in this scope +} + +pub trait First { + type Assoc; +} + +pub trait Second { + type Assoc; +} + +fn h + Second>() { + let _: Assoc = todo!(); //~ ERROR cannot find type `Assoc` in this scope +} + +pub trait Gat { + type Assoc<'a>; +} + +fn i() { + let _: Assoc = todo!(); //~ ERROR cannot find type `Assoc` in this scope +} + +fn j() { + struct Local; + impl Local { + fn method() { + let _: Assoc = todo!(); //~ ERROR cannot find type `Assoc` in this scope + } + } + + let _ = std::marker::PhantomData::; +} + +pub struct S; +impl S { + fn method() { + fn inner() { + let _: Assoc = todo!(); //~ ERROR cannot find type `Assoc` in this scope + } + inner(); + } +} + +fn main() {} diff --git a/tests/ui/associated-types/suggest-assoc-type-from-bounds.stderr b/tests/ui/associated-types/suggest-assoc-type-from-bounds.stderr new file mode 100644 index 000000000000..b5ce2d91ca4d --- /dev/null +++ b/tests/ui/associated-types/suggest-assoc-type-from-bounds.stderr @@ -0,0 +1,75 @@ +error[E0425]: cannot find type `Assoc` in this scope + --> $DIR/suggest-assoc-type-from-bounds.rs:6:12 + | +LL | let _: Assoc = todo!(); + | ^^^^^ + | +help: you might have meant to use an associated type of the same name + | +LL | let _: >::Assoc = todo!(); + | +++++++++++++++++++ +LL | let _: >::Assoc = todo!(); + | +++++++++++++++++++ + +error[E0425]: cannot find type `A` in this scope + --> $DIR/suggest-assoc-type-from-bounds.rs:20:12 + | +LL | let _: A = todo!(); + | ^ + | +help: you might have meant to use an associated type of the same name + | +LL | let _: >::A = todo!(); + | ++++++++++++++++++ +LL | let _: >::A = todo!(); + | +++++++++++++++++++++++ +help: you might be missing a type parameter + | +LL | fn g<'a, T: ::Foo<'a> + inner::Foo<'a>, A>() { + | +++ + +error[E0425]: cannot find type `Assoc` in this scope + --> $DIR/suggest-assoc-type-from-bounds.rs:32:12 + | +LL | let _: Assoc = todo!(); + | ^^^^^ + | +help: you might have meant to use an associated type of the same name + | +LL | let _: ::Assoc = todo!(); + | ++++++++++++++ +LL | let _: ::Assoc = todo!(); + | +++++++++++++++ + +error[E0425]: cannot find type `Assoc` in this scope + --> $DIR/suggest-assoc-type-from-bounds.rs:40:12 + | +LL | let _: Assoc = todo!(); + | ^^^^^ + | +help: you might have meant to use an associated type of the same name + | +LL - let _: Assoc = todo!(); +LL + let _: T::Assoc<'_> = todo!(); + | + +error[E0425]: cannot find type `Assoc` in this scope + --> $DIR/suggest-assoc-type-from-bounds.rs:47:20 + | +LL | let _: Assoc = todo!(); + | ^^^^^ + | +help: you might have meant to use an associated type of the same name + | +LL | let _: U::Assoc = todo!(); + | +++ + +error[E0425]: cannot find type `Assoc` in this scope + --> $DIR/suggest-assoc-type-from-bounds.rs:58:20 + | +LL | let _: Assoc = todo!(); + | ^^^^^ not found in this scope + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.rs b/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.rs new file mode 100644 index 000000000000..4a3ccc287f7f --- /dev/null +++ b/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.rs @@ -0,0 +1,18 @@ +//@ compile-flags: -Znext-solver=globally + +// Regression test for https://github.com/rust-lang/rust/issues/152684. + +#![feature(associated_type_defaults)] + +trait Foo { + type Assoc = T; + //~^ ERROR defaults for generic parameters are not allowed here + fn foo() -> Self::Assoc; +} +impl Foo for () { + fn foo() -> Self::Assoc { + [] //~ ERROR mismatched types + } +} + +fn main() {} diff --git a/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.stderr b/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.stderr new file mode 100644 index 000000000000..c40123324248 --- /dev/null +++ b/tests/ui/associated-types/suggest-param-env-shadowing-incompatible-args.stderr @@ -0,0 +1,20 @@ +error: defaults for generic parameters are not allowed here + --> $DIR/suggest-param-env-shadowing-incompatible-args.rs:8:16 + | +LL | type Assoc = T; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/suggest-param-env-shadowing-incompatible-args.rs:14:9 + | +LL | fn foo() -> Self::Assoc { + | ----------- expected `<() as Foo>::Assoc` because of return type +LL | [] + | ^^ expected `u8`, found `[_; 0]` + | + = note: expected type `u8` + found array `[_; 0]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/type-const-inherent-impl-normalize.rs b/tests/ui/associated-types/type-const-inherent-impl-normalize.rs new file mode 100644 index 000000000000..a9c7373b4f44 --- /dev/null +++ b/tests/ui/associated-types/type-const-inherent-impl-normalize.rs @@ -0,0 +1,16 @@ +struct S; +impl S { + type const LEN: usize = 1; + //~^ ERROR: associated `type const` are unstable [E0658] + //~| ERROR: `type const` syntax is experimental [E0658] + fn arr() { + [8; Self::LEN] + //~^ WARN: cannot use constants which depend on generic parameters in types + //~| WARN: this was previously accepted by the compiler but is being phased out + //~| WARN: cannot use constants which depend on generic parameters in types + //~| WARN: this was previously accepted by the compiler but is being phased out + //~| ERROR: mismatched types + } +} + +pub fn main() {} diff --git a/tests/ui/associated-types/type-const-inherent-impl-normalize.stderr b/tests/ui/associated-types/type-const-inherent-impl-normalize.stderr new file mode 100644 index 000000000000..b86859f4a993 --- /dev/null +++ b/tests/ui/associated-types/type-const-inherent-impl-normalize.stderr @@ -0,0 +1,52 @@ +error[E0658]: `type const` syntax is experimental + --> $DIR/type-const-inherent-impl-normalize.rs:3:5 + | +LL | type const LEN: usize = 1; + | ^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated `type const` are unstable + --> $DIR/type-const-inherent-impl-normalize.rs:3:5 + | +LL | type const LEN: usize = 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +warning: cannot use constants which depend on generic parameters in types + --> $DIR/type-const-inherent-impl-normalize.rs:7:13 + | +LL | [8; Self::LEN] + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #76200 + = note: `#[warn(const_evaluatable_unchecked)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: cannot use constants which depend on generic parameters in types + --> $DIR/type-const-inherent-impl-normalize.rs:7:13 + | +LL | [8; Self::LEN] + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #76200 + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0308]: mismatched types + --> $DIR/type-const-inherent-impl-normalize.rs:7:9 + | +LL | fn arr() { + | - help: try adding a return type: `-> [i32; 1]` +LL | [8; Self::LEN] + | ^^^^^^^^^^^^^^ expected `()`, found `[{integer}; 1]` + +error: aborting due to 3 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0308, E0658. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/async-await-let-else.stderr b/tests/ui/async-await/async-await-let-else.stderr index 5883f34f87de..b5b56d3242f4 100644 --- a/tests/ui/async-await/async-await-let-else.stderr +++ b/tests/ui/async-await/async-await-let-else.stderr @@ -22,7 +22,7 @@ error[E0277]: `Rc<()>` cannot be sent between threads safely --> $DIR/async-await-let-else.rs:47:13 | LL | async fn foo2(x: Option) { - | ------------------------------ within this `impl Future` + | - within this `impl Future` ... LL | is_send(foo2(Some(true))); | ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely diff --git a/tests/ui/async-await/async-closures/def-path.stderr b/tests/ui/async-await/async-closures/def-path.stderr index a507fa697604..e140e9b94b30 100644 --- a/tests/ui/async-await/async-closures/def-path.stderr +++ b/tests/ui/async-await/async-closures/def-path.stderr @@ -5,11 +5,11 @@ LL | let x = async || {}; | -- the expected `async` closure body LL | LL | let () = x(); - | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}` + | ^^ --- this expression has type `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=std::future::ResumeTy yield_ty=() return_ty=()}` | | | expected `async` closure body, found `()` | - = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=ResumeTy yield_ty=() return_ty=()}` + = note: expected `async` closure body `{static main::{closure#0}::{closure#0} upvar_tys=?14t resume_ty=std::future::ResumeTy yield_ty=() return_ty=()}` found unit type `()` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-closures/move-from-async-fn-bound.rs b/tests/ui/async-await/async-closures/move-from-async-fn-bound.rs new file mode 100644 index 000000000000..fbd8aac2515b --- /dev/null +++ b/tests/ui/async-await/async-closures/move-from-async-fn-bound.rs @@ -0,0 +1,13 @@ +//@ edition:2021 +// Test that a by-ref `AsyncFn` closure gets an error when it tries to +// consume a value, with a helpful diagnostic pointing to the bound. + +fn call(_: F) where F: AsyncFn() {} + +fn main() { + let y = vec![format!("World")]; + call(async || { + //~^ ERROR cannot move out of `y`, a captured variable in an `AsyncFn` closure + y.into_iter(); + }); +} diff --git a/tests/ui/async-await/async-closures/move-from-async-fn-bound.stderr b/tests/ui/async-await/async-closures/move-from-async-fn-bound.stderr new file mode 100644 index 000000000000..1a881db2a37d --- /dev/null +++ b/tests/ui/async-await/async-closures/move-from-async-fn-bound.stderr @@ -0,0 +1,30 @@ +error[E0507]: cannot move out of `y`, a captured variable in an `AsyncFn` closure + --> $DIR/move-from-async-fn-bound.rs:9:10 + | +LL | let y = vec![format!("World")]; + | - captured outer variable +LL | call(async || { + | ^^^^^^^^ + | | + | captured by this `AsyncFn` closure + | `y` is moved here +LL | +LL | y.into_iter(); + | - + | | + | variable moved due to use in coroutine + | move occurs because `y` has type `Vec`, which does not implement the `Copy` trait + | +help: `AsyncFn` and `AsyncFnMut` closures require captured values to be able to be consumed multiple times, but `AsyncFnOnce` closures may consume them only once + --> $DIR/move-from-async-fn-bound.rs:5:27 + | +LL | fn call(_: F) where F: AsyncFn() {} + | ^^^^^^^^^ +help: consider cloning the value if the performance cost is acceptable + | +LL | y.clone().into_iter(); + | ++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.fixed b/tests/ui/async-await/async-fn/dyn-in-return-type.fixed new file mode 100644 index 000000000000..6a717f628460 --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.fixed @@ -0,0 +1,30 @@ +//@ edition:2024 +//@ run-rustfix + +async fn f() -> Box { +//~^ ERROR return type cannot be a trait object without pointer indirection +//~| HELP consider returning an `impl Trait` instead of a `dyn Trait` +//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") +} +trait T { + async fn f(&self) -> Box { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } +} +impl T for () { + async fn f(&self) -> Box { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } +} + +fn main() { + let _ = f(); + let _ = ().f(); +} diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.rs b/tests/ui/async-await/async-fn/dyn-in-return-type.rs new file mode 100644 index 000000000000..47d5e371f55f --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.rs @@ -0,0 +1,30 @@ +//@ edition:2024 +//@ run-rustfix + +async fn f() -> dyn core::fmt::Debug { +//~^ ERROR return type cannot be a trait object without pointer indirection +//~| HELP consider returning an `impl Trait` instead of a `dyn Trait` +//~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") +} +trait T { + async fn f(&self) -> dyn core::fmt::Debug { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } +} +impl T for () { + async fn f(&self) -> dyn core::fmt::Debug { + //~^ ERROR return type cannot be a trait object without pointer indirection + //~| HELP consider returning an `impl Trait` instead of a `dyn Trait` + //~| HELP alternatively, box the return type, and wrap all of the returned values in `Box::new` + Box::new("") + } +} + +fn main() { + let _ = f(); + let _ = ().f(); +} diff --git a/tests/ui/async-await/async-fn/dyn-in-return-type.stderr b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr new file mode 100644 index 000000000000..0d8a92d33cf9 --- /dev/null +++ b/tests/ui/async-await/async-fn/dyn-in-return-type.stderr @@ -0,0 +1,51 @@ +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:4:17 + | +LL | async fn f() -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL - async fn f() -> dyn core::fmt::Debug { +LL + async fn f() -> impl core::fmt::Debug { + | +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | async fn f() -> Box { + | ++++ + + +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:11:26 + | +LL | async fn f(&self) -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL - async fn f(&self) -> dyn core::fmt::Debug { +LL + async fn f(&self) -> impl core::fmt::Debug { + | +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | async fn f(&self) -> Box { + | ++++ + + +error[E0746]: return type cannot be a trait object without pointer indirection + --> $DIR/dyn-in-return-type.rs:19:26 + | +LL | async fn f(&self) -> dyn core::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +help: consider returning an `impl Trait` instead of a `dyn Trait` + | +LL - async fn f(&self) -> dyn core::fmt::Debug { +LL + async fn f(&self) -> impl core::fmt::Debug { + | +help: alternatively, box the return type, and wrap all of the returned values in `Box::new` + | +LL | async fn f(&self) -> Box { + | ++++ + + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0746`. diff --git a/tests/ui/async-await/async-fn/dyn-pos.stderr b/tests/ui/async-await/async-fn/dyn-pos.stderr index 7d5b37bdbe73..efd3357ca679 100644 --- a/tests/ui/async-await/async-fn/dyn-pos.stderr +++ b/tests/ui/async-await/async-fn/dyn-pos.stderr @@ -8,7 +8,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit --> $SRC_DIR/core/src/ops/async_function.rs:LL:COL | - = note: the trait is not dyn compatible because it contains the generic associated type `CallRefFuture` + = note: the trait is not dyn compatible because it contains generic associated type `CallRefFuture` error: aborting due to 1 previous error diff --git a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr index 98c7be2a5a3f..232246590cf1 100644 --- a/tests/ui/async-await/async-fn/recurse-ice-129215.stderr +++ b/tests/ui/async-await/async-fn/recurse-ice-129215.stderr @@ -7,10 +7,10 @@ LL | a() = help: the trait `Future` is not implemented for `()` error[E0277]: `()` is not a future - --> $DIR/recurse-ice-129215.rs:3:1 + --> $DIR/recurse-ice-129215.rs:3:13 | LL | async fn a() { - | ^^^^^^^^^^^^ `()` is not a future + | ^ `()` is not a future | = help: the trait `Future` is not implemented for `()` diff --git a/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index 70900e612f48..a2be23099415 100644 --- a/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr +++ b/tests/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -5,7 +5,7 @@ LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/2015-edition-error-various-positions.rs:3:9 | @@ -20,7 +20,7 @@ LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:12:16 @@ -29,7 +29,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:12:23 @@ -38,7 +38,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:17:14 @@ -47,7 +47,7 @@ LL | struct Foo { await: () } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:21:15 @@ -56,7 +56,7 @@ LL | impl Foo { fn await() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:25:14 @@ -65,7 +65,7 @@ LL | macro_rules! await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:32:5 @@ -74,7 +74,7 @@ LL | await!(); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:35:11 @@ -83,7 +83,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:35:19 @@ -92,7 +92,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 10 previous errors diff --git a/tests/ui/async-await/await-keyword/2015-edition-warning.stderr b/tests/ui/async-await/await-keyword/2015-edition-warning.stderr index 9d19a09092b9..97c69f2e7288 100644 --- a/tests/ui/async-await/await-keyword/2015-edition-warning.stderr +++ b/tests/ui/async-await/await-keyword/2015-edition-warning.stderr @@ -5,7 +5,7 @@ LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/2015-edition-warning.rs:5:9 | @@ -20,7 +20,7 @@ LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:16:16 @@ -29,7 +29,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:16:23 @@ -38,7 +38,7 @@ LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:23:11 @@ -47,7 +47,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:23:19 @@ -56,7 +56,7 @@ LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 6 previous errors diff --git a/tests/ui/async-await/coroutine-not-future.stderr b/tests/ui/async-await/coroutine-not-future.stderr index b0f371f6706d..b55faf39ce69 100644 --- a/tests/ui/async-await/coroutine-not-future.stderr +++ b/tests/ui/async-await/coroutine-not-future.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `impl Future: Coroutine<_>` is not sa --> $DIR/coroutine-not-future.rs:36:21 | LL | takes_coroutine(async_fn()); - | --------------- ^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future` + | --------------- ^^^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `impl Future` | | | required by a bound introduced by this call | @@ -16,7 +16,7 @@ error[E0277]: the trait bound `impl Future: Coroutine<_>` is not sa --> $DIR/coroutine-not-future.rs:38:21 | LL | takes_coroutine(returns_async_block()); - | --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future` + | --------------- ^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `impl Future` | | | required by a bound introduced by this call | @@ -30,7 +30,7 @@ error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:40:21: --> $DIR/coroutine-not-future.rs:40:21 | LL | takes_coroutine(async {}); - | --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}` + | --------------- ^^^^^^^^ the nightly-only, unstable trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}` | | | required by a bound introduced by this call | diff --git a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr index ce023397db90..928e1fcaa578 100644 --- a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr +++ b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr @@ -6,7 +6,7 @@ LL | | false | | ^^^^^ expected `()`, found `bool` LL | | LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` error[E0308]: mismatched types --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:12:9 diff --git a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout index b30c15bcbe6e..13f03ffa65b5 100644 --- a/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout +++ b/tests/ui/async-await/future-sizes/async-awaiting-fut.stdout @@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size field `.value`: 3077 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes +print-type-size field `.0`: 3077 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of calls_fut<{async fn body of big_fut()}>()}>`: 3077 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3077 bytes print-type-size field `.uninit`: 0 bytes @@ -36,6 +38,8 @@ print-type-size variant `Panicked`: 1025 bytes print-type-size upvar `.fut`: 1025 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes +print-type-size field `.0`: 1025 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of big_fut()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes @@ -85,6 +89,10 @@ print-type-size type: `std::mem::ManuallyDrop`: 1 bytes, alignment: 1 byte print-type-size field `.value`: 1 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeDangling`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes print-type-size type: `std::mem::MaybeUninit`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/async-await/future-sizes/large-arg.stdout b/tests/ui/async-await/future-sizes/large-arg.stdout index e00420d1493f..d51afa33595c 100644 --- a/tests/ui/async-await/future-sizes/large-arg.stdout +++ b/tests/ui/async-await/future-sizes/large-arg.stdout @@ -7,6 +7,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size field `.value`: 3075 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes +print-type-size field `.0`: 3075 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of a<[u8; 1024]>()}>`: 3075 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 3075 bytes print-type-size field `.uninit`: 0 bytes @@ -24,6 +26,8 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size field `.value`: 2050 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes +print-type-size field `.0`: 2050 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of b<[u8; 1024]>()}>`: 2050 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 2050 bytes print-type-size field `.uninit`: 0 bytes @@ -41,6 +45,8 @@ print-type-size variant `Panicked`: 1024 bytes print-type-size upvar `.t`: 1024 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size field `.value`: 1025 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes +print-type-size field `.0`: 1025 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of c<[u8; 1024]>()}>`: 1025 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1025 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr index 54df0edf5a8e..c98df134072e 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed-in-trait.stderr @@ -1,8 +1,8 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/async-example-desugared-boxed-in-trait.rs:11:5 + --> $DIR/async-example-desugared-boxed-in-trait.rs:11:28 | LL | async fn foo(&self) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin>>`, found future + | ^^^ expected `Pin>>`, found future | note: type in trait --> $DIR/async-example-desugared-boxed-in-trait.rs:7:22 diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr index b7f2879727f2..d3765a7e6e6f 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr @@ -2,7 +2,7 @@ warning: impl trait in impl method signature does not match trait method signatu --> $DIR/async-example-desugared-boxed.rs:14:22 | LL | async fn foo(&self) -> i32; - | --------------------------- return type from trait method defined here + | --- return type from trait method defined here ... LL | fn foo(&self) -> Pin + '_>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr index 86546df88c17..3328dea37fe4 100644 --- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr +++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr @@ -2,7 +2,7 @@ warning: impl trait in impl method signature does not match trait method signatu --> $DIR/async-example-desugared-manual.rs:22:22 | LL | async fn foo(&self) -> i32; - | --------------------------- return type from trait method defined here + | --- return type from trait method defined here ... LL | fn foo(&self) -> MyFuture { | ^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr index 183b0fa152aa..52fd887b296f 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr @@ -1,11 +1,10 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics-and-bounds.rs:8:5 + --> $DIR/async-generics-and-bounds.rs:8:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `T` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `T` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | @@ -13,13 +12,12 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Has | ++++ ++ ++ +++++++ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics-and-bounds.rs:8:5 + --> $DIR/async-generics-and-bounds.rs:8:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `U` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `U` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.stderr index 8916ef5ab683..3f44e4cdb677 100644 --- a/tests/ui/async-await/in-trait/async-generics.stderr +++ b/tests/ui/async-await/in-trait/async-generics.stderr @@ -1,11 +1,10 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics.rs:5:5 + --> $DIR/async-generics.rs:5:28 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `T` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `T` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | @@ -13,13 +12,12 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a; | ++++ ++ ++ +++++++++++ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics.rs:5:5 + --> $DIR/async-generics.rs:5:28 | LL | async fn foo(&self) -> &(T, U); - | ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^ - | | | - | | the parameter type `U` must be valid for the anonymous lifetime as defined here... - | ...so that the reference type `&(T, U)` does not outlive the data it points at + | - ^^^^^^^ ...so that the reference type `&(T, U)` does not outlive the data it points at + | | + | the parameter type `U` must be valid for the anonymous lifetime as defined here... | help: consider adding an explicit lifetime bound | diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr index 823d8d5b92fc..d0c11565f4e9 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr @@ -1,14 +1,14 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/dont-project-to-specializable-projection.rs:14:5 + --> $DIR/dont-project-to-specializable-projection.rs:14:35 | LL | default async fn foo(_: T) -> &'static str { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found future + | ^^^^^^^^^^^^ expected associated type, found future | note: type in trait - --> $DIR/dont-project-to-specializable-projection.rs:10:5 + --> $DIR/dont-project-to-specializable-projection.rs:10:27 | LL | async fn foo(_: T) -> &'static str; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ = note: expected signature `fn(_) -> impl Future` found signature `fn(_) -> impl Future` diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index 1fccc32470ff..c4240a095e68 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -8,10 +8,10 @@ LL | async fn foo(self: &dyn Foo) { = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

{ impl

Trait

for () { const A: () = (); - //~^ ERROR const `A` has 1 type parameter but its trait declaration has 0 type parameters + //~^ ERROR constant `A` has 1 type parameter but its trait declaration has 0 type parameters const B: u64 = 0; - //~^ ERROR const `B` has 1 const parameter but its trait declaration has 2 const parameters + //~^ ERROR constant `B` has 1 const parameter but its trait declaration has 2 const parameters const C<'a>: &'a str = ""; - //~^ ERROR const `C` has 0 type parameters but its trait declaration has 1 type parameter + //~^ ERROR constant `C` has 0 type parameters but its trait declaration has 1 type parameter const D: u16 = N; - //~^ ERROR const `D` has an incompatible generic parameter for trait `Trait` + //~^ ERROR constant `D` has an incompatible generic parameter for trait `Trait` const E: &'static () = &(); - //~^ ERROR lifetime parameters or bounds on associated const `E` do not match the trait declaration + //~^ ERROR lifetime parameters or bounds on associated constant `E` do not match the trait declaration const F: usize = 1024 where diff --git a/tests/ui/generic-const-items/compare-impl-item.stderr b/tests/ui/generic-const-items/compare-impl-item.stderr index f7e3ff6501b1..ffe65f9fc088 100644 --- a/tests/ui/generic-const-items/compare-impl-item.stderr +++ b/tests/ui/generic-const-items/compare-impl-item.stderr @@ -1,4 +1,4 @@ -error[E0049]: associated const `A` has 1 type parameter but its trait declaration has 0 type parameters +error[E0049]: associated constant `A` has 1 type parameter but its trait declaration has 0 type parameters --> $DIR/compare-impl-item.rs:16:13 | LL | const A: (); @@ -7,7 +7,7 @@ LL | const A: (); LL | const A: () = (); | ^ found 1 type parameter -error[E0049]: associated const `B` has 1 const parameter but its trait declaration has 2 const parameters +error[E0049]: associated constant `B` has 1 const parameter but its trait declaration has 2 const parameters --> $DIR/compare-impl-item.rs:18:13 | LL | const B: u64; @@ -18,7 +18,7 @@ LL | const B: u64; LL | const B: u64 = 0; | ^^^^^^^^^^^^ found 1 const parameter -error[E0049]: associated const `C` has 0 type parameters but its trait declaration has 1 type parameter +error[E0049]: associated constant `C` has 0 type parameters but its trait declaration has 1 type parameter --> $DIR/compare-impl-item.rs:20:13 | LL | const C: T; @@ -27,7 +27,7 @@ LL | const C: T; LL | const C<'a>: &'a str = ""; | ^^ found 0 type parameters -error[E0053]: associated const `D` has an incompatible generic parameter for trait `Trait` +error[E0053]: associated constant `D` has an incompatible generic parameter for trait `Trait` --> $DIR/compare-impl-item.rs:22:13 | LL | trait Trait

{ @@ -42,14 +42,14 @@ LL | impl

Trait

for () { LL | const D: u16 = N; | ^^^^^^^^^^^^ found const parameter of type `u16` -error[E0195]: lifetime parameters or bounds on associated const `E` do not match the trait declaration +error[E0195]: lifetime parameters or bounds on associated constant `E` do not match the trait declaration --> $DIR/compare-impl-item.rs:24:12 | LL | const E<'a>: &'a (); - | ---- lifetimes in impl do not match this associated const in trait + | ---- lifetimes in impl do not match this associated constant in trait ... LL | const E: &'static () = &(); - | ^ lifetimes do not match associated const in trait + | ^ lifetimes do not match associated constant in trait error[E0276]: impl has stricter requirements than trait --> $DIR/compare-impl-item.rs:29:12 diff --git a/tests/ui/generic-const-items/type-const-nested-assoc-const.rs b/tests/ui/generic-const-items/type-const-nested-assoc-const.rs new file mode 100644 index 000000000000..72a3098b76cf --- /dev/null +++ b/tests/ui/generic-const-items/type-const-nested-assoc-const.rs @@ -0,0 +1,18 @@ +//@ check-pass + +#![feature(generic_const_items, min_generic_const_args)] +#![allow(incomplete_features)] + +type const CT: usize = { ::N }; + +trait Trait { + type const N: usize; +} + +impl Trait for T { + type const N:usize = 0; +} + +fn f(_x: [(); CT::<()>]) {} + +fn main() {} diff --git a/tests/ui/generics/generic-impl-method-params-2311.rs b/tests/ui/generics/generic-impl-method-params-2311.rs new file mode 100644 index 000000000000..cd9f488daed0 --- /dev/null +++ b/tests/ui/generics/generic-impl-method-params-2311.rs @@ -0,0 +1,23 @@ +//@ check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +trait clam { + fn get(self) -> A; +} + +struct foo { + x: A, +} + +impl foo { + pub fn bar>(&self, _c: C) -> B { + panic!(); + } +} + +fn foo(b: A) -> foo { + foo { x: b } +} + +pub fn main() {} diff --git a/tests/ui/generics/generic-trait-method-params-2311.rs b/tests/ui/generics/generic-trait-method-params-2311.rs new file mode 100644 index 000000000000..f63036e47f6f --- /dev/null +++ b/tests/ui/generics/generic-trait-method-params-2311.rs @@ -0,0 +1,13 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2311 + +//@ check-pass +#![allow(non_camel_case_types)] + +trait clam { + fn get(self) -> A; +} +trait foo { + fn bar>(&self, c: C) -> B; +} + +pub fn main() {} diff --git a/tests/ui/generics/resolve-generic-method-param-2312.rs b/tests/ui/generics/resolve-generic-method-param-2312.rs new file mode 100644 index 000000000000..7473b73f5bfa --- /dev/null +++ b/tests/ui/generics/resolve-generic-method-param-2312.rs @@ -0,0 +1,21 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2312 + +//@ check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +// Testing that the B's are resolved + +trait clam { + fn get(self) -> A; +} + +struct foo(isize); + +impl foo { + pub fn bar>(&self, _c: C) -> B { + panic!(); + } +} + +pub fn main() {} diff --git a/tests/ui/generics/type-args-on-module-in-bound.rs b/tests/ui/generics/type-args-on-module-in-bound.rs new file mode 100644 index 000000000000..96ca37407cfc --- /dev/null +++ b/tests/ui/generics/type-args-on-module-in-bound.rs @@ -0,0 +1,4 @@ +//! regression test for +fn is_copy::Copy>() {} +//~^ ERROR type arguments are not allowed on module `marker` [E0109] +fn main() {} diff --git a/tests/ui/generics/type-args-on-module-in-bound.stderr b/tests/ui/generics/type-args-on-module-in-bound.stderr new file mode 100644 index 000000000000..ac70ae63e90b --- /dev/null +++ b/tests/ui/generics/type-args-on-module-in-bound.stderr @@ -0,0 +1,11 @@ +error[E0109]: type arguments are not allowed on module `marker` + --> $DIR/type-args-on-module-in-bound.rs:2:29 + | +LL | fn is_copy::Copy>() {} + | ------ ^^^ type argument not allowed + | | + | not allowed on module `marker` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/generics/wrong-number-of-args-in-macro.rs b/tests/ui/generics/wrong-number-of-args-in-macro.rs new file mode 100644 index 000000000000..953e05434d25 --- /dev/null +++ b/tests/ui/generics/wrong-number-of-args-in-macro.rs @@ -0,0 +1,15 @@ +// Regression test for #149559 + +struct Foo; //~ ERROR type parameter `T` is never used + +macro_rules! foo_ty { + ($a:ty, $b:ty) => { + Foo + //~^ ERROR cannot find type `a` in this scope + //~| ERROR struct takes 1 generic argument but 2 generic arguments were supplied + }; +} + +fn foo<'a, 'b>() -> foo_ty!(&'b (), &'b ()) {} + +fn main() {} diff --git a/tests/ui/generics/wrong-number-of-args-in-macro.stderr b/tests/ui/generics/wrong-number-of-args-in-macro.stderr new file mode 100644 index 000000000000..62a5eb9414ed --- /dev/null +++ b/tests/ui/generics/wrong-number-of-args-in-macro.stderr @@ -0,0 +1,44 @@ +error[E0425]: cannot find type `a` in this scope + --> $DIR/wrong-number-of-args-in-macro.rs:7:13 + | +LL | Foo + | ^ not found in this scope +... +LL | fn foo<'a, 'b>() -> foo_ty!(&'b (), &'b ()) {} + | ----------------------- in this macro invocation + | + = note: this error originates in the macro `foo_ty` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might be missing a type parameter + | +LL | fn foo<'a, 'b, a>() -> foo_ty!(&'b (), &'b ()) {} + | +++ + +error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied + --> $DIR/wrong-number-of-args-in-macro.rs:7:9 + | +LL | Foo + | ^^^ expected 1 generic argument +... +LL | fn foo<'a, 'b>() -> foo_ty!(&'b (), &'b ()) {} + | ----------------------- in this macro invocation + | +note: struct defined here, with 1 generic parameter: `T` + --> $DIR/wrong-number-of-args-in-macro.rs:3:8 + | +LL | struct Foo; + | ^^^ - + = note: this error originates in the macro `foo_ty` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0392]: type parameter `T` is never used + --> $DIR/wrong-number-of-args-in-macro.rs:3:12 + | +LL | struct Foo; + | ^ unused type parameter + | + = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0392, E0425. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/generics/wrong-number-of-args.rs b/tests/ui/generics/wrong-number-of-args.rs index 6524bd538b6b..9af16567cd75 100644 --- a/tests/ui/generics/wrong-number-of-args.rs +++ b/tests/ui/generics/wrong-number-of-args.rs @@ -127,7 +127,7 @@ mod r#trait { //~| HELP remove type D = Box; - //~^ ERROR missing generics for trait `GenericType` + //~^ ERROR missing generics for trait `r#trait::GenericType` //~| HELP add missing type E = Box>; @@ -321,10 +321,6 @@ mod stdlib { //~| ERROR struct takes at least 2 //~| HELP add missing - type D = HashMap; - //~^ ERROR struct takes at most 3 - //~| HELP remove the - type E = HashMap<>; //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments //~| HELP add missing diff --git a/tests/ui/generics/wrong-number-of-args.stderr b/tests/ui/generics/wrong-number-of-args.stderr index bac0d26b622d..554d017d67e3 100644 --- a/tests/ui/generics/wrong-number-of-args.stderr +++ b/tests/ui/generics/wrong-number-of-args.stderr @@ -469,7 +469,7 @@ note: trait defined here, with 1 lifetime parameter: `'a` LL | trait GenericLifetime<'a> { | ^^^^^^^^^^^^^^^ -- -error[E0107]: missing generics for trait `GenericType` +error[E0107]: missing generics for trait `r#trait::GenericType` --> $DIR/wrong-number-of-args.rs:129:22 | LL | type D = Box; @@ -926,16 +926,8 @@ help: add missing generic arguments LL | type C = HashMap<'static, K, V>; | ++++++ -error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:324:18 - | -LL | type D = HashMap; - | ^^^^^^^ ----- help: remove the unnecessary generic argument - | | - | expected at most 3 generic arguments - error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:328:18 + --> $DIR/wrong-number-of-args.rs:324:18 | LL | type E = HashMap<>; | ^^^^^^^ expected at least 2 generic arguments @@ -946,7 +938,7 @@ LL | type E = HashMap; | ++++ error[E0107]: missing generics for enum `Result` - --> $DIR/wrong-number-of-args.rs:334:18 + --> $DIR/wrong-number-of-args.rs:330:18 | LL | type A = Result; | ^^^^^^ expected 2 generic arguments @@ -957,7 +949,7 @@ LL | type A = Result; | ++++++ error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied - --> $DIR/wrong-number-of-args.rs:338:18 + --> $DIR/wrong-number-of-args.rs:334:18 | LL | type B = Result; | ^^^^^^ ------ supplied 1 generic argument @@ -970,7 +962,7 @@ LL | type B = Result; | +++ error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/wrong-number-of-args.rs:342:18 + --> $DIR/wrong-number-of-args.rs:338:18 | LL | type C = Result<'static>; | ^^^^^^--------- help: remove the unnecessary generics @@ -978,7 +970,7 @@ LL | type C = Result<'static>; | expected 0 lifetime arguments error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:342:18 + --> $DIR/wrong-number-of-args.rs:338:18 | LL | type C = Result<'static>; | ^^^^^^ expected 2 generic arguments @@ -989,7 +981,7 @@ LL | type C = Result<'static, T, E>; | ++++++ error[E0107]: enum takes 2 generic arguments but 3 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:348:18 + --> $DIR/wrong-number-of-args.rs:344:18 | LL | type D = Result; | ^^^^^^ ------ help: remove the unnecessary generic argument @@ -997,7 +989,7 @@ LL | type D = Result; | expected 2 generic arguments error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied - --> $DIR/wrong-number-of-args.rs:352:18 + --> $DIR/wrong-number-of-args.rs:348:18 | LL | type E = Result<>; | ^^^^^^ expected 2 generic arguments @@ -1007,7 +999,7 @@ help: add missing generic arguments LL | type E = Result; | ++++ -error: aborting due to 71 previous errors +error: aborting due to 70 previous errors Some errors have detailed explanations: E0106, E0107. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs index a89b22925128..df1b9e164c76 100644 --- a/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs +++ b/tests/ui/half-open-range-patterns/half-open-range-pats-semantics.rs @@ -1,9 +1,11 @@ //@ run-pass +//@ compile-flags: --check-cfg=cfg(target_has_reliable_f16,target_has_reliable_f128) // Test half-open range patterns against their expression equivalents // via `.contains(...)` and make sure the dynamic semantics match. #![allow(unreachable_patterns)] +#![feature(cfg_target_has_reliable_f16_f128)] #![feature(f128)] #![feature(f16)] @@ -42,8 +44,7 @@ fn range_to_inclusive() { assert!(!yes!('b', ..='a')); // f16; `..=X` - // FIXME(f16_f128): remove gate when ABI issues are resolved - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f16)] { assert!(yes!(f16::NEG_INFINITY, ..=f16::NEG_INFINITY)); assert!(yes!(f16::NEG_INFINITY, ..=1.0f16)); @@ -64,8 +65,7 @@ fn range_to_inclusive() { assert!(!yes!(1.6f64, ..=-1.5f64)); // f128; `..=X` - // FIXME(f16_f128): remove gate when ABI issues are resolved - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f128)] { assert!(yes!(f128::NEG_INFINITY, ..=f128::NEG_INFINITY)); assert!(yes!(f128::NEG_INFINITY, ..=1.0f128)); @@ -106,8 +106,7 @@ fn range_to() { assert!(!yes!('b', ..'a')); // f16; `..X` - // FIXME(f16_f128): remove gate when ABI issues are resolved - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f16)] { assert!(yes!(f16::NEG_INFINITY, ..1.0f16)); assert!(!yes!(1.5f16, ..1.5f16)); @@ -131,8 +130,7 @@ fn range_to() { assert!(!yes!(1.6f64, ..1.5f64)); // f128; `..X` - // FIXME(f16_f128): remove gate when ABI issues are resolved - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f128)] { assert!(yes!(f128::NEG_INFINITY, ..1.0f128)); assert!(!yes!(1.5f128, ..1.5f128)); @@ -174,8 +172,7 @@ fn range_from() { assert!(yes!(core::char::MAX, core::char::MAX..)); // f16; `X..` - // FIXME(f16_f128): remove gate when ABI issues are resolved - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f16)] { assert!(yes!(f16::NEG_INFINITY, f16::NEG_INFINITY..)); assert!(yes!(f16::INFINITY, f16::NEG_INFINITY..)); @@ -208,8 +205,7 @@ fn range_from() { assert!(yes!(f64::INFINITY, f64::INFINITY..)); // f128; `X..` - // FIXME(f16_f128): remove gate when ABI issues are resolved - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f128)] { assert!(yes!(f128::NEG_INFINITY, f128::NEG_INFINITY..)); assert!(yes!(f128::INFINITY, f128::NEG_INFINITY..)); diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr index 395dd068e237..90d9eb3922e0 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr @@ -2,15 +2,10 @@ error[E0308]: mismatched types --> $DIR/candidate-from-env-universe-err-project.rs:38:5 | LL | projection_bound::(); - | ^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | ^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | = note: expected associated type `>::Assoc` found associated type `>::Assoc` -note: the lifetime requirement is introduced here - --> $DIR/candidate-from-env-universe-err-project.rs:19:42 - | -LL | fn projection_bound Trait<'a, Assoc = usize>>() {} - | ^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/candidate-from-env-universe-err-project.rs:52:30 diff --git a/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.rs b/tests/ui/higher-ranked/trait-bounds/higher-trait-bounds-ice-60218.rs similarity index 81% rename from tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.rs rename to tests/ui/higher-ranked/trait-bounds/higher-trait-bounds-ice-60218.rs index d1a4e09243ec..d0d09f11a574 100644 --- a/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.rs +++ b/tests/ui/higher-ranked/trait-bounds/higher-trait-bounds-ice-60218.rs @@ -1,6 +1,4 @@ -// https://github.com/rust-lang/rust/issues/60218 -// Regression test for #60218 -// +// Regression test for https://github.com/rust-lang/rust/issues/60218 // This was reported to cause ICEs. use std::iter::Map; diff --git a/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.stderr b/tests/ui/higher-ranked/trait-bounds/higher-trait-bounds-ice-60218.stderr similarity index 85% rename from tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.stderr rename to tests/ui/higher-ranked/trait-bounds/higher-trait-bounds-ice-60218.stderr index 4c403bcbd601..b02179f14125 100644 --- a/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.stderr +++ b/tests/ui/higher-ranked/trait-bounds/higher-trait-bounds-ice-60218.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&u32: Foo` is not satisfied - --> $DIR/higher-trait-bounds-ice-60218.rs:19:19 + --> $DIR/higher-trait-bounds-ice-60218.rs:17:19 | LL | trigger_error(vec![], |x: &u32| x) | ------------- ^^^^^^ the trait `Foo` is not implemented for `&u32` @@ -7,12 +7,12 @@ LL | trigger_error(vec![], |x: &u32| x) | required by a bound introduced by this call | help: this trait has no implementations, consider adding one - --> $DIR/higher-trait-bounds-ice-60218.rs:8:1 + --> $DIR/higher-trait-bounds-ice-60218.rs:6:1 | LL | pub trait Foo {} | ^^^^^^^^^^^^^ note: required by a bound in `trigger_error` - --> $DIR/higher-trait-bounds-ice-60218.rs:14:72 + --> $DIR/higher-trait-bounds-ice-60218.rs:12:72 | LL | pub fn trigger_error(iterable: I, functor: F) | ------------- required by a bound in this function diff --git a/tests/ui/higher-ranked/trait-bounds/issue-88446.rs b/tests/ui/higher-ranked/trait-bounds/issue-88446.rs index 0ca8387776a4..8e42465b929a 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-88446.rs +++ b/tests/ui/higher-ranked/trait-bounds/issue-88446.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver trait Yokeable<'a> { type Output: 'a; diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs index d85c6999e26f..226bd48f0e4e 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-89436.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![allow(unused)] diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs index b3feda4a531f..0dcef54ed69c 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90638.rs @@ -1,4 +1,7 @@ //@check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver trait Yokeable<'a>: 'static { type Output: 'a; diff --git a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr index fe3a12e93a7e..90dd40534ed1 100644 --- a/tests/ui/hygiene/cross-crate-name-hiding-2.stderr +++ b/tests/ui/hygiene/cross-crate-name-hiding-2.stderr @@ -1,13 +1,11 @@ error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope --> $DIR/cross-crate-name-hiding-2.rs:13:13 | +LL | my_struct!(define); + | ------------------ you might have meant to refer to this struct +... LL | let x = MyStruct {}; | ^^^^^^^^ not found in this scope - | - ::: $DIR/auxiliary/use_by_macro.rs:15:1 - | -LL | x!(my_struct); - | ------------- you might have meant to refer to this struct error: aborting due to 1 previous error diff --git a/tests/ui/hygiene/cross-crate-redefine.rs b/tests/ui/hygiene/cross-crate-redefine.rs index e42c5e3de064..a87c933391d4 100644 --- a/tests/ui/hygiene/cross-crate-redefine.rs +++ b/tests/ui/hygiene/cross-crate-redefine.rs @@ -8,7 +8,7 @@ extern crate use_by_macro; use use_by_macro::*; my_struct!(define); -//~^ ERROR the name `MyStruct` is defined multiple times my_struct!(define); +//~^ ERROR the name `MyStruct` is defined multiple times fn main() {} diff --git a/tests/ui/hygiene/cross-crate-redefine.stderr b/tests/ui/hygiene/cross-crate-redefine.stderr index c0fd3f4b7ebf..8ad7d6d7b089 100644 --- a/tests/ui/hygiene/cross-crate-redefine.stderr +++ b/tests/ui/hygiene/cross-crate-redefine.stderr @@ -1,11 +1,10 @@ error[E0428]: the name `MyStruct` is defined multiple times - --> $DIR/cross-crate-redefine.rs:10:1 + --> $DIR/cross-crate-redefine.rs:11:1 | -LL | my_struct!(define); - | ^^^^^^^^^^^^^^^^^^ `MyStruct` redefined here -LL | LL | my_struct!(define); | ------------------ previous definition of the type `MyStruct` here +LL | my_struct!(define); + | ^^^^^^^^^^^^^^^^^^ `MyStruct` redefined here | = note: `MyStruct` must be defined only once in the type namespace of this module = note: this error originates in the macro `my_struct` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/hygiene/duplicate_lifetimes.rs b/tests/ui/hygiene/duplicate_lifetimes.rs index 8971fb62626c..4d128da7fdbf 100644 --- a/tests/ui/hygiene/duplicate_lifetimes.rs +++ b/tests/ui/hygiene/duplicate_lifetimes.rs @@ -3,7 +3,7 @@ #![feature(decl_macro, rustc_attrs)] -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] macro m($a:lifetime) { fn g<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter } diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs index 71c33674b37f..60355c22bb30 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.rs @@ -10,7 +10,7 @@ macro a() { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `my_core` + //~^ ERROR cannot find } } @@ -23,7 +23,7 @@ mod v { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `my_core` + //~^ ERROR cannot find } fn main() {} diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr index 87ef07c27f5b..db1a56d7d816 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail-2018.stderr @@ -15,7 +15,7 @@ LL | a!(); | = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `my_core` +error[E0433]: cannot find module or crate `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail-2018.rs:12:18 | LL | fn f() { my_core::mem::drop(0); } @@ -29,7 +29,7 @@ LL | a!(); std::mem = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `my_core` +error[E0433]: cannot find module or crate `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail-2018.rs:25:14 | LL | fn f() { my_core::mem::drop(0); } diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs b/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs index 8265b73cc565..8f75ba1434a1 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail.rs @@ -10,7 +10,7 @@ macro a() { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `my_core` + //~^ ERROR cannot find } } @@ -23,7 +23,7 @@ mod v { mod u { // Late resolution. fn f() { my_core::mem::drop(0); } - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `my_core` + //~^ ERROR cannot find } fn main() {} diff --git a/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr index d36bc9130953..f3a43fa0127c 100644 --- a/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr +++ b/tests/ui/hygiene/extern-prelude-from-opaque-fail.stderr @@ -15,7 +15,7 @@ LL | a!(); | = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `my_core` +error[E0433]: cannot find module or crate `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail.rs:12:18 | LL | fn f() { my_core::mem::drop(0); } @@ -29,7 +29,7 @@ LL | a!(); my_core::mem = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `my_core` +error[E0433]: cannot find module or crate `my_core` in this scope --> $DIR/extern-prelude-from-opaque-fail.rs:25:14 | LL | fn f() { my_core::mem::drop(0); } diff --git a/tests/ui/hygiene/format-args.rs b/tests/ui/hygiene/format-args.rs index ff08aecfd9eb..f845f5d8a4c8 100644 --- a/tests/ui/hygiene/format-args.rs +++ b/tests/ui/hygiene/format-args.rs @@ -3,6 +3,8 @@ #![allow(non_upper_case_globals)] #![feature(format_args_nl)] +use std::format_args_nl; + static arg0: () = (); fn main() { diff --git a/tests/ui/hygiene/generic_params.rs b/tests/ui/hygiene/generic_params.rs index def9be3a1b64..bb0de15d9a0a 100644 --- a/tests/ui/hygiene/generic_params.rs +++ b/tests/ui/hygiene/generic_params.rs @@ -11,7 +11,7 @@ mod type_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($T:ident) { fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) { (t1.clone(), t2.clone()) @@ -43,7 +43,7 @@ mod lifetime_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($a:lifetime) { fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { (t1, t2) @@ -75,7 +75,7 @@ mod const_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($C:ident) { fn g(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { (t1, t2) diff --git a/tests/ui/hygiene/no_implicit_prelude.rs b/tests/ui/hygiene/no_implicit_prelude.rs index 8145212fe309..bfe7a6a44614 100644 --- a/tests/ui/hygiene/no_implicit_prelude.rs +++ b/tests/ui/hygiene/no_implicit_prelude.rs @@ -9,7 +9,7 @@ mod foo { #[no_implicit_prelude] mod bar { pub macro m() { - Vec::new(); //~ ERROR failed to resolve + Vec::new(); //~ ERROR cannot find ().clone() //~ ERROR no method named `clone` found } fn f() { diff --git a/tests/ui/hygiene/no_implicit_prelude.stderr b/tests/ui/hygiene/no_implicit_prelude.stderr index 0606fe501386..5461ee527b88 100644 --- a/tests/ui/hygiene/no_implicit_prelude.stderr +++ b/tests/ui/hygiene/no_implicit_prelude.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `Vec` +error[E0433]: cannot find type `Vec` in this scope --> $DIR/no_implicit_prelude.rs:12:9 | LL | fn f() { ::bar::m!(); } diff --git a/tests/ui/hygiene/panic-location.rs b/tests/ui/hygiene/panic-location.rs index 4731d8e1d538..27850f3e4c3a 100644 --- a/tests/ui/hygiene/panic-location.rs +++ b/tests/ui/hygiene/panic-location.rs @@ -2,6 +2,7 @@ //@ check-run-results //@ exec-env:RUST_BACKTRACE=0 //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" // // Regression test for issue #70963 // The reported panic location should not be `<::core::macros::panic macros>`. diff --git a/tests/ui/hygiene/rustc-macro-transparency.rs b/tests/ui/hygiene/rustc-macro-transparency.rs index 1a78a7543cfd..0c680abb4153 100644 --- a/tests/ui/hygiene/rustc-macro-transparency.rs +++ b/tests/ui/hygiene/rustc-macro-transparency.rs @@ -5,7 +5,7 @@ macro transparent() { struct Transparent; let transparent = 0; } -#[rustc_macro_transparency = "semitransparent"] +#[rustc_macro_transparency = "semiopaque"] macro semiopaque() { struct SemiOpaque; let semiopaque = 0; diff --git a/tests/ui/hygiene/rustc-macro-transparency.stderr b/tests/ui/hygiene/rustc-macro-transparency.stderr index 1bea8a0ee4f3..af67bfe66cc8 100644 --- a/tests/ui/hygiene/rustc-macro-transparency.stderr +++ b/tests/ui/hygiene/rustc-macro-transparency.stderr @@ -11,10 +11,13 @@ LL | struct SemiOpaque; | ------------------ similarly named unit struct `SemiOpaque` defined here ... LL | semiopaque; - | ^^^^^^^^^^ - | | - | not a value - | help: a unit struct with a similar name exists (notice the capitalization): `SemiOpaque` + | ^^^^^^^^^^ not a value + | +help: a unit struct with a similar name exists (notice the capitalization) + | +LL - semiopaque; +LL + SemiOpaque; + | error[E0423]: expected value, found macro `opaque` --> $DIR/rustc-macro-transparency.rs:30:5 diff --git a/tests/ui/hygiene/unpretty-debug-lifetimes.rs b/tests/ui/hygiene/unpretty-debug-lifetimes.rs new file mode 100644 index 000000000000..ee8be21b60d0 --- /dev/null +++ b/tests/ui/hygiene/unpretty-debug-lifetimes.rs @@ -0,0 +1,18 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=expanded,hygiene + +// Regression test for lifetime hygiene annotations in -Zunpretty=expanded,hygiene +// Previously, lifetimes were missing the #N syntax context suffix. + +// Don't break whenever Symbol numbering changes +//@ normalize-stdout: "\d+#" -> "0#" + +#![feature(decl_macro)] +#![feature(no_core)] +#![no_core] + +macro lifetime_hygiene($f:ident<$a:lifetime>) { + fn $f<$a, 'a>() {} +} + +lifetime_hygiene!(f<'a>); diff --git a/tests/ui/hygiene/unpretty-debug-lifetimes.stdout b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout new file mode 100644 index 000000000000..28a5c70a02d7 --- /dev/null +++ b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout @@ -0,0 +1,31 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=expanded,hygiene + +// Regression test for lifetime hygiene annotations in -Zunpretty=expanded,hygiene +// Previously, lifetimes were missing the #N syntax context suffix. + +// Don't break whenever Symbol numbering changes +//@ normalize-stdout: "\d+#" -> "0#" + +#![feature /* 0#0 */(decl_macro)] +#![feature /* 0#0 */(no_core)] +#![no_core /* 0#0 */] + +macro lifetime_hygiene + /* + 0#0 + */ { + ($f:ident<$a:lifetime>) => { fn $f<$a, 'a>() {} } +} +fn f /* 0#0 */<'a /* 0#0 */, 'a /* 0#1 */>() {} + + +/* +Expansions: +crate0::{{expn0}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Root +crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "lifetime_hygiene") + +SyntaxContexts: +#0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque) +#1: parent: #0, outer_mark: (crate0::{{expn1}}, Opaque) +*/ diff --git a/tests/ui/impl-trait/associated-type-cycle.stderr b/tests/ui/impl-trait/associated-type-cycle.stderr index 7eef8d1e3389..438a5a92ffc2 100644 --- a/tests/ui/impl-trait/associated-type-cycle.stderr +++ b/tests/ui/impl-trait/associated-type-cycle.stderr @@ -5,7 +5,7 @@ LL | type Bar; | -------- `Bar` defined here ... LL | impl Foo for Box { - | ^^^ help: specify the associated type: `Foo` + | ^^^ help: specify the associated type: `Foo` error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index c2b889138c89..7f965b9609a9 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -33,13 +33,19 @@ LL | n + sum_to(n - 1) help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: `u32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u32` implements `Add<&u32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u32` implements `Add` + = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2015.stderr b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2015.stderr new file mode 100644 index 000000000000..8954a802ab95 --- /dev/null +++ b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2015.stderr @@ -0,0 +1,17 @@ +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:44 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^^^^^^^^^^^^--^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope + | +note: lifetime declared here + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:20 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^ ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2024.stderr b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2024.stderr new file mode 100644 index 000000000000..8954a802ab95 --- /dev/null +++ b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.edition2024.stderr @@ -0,0 +1,17 @@ +error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:44 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^^^^^^^^^^^^--^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope + | +note: lifetime declared here + --> $DIR/higher-ranked-lifetime-capture-deduplication.rs:19:20 + | +LL | fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + | ^^ ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.rs b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.rs new file mode 100644 index 000000000000..d8da93e5560d --- /dev/null +++ b/tests/ui/impl-trait/higher-ranked-lifetime-capture-deduplication.rs @@ -0,0 +1,26 @@ +//@revisions: edition2015 edition2024 +//@[edition2015] edition:2015 +//@[edition2024] edition:2024 + +trait Trait<'a> { + type Out; + fn call(&'a self) -> Self::Out; +} + +struct X(()); + +impl<'a> Trait<'a> for X { + type Out = (); + fn call(&'a self) -> Self::Out { + () + } +} + +fn f() -> impl for<'a, 'b> Trait<'a, Out = impl Sized + 'a + 'b> { + //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` + X(()) +} + +fn main() { + let _ = f(); +} diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr index 40cb6b647d1e..36f52e8103a3 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -12,10 +12,12 @@ LL + fn d() -> impl Fn() -> (impl Debug + 'static) { | error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:4:41 + --> $DIR/impl-fn-hrtb-bounds.rs:4:28 | LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-hrtb-bounds.rs:4:19 @@ -24,10 +26,12 @@ LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { | ^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:9:52 + --> $DIR/impl-fn-hrtb-bounds.rs:9:39 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-hrtb-bounds.rs:9:20 @@ -36,10 +40,12 @@ LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:14:52 + --> $DIR/impl-fn-hrtb-bounds.rs:14:39 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-hrtb-bounds.rs:14:20 diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr index 94b6ffdd9123..5ba9567e14e3 100644 --- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr +++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr @@ -21,10 +21,12 @@ LL | fn b() -> impl Fn() -> (impl Debug + Send) { | + + error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-parsing-ambiguities.rs:4:40 + --> $DIR/impl-fn-parsing-ambiguities.rs:4:27 | LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/impl-fn-parsing-ambiguities.rs:4:19 diff --git a/tests/ui/impl-trait/impl-trait-in-generic-param.rs b/tests/ui/impl-trait/impl-trait-in-generic-param.rs new file mode 100644 index 000000000000..4a6a76e4f2d1 --- /dev/null +++ b/tests/ui/impl-trait/impl-trait-in-generic-param.rs @@ -0,0 +1,30 @@ +//! regression test for + +trait Foo {} + +trait Bar {} + +trait Iterable { + type Item; +} + +struct Container> { + //~^ ERROR `impl Trait` is not allowed in generics + field: T +} + +enum Enum> { + //~^ ERROR `impl Trait` is not allowed in generics + A(T), +} + +union Union + Copy> { + //~^ ERROR `impl Trait` is not allowed in generics + x: T, +} + +type Type> = T; +//~^ ERROR `impl Trait` is not allowed in generics + +fn main() { +} diff --git a/tests/ui/impl-trait/impl-trait-in-generic-param.stderr b/tests/ui/impl-trait/impl-trait-in-generic-param.stderr new file mode 100644 index 000000000000..806a3cb22754 --- /dev/null +++ b/tests/ui/impl-trait/impl-trait-in-generic-param.stderr @@ -0,0 +1,35 @@ +error[E0562]: `impl Trait` is not allowed in generics + --> $DIR/impl-trait-in-generic-param.rs:11:37 + | +LL | struct Container> { + | ^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error[E0562]: `impl Trait` is not allowed in generics + --> $DIR/impl-trait-in-generic-param.rs:16:30 + | +LL | enum Enum> { + | ^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error[E0562]: `impl Trait` is not allowed in generics + --> $DIR/impl-trait-in-generic-param.rs:21:32 + | +LL | union Union + Copy> { + | ^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error[E0562]: `impl Trait` is not allowed in generics + --> $DIR/impl-trait-in-generic-param.rs:26:30 + | +LL | type Type> = T; + | ^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr index 19ffff9d3f2b..75d722402096 100644 --- a/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr +++ b/tests/ui/impl-trait/in-trait/async-and-ret-ref.stderr @@ -1,11 +1,11 @@ error[E0310]: the associated type `impl T` may not live long enough - --> $DIR/async-and-ret-ref.rs:7:5 + --> $DIR/async-and-ret-ref.rs:7:23 | LL | async fn foo() -> &'static impl T; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the associated type `impl T` must be valid for the static lifetime... - | ...so that the reference type `&'static impl T` does not outlive the data it points at + | ^^^^^^^^^^^^^^^ + | | + | the associated type `impl T` must be valid for the static lifetime... + | ...so that the reference type `&'static impl T` does not outlive the data it points at error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs b/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs index 8433fb72b5e0..fa4ce66d54e6 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.rs @@ -14,6 +14,7 @@ impl Mirror for () { pub trait First { async fn first() -> <() as Mirror>::Assoc; + //~^ ERROR type annotations needed } impl First for () { diff --git a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr index fd53c9fef443..af71e52b87d7 100644 --- a/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr +++ b/tests/ui/impl-trait/in-trait/refine-resolution-errors.stderr @@ -28,7 +28,13 @@ help: consider relaxing the implicit `Sized` restriction LL | type Assoc: ?Sized; | ++++++++ -error: aborting due to 2 previous errors +error[E0282]: type annotations needed + --> $DIR/refine-resolution-errors.rs:16:25 + | +LL | async fn first() -> <() as Mirror>::Assoc; + | ^^^^^^^^^^^^^^^^^^^^^ cannot infer type -Some errors have detailed explanations: E0207, E0277. +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0207, E0277, E0282. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr b/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr index 27a3c6c8b7ce..8348a1d5e87b 100644 --- a/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr +++ b/tests/ui/impl-trait/issues/issue-54895.edition2015.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-54895.rs:18:53 + --> $DIR/issue-54895.rs:18:40 | LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-54895.rs:18:20 diff --git a/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr b/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr index 54aa29e62d88..8348a1d5e87b 100644 --- a/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr +++ b/tests/ui/impl-trait/issues/issue-54895.edition2024.stderr @@ -2,7 +2,9 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `imp --> $DIR/issue-54895.rs:18:40 | LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-54895.rs:18:20 @@ -10,18 +12,6 @@ note: lifetime declared here LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { | ^^ -error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-54895.rs:18:53 - | -LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^ - | -note: lifetime declared here - --> $DIR/issue-54895.rs:18:20 - | -LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/issues/issue-54895.rs b/tests/ui/impl-trait/issues/issue-54895.rs index bc1841209e17..ccdb0ce20f9a 100644 --- a/tests/ui/impl-trait/issues/issue-54895.rs +++ b/tests/ui/impl-trait/issues/issue-54895.rs @@ -17,7 +17,6 @@ impl<'a> Trait<'a> for X { fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - //[edition2024]~^^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` X(()) } diff --git a/tests/ui/impl-trait/issues/issue-67830.stderr b/tests/ui/impl-trait/issues/issue-67830.stderr index a7633c7f20b6..7254955ed0bd 100644 --- a/tests/ui/impl-trait/issues/issue-67830.stderr +++ b/tests/ui/impl-trait/issues/issue-67830.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-67830.rs:20:64 + --> $DIR/issue-67830.rs:20:48 | LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { - | ^^ + | ^^^^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-67830.rs:20:23 diff --git a/tests/ui/impl-trait/issues/issue-72911.rs b/tests/ui/impl-trait/issues/issue-72911.rs index 63f4898f4306..b105860ba651 100644 --- a/tests/ui/impl-trait/issues/issue-72911.rs +++ b/tests/ui/impl-trait/issues/issue-72911.rs @@ -9,12 +9,12 @@ pub fn gather_all() -> impl Iterator { } fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator { - //~^ ERROR: failed to resolve + //~^ ERROR: cannot find unimplemented!() } fn lint_files() -> impl Iterator { - //~^ ERROR: failed to resolve + //~^ ERROR: cannot find unimplemented!() } diff --git a/tests/ui/impl-trait/issues/issue-72911.stderr b/tests/ui/impl-trait/issues/issue-72911.stderr index 063b7f68dc02..1333f608ead1 100644 --- a/tests/ui/impl-trait/issues/issue-72911.stderr +++ b/tests/ui/impl-trait/issues/issue-72911.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `foo` +error[E0433]: cannot find module or crate `foo` in this scope --> $DIR/issue-72911.rs:11:33 | LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator { @@ -6,7 +6,7 @@ LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator $DIR/issue-72911.rs:16:41 | LL | fn lint_files() -> impl Iterator { diff --git a/tests/ui/impl-trait/issues/issue-88236-2.stderr b/tests/ui/impl-trait/issues/issue-88236-2.stderr index 4ded9ed386fa..3943c4121845 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.stderr +++ b/tests/ui/impl-trait/issues/issue-88236-2.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:15:61 + --> $DIR/issue-88236-2.rs:15:49 | LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236-2.rs:15:28 @@ -11,10 +13,12 @@ LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:18:80 + --> $DIR/issue-88236-2.rs:18:68 | LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236-2.rs:18:47 @@ -23,10 +27,12 @@ LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Sen | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:23:78 + --> $DIR/issue-88236-2.rs:23:66 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236-2.rs:23:45 diff --git a/tests/ui/impl-trait/issues/issue-88236.stderr b/tests/ui/impl-trait/issues/issue-88236.stderr index 5dee5f88c89f..6303379288b7 100644 --- a/tests/ui/impl-trait/issues/issue-88236.stderr +++ b/tests/ui/impl-trait/issues/issue-88236.stderr @@ -1,8 +1,10 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236.rs:15:61 + --> $DIR/issue-88236.rs:15:49 | LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} - | ^^ + | ^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/issue-88236.rs:15:28 diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index a15f400fc2a7..6c1253678e99 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -30,10 +30,12 @@ LL | fn two_htrb_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl for<'b | ++++ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:25:69 + --> $DIR/nested-rpit-hrtb.rs:25:56 | LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {} - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:25:36 @@ -42,10 +44,10 @@ LL | fn one_hrtb_outlives() -> impl for<'a> Foo<'a, Assoc = impl Sized + 'a> {} | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:29:68 + --> $DIR/nested-rpit-hrtb.rs:29:59 | LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} - | ^^ + | ^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:29:39 @@ -54,10 +56,12 @@ LL | fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:32:74 + --> $DIR/nested-rpit-hrtb.rs:32:61 | LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} - | ^^ + | ^^^^^^^^^^^^^-- + | | + | `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:32:41 @@ -66,10 +70,10 @@ LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:35:73 + --> $DIR/nested-rpit-hrtb.rs:35:64 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} - | ^^ + | ^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/nested-rpit-hrtb.rs:35:44 diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr index 880e7878477a..fef0a85bf1ae 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr +++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr @@ -282,7 +282,6 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has | LL | let x = { let x = display_len(&mut vec![0]); x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the precise capturing `use<...>` syntax to make the captures explicit | LL | fn display_len(x: &Vec) -> impl Display + use { diff --git a/tests/ui/impl-trait/stashed-diag-issue-121504.rs b/tests/ui/impl-trait/stashed-diag-issue-121504.rs index 84686ba4f7d3..ee2cd1ee816f 100644 --- a/tests/ui/impl-trait/stashed-diag-issue-121504.rs +++ b/tests/ui/impl-trait/stashed-diag-issue-121504.rs @@ -4,7 +4,7 @@ trait MyTrait { async fn foo(self) -> (Self, i32); } -impl MyTrait for xyz::T { //~ ERROR failed to resolve: use of unresolved module or unlinked crate `xyz` +impl MyTrait for xyz::T { //~ ERROR cannot find module or crate `xyz` async fn foo(self, key: i32) -> (u32, i32) { (self, key) } diff --git a/tests/ui/impl-trait/stashed-diag-issue-121504.stderr b/tests/ui/impl-trait/stashed-diag-issue-121504.stderr index 41c6cc425558..f973e6c9dc42 100644 --- a/tests/ui/impl-trait/stashed-diag-issue-121504.stderr +++ b/tests/ui/impl-trait/stashed-diag-issue-121504.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `xyz` +error[E0433]: cannot find module or crate `xyz` in this scope --> $DIR/stashed-diag-issue-121504.rs:7:18 | LL | impl MyTrait for xyz::T { diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 6cab4fabb1ff..2d97215de3bb 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -384,19 +384,11 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani | = note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`: - impl Fn for &F - where A: Tuple, F: Fn, F: ?Sized; + where A: std::marker::Tuple, F: Fn, F: ?Sized; - impl Fn for Box - where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; + where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - impl Fn for Exclusive - where F: Sync, F: Fn, Args: Tuple; - -error[E0118]: no nominal type found for inherent implementation - --> $DIR/where-allowed.rs:241:1 - | -LL | impl T {} - | ^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type - | - = note: either implement a trait on it or create a newtype to wrap it instead + where F: Sync, F: Fn, Args: std::marker::Tuple; error: unconstrained opaque type --> $DIR/where-allowed.rs:122:16 @@ -414,6 +406,14 @@ LL | type InTypeAlias = impl Debug; | = note: `InTypeAlias` must be used in combination with a concrete type within the same crate +error[E0118]: no nominal type found for inherent implementation + --> $DIR/where-allowed.rs:241:1 + | +LL | impl T {} + | ^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type + | + = note: either implement a trait on it or create a newtype to wrap it instead + error: aborting due to 48 previous errors Some errors have detailed explanations: E0053, E0118, E0283, E0562, E0658, E0666. diff --git a/tests/ui/imports/absolute-paths-in-nested-use-groups.rs b/tests/ui/imports/absolute-paths-in-nested-use-groups.rs index 96b5131674c7..9a8c9aab7282 100644 --- a/tests/ui/imports/absolute-paths-in-nested-use-groups.rs +++ b/tests/ui/imports/absolute-paths-in-nested-use-groups.rs @@ -3,9 +3,12 @@ mod foo {} use foo::{ - ::bar, //~ ERROR crate root in paths can only be used in start position - super::bar, //~ ERROR `super` in paths can only be used in start position - self::bar, //~ ERROR `self` in paths can only be used in start position + ::bar, + //~^ ERROR: crate root in paths can only be used in start position + super::bar, + //~^ ERROR: `super` in paths can only be used in start position + self::bar, + //~^ ERROR: `self` in paths can only be used in start position }; fn main() {} diff --git a/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr b/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr index e41590ac45ee..ff951ad7489c 100644 --- a/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr +++ b/tests/ui/imports/absolute-paths-in-nested-use-groups.stderr @@ -1,20 +1,20 @@ -error[E0433]: failed to resolve: crate root in paths can only be used in start position +error[E0433]: the crate root in paths can only be used in start position --> $DIR/absolute-paths-in-nested-use-groups.rs:6:5 | LL | ::bar, - | ^ crate root in paths can only be used in start position + | ^ can only be used in path start position -error[E0433]: failed to resolve: `super` in paths can only be used in start position - --> $DIR/absolute-paths-in-nested-use-groups.rs:7:5 - | -LL | super::bar, - | ^^^^^ `super` in paths can only be used in start position - -error[E0433]: failed to resolve: `self` in paths can only be used in start position +error[E0433]: `super` in paths can only be used in start position --> $DIR/absolute-paths-in-nested-use-groups.rs:8:5 | +LL | super::bar, + | ^^^^^ can only be used in path start position + +error[E0433]: `self` in paths can only be used in start position + --> $DIR/absolute-paths-in-nested-use-groups.rs:10:5 + | LL | self::bar, - | ^^^^ `self` in paths can only be used in start position + | ^^^^ can only be used in path start position error: aborting due to 3 previous errors diff --git a/tests/ui/imports/ambiguous-10.rs b/tests/ui/imports/ambiguous-10.rs index 166b01ede12d..61069cb75124 100644 --- a/tests/ui/imports/ambiguous-10.rs +++ b/tests/ui/imports/ambiguous-10.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass mod a { pub enum Token {} } @@ -13,6 +13,6 @@ mod b { use crate::a::*; use crate::b::*; fn c(_: Token) {} -//~^ ERROR `Token` is ambiguous +//~^ WARN `Token` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() { } diff --git a/tests/ui/imports/ambiguous-10.stderr b/tests/ui/imports/ambiguous-10.stderr index f175d27c99e9..4ae3e4203fab 100644 --- a/tests/ui/imports/ambiguous-10.stderr +++ b/tests/ui/imports/ambiguous-10.stderr @@ -1,4 +1,4 @@ -error: `Token` is ambiguous +warning: `Token` is ambiguous --> $DIR/ambiguous-10.rs:15:9 | LL | fn c(_: Token) {} @@ -19,12 +19,12 @@ note: `Token` could also refer to the enum imported here LL | use crate::b::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `Token` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Token` is ambiguous +warning: `Token` is ambiguous --> $DIR/ambiguous-10.rs:15:9 | LL | fn c(_: Token) {} @@ -45,5 +45,5 @@ note: `Token` could also refer to the enum imported here LL | use crate::b::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `Token` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-12.rs b/tests/ui/imports/ambiguous-12.rs index 543396b8dfe5..93cd3ca6f347 100644 --- a/tests/ui/imports/ambiguous-12.rs +++ b/tests/ui/imports/ambiguous-12.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass macro_rules! m { () => { pub fn b() {} @@ -19,6 +19,6 @@ use crate::public::*; fn main() { b(); - //~^ ERROR `b` is ambiguous + //~^ WARN `b` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-12.stderr b/tests/ui/imports/ambiguous-12.stderr index 5f92eae0dbcb..1a1777dedac4 100644 --- a/tests/ui/imports/ambiguous-12.stderr +++ b/tests/ui/imports/ambiguous-12.stderr @@ -1,4 +1,4 @@ -error: `b` is ambiguous +warning: `b` is ambiguous --> $DIR/ambiguous-12.rs:21:5 | LL | b(); @@ -19,12 +19,12 @@ note: `b` could also refer to the function imported here LL | use crate::public::*; | ^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `b` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `b` is ambiguous +warning: `b` is ambiguous --> $DIR/ambiguous-12.rs:21:5 | LL | b(); @@ -45,5 +45,5 @@ note: `b` could also refer to the function imported here LL | use crate::public::*; | ^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `b` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-13.rs b/tests/ui/imports/ambiguous-13.rs index 3569dd5d9adc..5fbb71d8545a 100644 --- a/tests/ui/imports/ambiguous-13.rs +++ b/tests/ui/imports/ambiguous-13.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass pub mod object { #[derive(Debug)] pub struct Rect; @@ -16,6 +16,6 @@ use crate::object::*; use crate::content::*; fn a(_: Rect) {} -//~^ ERROR `Rect` is ambiguous +//~^ WARN `Rect` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() { } diff --git a/tests/ui/imports/ambiguous-13.stderr b/tests/ui/imports/ambiguous-13.stderr index 279b4e8f1420..ca83cf63c12c 100644 --- a/tests/ui/imports/ambiguous-13.stderr +++ b/tests/ui/imports/ambiguous-13.stderr @@ -1,4 +1,4 @@ -error: `Rect` is ambiguous +warning: `Rect` is ambiguous --> $DIR/ambiguous-13.rs:18:9 | LL | fn a(_: Rect) {} @@ -19,12 +19,12 @@ note: `Rect` could also refer to the struct imported here LL | use crate::content::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Rect` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Rect` is ambiguous +warning: `Rect` is ambiguous --> $DIR/ambiguous-13.rs:18:9 | LL | fn a(_: Rect) {} @@ -45,5 +45,5 @@ note: `Rect` could also refer to the struct imported here LL | use crate::content::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Rect` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-14.rs b/tests/ui/imports/ambiguous-14.rs index ba2d7dc4e016..325b29f3b481 100644 --- a/tests/ui/imports/ambiguous-14.rs +++ b/tests/ui/imports/ambiguous-14.rs @@ -1,6 +1,6 @@ //@ edition:2015 // https://github.com/rust-lang/rust/issues/98467 - +//@ check-pass mod a { pub fn foo() {} } @@ -21,6 +21,6 @@ mod g { fn main() { g::foo(); - //~^ ERROR `foo` is ambiguous + //~^ WARN `foo` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-14.stderr b/tests/ui/imports/ambiguous-14.stderr index 4efa31c61e32..6823d728c368 100644 --- a/tests/ui/imports/ambiguous-14.stderr +++ b/tests/ui/imports/ambiguous-14.stderr @@ -1,4 +1,4 @@ -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/ambiguous-14.rs:23:8 | LL | g::foo(); @@ -8,23 +8,23 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:13:13 + --> $DIR/ambiguous-14.rs:18:13 | LL | pub use a::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:14:13 + --> $DIR/ambiguous-14.rs:19:13 | -LL | pub use b::*; +LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/ambiguous-14.rs:23:8 | LL | g::foo(); @@ -34,16 +34,16 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:13:13 + --> $DIR/ambiguous-14.rs:18:13 | LL | pub use a::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:14:13 + --> $DIR/ambiguous-14.rs:19:13 | -LL | pub use b::*; +LL | pub use f::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-15.rs b/tests/ui/imports/ambiguous-15.rs index 07d8893b2dea..f90d9696e8ef 100644 --- a/tests/ui/imports/ambiguous-15.rs +++ b/tests/ui/imports/ambiguous-15.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152 - +//@ check-pass mod t2 { #[derive(Debug)] pub enum Error {} @@ -20,7 +20,7 @@ mod t3 { use self::t3::*; fn a(_: E) {} -//~^ ERROR `Error` is ambiguous +//~^ WARN `Error` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() {} diff --git a/tests/ui/imports/ambiguous-15.stderr b/tests/ui/imports/ambiguous-15.stderr index 15f83546532e..59f9cb0526fc 100644 --- a/tests/ui/imports/ambiguous-15.stderr +++ b/tests/ui/imports/ambiguous-15.stderr @@ -1,4 +1,4 @@ -error: `Error` is ambiguous +warning: `Error` is ambiguous --> $DIR/ambiguous-15.rs:22:9 | LL | fn a(_: E) {} @@ -19,12 +19,12 @@ note: `Error` could also refer to the enum imported here LL | pub use t2::*; | ^^^^^ = help: consider adding an explicit import of `Error` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Error` is ambiguous +warning: `Error` is ambiguous --> $DIR/ambiguous-15.rs:22:9 | LL | fn a(_: E) {} @@ -45,5 +45,5 @@ note: `Error` could also refer to the enum imported here LL | pub use t2::*; | ^^^^^ = help: consider adding an explicit import of `Error` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-16.rs b/tests/ui/imports/ambiguous-16.rs index f31c78d18a38..2cd1e2aca9d3 100644 --- a/tests/ui/imports/ambiguous-16.rs +++ b/tests/ui/imports/ambiguous-16.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099 - +//@ check-pass mod framing { mod public_message { use super::*; @@ -20,7 +20,7 @@ mod framing { } use crate::framing::ConfirmedTranscriptHashInput; -//~^ ERROR `ConfirmedTranscriptHashInput` is ambiguous +//~^ WARN `ConfirmedTranscriptHashInput` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() { } diff --git a/tests/ui/imports/ambiguous-16.stderr b/tests/ui/imports/ambiguous-16.stderr index 7c80dee17f04..bb76111ebe89 100644 --- a/tests/ui/imports/ambiguous-16.stderr +++ b/tests/ui/imports/ambiguous-16.stderr @@ -1,4 +1,4 @@ -error: `ConfirmedTranscriptHashInput` is ambiguous +warning: `ConfirmedTranscriptHashInput` is ambiguous --> $DIR/ambiguous-16.rs:22:21 | LL | use crate::framing::ConfirmedTranscriptHashInput; @@ -19,12 +19,12 @@ note: `ConfirmedTranscriptHashInput` could also refer to the struct imported her LL | pub use self::public_message_in::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `ConfirmedTranscriptHashInput` is ambiguous +warning: `ConfirmedTranscriptHashInput` is ambiguous --> $DIR/ambiguous-16.rs:22:21 | LL | use crate::framing::ConfirmedTranscriptHashInput; @@ -45,5 +45,5 @@ note: `ConfirmedTranscriptHashInput` could also refer to the struct imported her LL | pub use self::public_message_in::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `ConfirmedTranscriptHashInput` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-17.rs b/tests/ui/imports/ambiguous-17.rs index 3a51c156d34c..8ef0318fa046 100644 --- a/tests/ui/imports/ambiguous-17.rs +++ b/tests/ui/imports/ambiguous-17.rs @@ -1,6 +1,6 @@ //@ edition:2015 // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152 - +//@ check-pass pub use evp::*; //~ WARNING ambiguous glob re-exports pub use handwritten::*; @@ -24,6 +24,6 @@ mod handwritten { fn main() { id(); - //~^ ERROR `id` is ambiguous + //~^ WARN `id` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-17.stderr b/tests/ui/imports/ambiguous-17.stderr index 1849b83d76a3..ef4a835a0b3c 100644 --- a/tests/ui/imports/ambiguous-17.stderr +++ b/tests/ui/imports/ambiguous-17.stderr @@ -8,7 +8,7 @@ LL | pub use handwritten::*; | = note: `#[warn(ambiguous_glob_reexports)]` on by default -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-17.rs:26:5 | LL | id(); @@ -29,12 +29,12 @@ note: `id` could also refer to the function imported here LL | pub use handwritten::*; | ^^^^^^^^^^^^^^ = help: consider adding an explicit import of `id` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error; 1 warning emitted +warning: 2 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `id` is ambiguous +warning: `id` is ambiguous --> $DIR/ambiguous-17.rs:26:5 | LL | id(); @@ -55,5 +55,5 @@ note: `id` could also refer to the function imported here LL | pub use handwritten::*; | ^^^^^^^^^^^^^^ = help: consider adding an explicit import of `id` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-2.rs b/tests/ui/imports/ambiguous-2.rs index 087431485ad6..978655bc0177 100644 --- a/tests/ui/imports/ambiguous-2.rs +++ b/tests/ui/imports/ambiguous-2.rs @@ -1,10 +1,9 @@ -//@ check-pass //@ aux-build: ../ambiguous-1.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1633574396 - +//@ check-pass extern crate ambiguous_1; fn main() { - ambiguous_1::id(); - //^ FIXME: `id` should be identified as an ambiguous item. + ambiguous_1::id(); //~ WARN `id` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/ambiguous-2.stderr b/tests/ui/imports/ambiguous-2.stderr new file mode 100644 index 000000000000..5b12491af19d --- /dev/null +++ b/tests/ui/imports/ambiguous-2.stderr @@ -0,0 +1,49 @@ +warning: `id` is ambiguous + --> $DIR/ambiguous-2.rs:7:18 + | +LL | ambiguous_1::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:13:13 + | +LL | pub use self::evp::*; + | ^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:15:13 + | +LL | pub use self::handwritten::*; + | ^^^^^^^^^^^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `id` is ambiguous + --> $DIR/ambiguous-2.rs:7:18 + | +LL | ambiguous_1::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:13:13 + | +LL | pub use self::evp::*; + | ^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-1.rs:15:13 + | +LL | pub use self::handwritten::*; + | ^^^^^^^^^^^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/ambiguous-3.rs b/tests/ui/imports/ambiguous-3.rs index ff0dcc221ec0..717c1eb8597a 100644 --- a/tests/ui/imports/ambiguous-3.rs +++ b/tests/ui/imports/ambiguous-3.rs @@ -1,9 +1,9 @@ // https://github.com/rust-lang/rust/issues/47525 - +//@ check-pass fn main() { use a::*; x(); - //~^ ERROR `x` is ambiguous + //~^ WARN `x` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-3.stderr b/tests/ui/imports/ambiguous-3.stderr index 27fa05a195b9..7addf9bc797c 100644 --- a/tests/ui/imports/ambiguous-3.stderr +++ b/tests/ui/imports/ambiguous-3.stderr @@ -1,4 +1,4 @@ -error: `x` is ambiguous +warning: `x` is ambiguous --> $DIR/ambiguous-3.rs:5:5 | LL | x(); @@ -19,12 +19,12 @@ note: `x` could also refer to the function imported here LL | pub use self::c::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `x` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `x` is ambiguous +warning: `x` is ambiguous --> $DIR/ambiguous-3.rs:5:5 | LL | x(); @@ -45,5 +45,5 @@ note: `x` could also refer to the function imported here LL | pub use self::c::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `x` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs index d604dca30eed..1a2bfeaf53dc 100644 --- a/tests/ui/imports/ambiguous-4.rs +++ b/tests/ui/imports/ambiguous-4.rs @@ -1,10 +1,9 @@ //@ edition:2015 -//@ check-pass //@ aux-build: ../ambiguous-4-extern.rs - +//@ check-pass extern crate ambiguous_4_extern; fn main() { - ambiguous_4_extern::id(); - //^ FIXME: `id` should be identified as an ambiguous item. + ambiguous_4_extern::id(); //~ WARN `id` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/ambiguous-4.stderr b/tests/ui/imports/ambiguous-4.stderr new file mode 100644 index 000000000000..691dd33a398a --- /dev/null +++ b/tests/ui/imports/ambiguous-4.stderr @@ -0,0 +1,49 @@ +warning: `id` is ambiguous + --> $DIR/ambiguous-4.rs:7:25 + | +LL | ambiguous_4_extern::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:13:9 + | +LL | pub use evp::*; + | ^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:14:9 + | +LL | pub use handwritten::*; + | ^^^^^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `id` is ambiguous + --> $DIR/ambiguous-4.rs:7:25 + | +LL | ambiguous_4_extern::id(); + | ^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `id` could refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:13:9 + | +LL | pub use evp::*; + | ^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `id` could also refer to the function defined here + --> $DIR/auxiliary/../ambiguous-4-extern.rs:14:9 + | +LL | pub use handwritten::*; + | ^^^^^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/ambiguous-5.rs b/tests/ui/imports/ambiguous-5.rs index 8f89c966d4a5..9879216280a2 100644 --- a/tests/ui/imports/ambiguous-5.rs +++ b/tests/ui/imports/ambiguous-5.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1637022296 - +//@ check-pass mod a { pub struct Class(u16); } @@ -10,7 +10,7 @@ mod gpos { use super::gsubgpos::*; use super::*; struct MarkRecord(Class); - //~^ ERROR`Class` is ambiguous + //~^ WARN`Class` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-5.stderr b/tests/ui/imports/ambiguous-5.stderr index 1fc5f4543f35..a4f3151c9e85 100644 --- a/tests/ui/imports/ambiguous-5.stderr +++ b/tests/ui/imports/ambiguous-5.stderr @@ -1,4 +1,4 @@ -error: `Class` is ambiguous +warning: `Class` is ambiguous --> $DIR/ambiguous-5.rs:12:23 | LL | struct MarkRecord(Class); @@ -19,12 +19,12 @@ note: `Class` could also refer to the struct imported here LL | use super::gsubgpos::*; | ^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Class` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `Class` is ambiguous +warning: `Class` is ambiguous --> $DIR/ambiguous-5.rs:12:23 | LL | struct MarkRecord(Class); @@ -45,5 +45,5 @@ note: `Class` could also refer to the struct imported here LL | use super::gsubgpos::*; | ^^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `Class` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-6.rs b/tests/ui/imports/ambiguous-6.rs index 1c6e34377165..9a3a138bda4c 100644 --- a/tests/ui/imports/ambiguous-6.rs +++ b/tests/ui/imports/ambiguous-6.rs @@ -1,10 +1,10 @@ //@ edition: 2021 // https://github.com/rust-lang/rust/issues/112713 - +//@ check-pass pub fn foo() -> u32 { use sub::*; C - //~^ ERROR `C` is ambiguous + //~^ WARN `C` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-6.stderr b/tests/ui/imports/ambiguous-6.stderr index 681bc40931f5..d811cfa4236a 100644 --- a/tests/ui/imports/ambiguous-6.stderr +++ b/tests/ui/imports/ambiguous-6.stderr @@ -1,4 +1,4 @@ -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/ambiguous-6.rs:6:5 | LL | C @@ -19,12 +19,12 @@ note: `C` could also refer to the constant imported here LL | pub use mod2::*; | ^^^^^^^ = help: consider adding an explicit import of `C` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted Future incompatibility report: Future breakage diagnostic: -error: `C` is ambiguous +warning: `C` is ambiguous --> $DIR/ambiguous-6.rs:6:5 | LL | C @@ -45,5 +45,5 @@ note: `C` could also refer to the constant imported here LL | pub use mod2::*; | ^^^^^^^ = help: consider adding an explicit import of `C` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-9.rs b/tests/ui/imports/ambiguous-9.rs index c10b1268060c..e6329b8d46ac 100644 --- a/tests/ui/imports/ambiguous-9.rs +++ b/tests/ui/imports/ambiguous-9.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/pull/113099#issuecomment-1638206152 - +//@ check-pass pub mod dsl { mod range { pub fn date_range() {} @@ -21,8 +21,8 @@ use prelude::*; fn main() { date_range(); - //~^ ERROR `date_range` is ambiguous + //~^ WARN `date_range` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - //~| ERROR `date_range` is ambiguous + //~| WARN `date_range` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-9.stderr b/tests/ui/imports/ambiguous-9.stderr index 800a2e10c9d7..da7d2d970fdd 100644 --- a/tests/ui/imports/ambiguous-9.stderr +++ b/tests/ui/imports/ambiguous-9.stderr @@ -8,7 +8,7 @@ LL | use super::prelude::*; | = note: `#[warn(ambiguous_glob_reexports)]` on by default -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -29,7 +29,7 @@ note: `date_range` could also refer to the function imported here LL | use super::prelude::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default warning: ambiguous glob re-exports --> $DIR/ambiguous-9.rs:15:13 @@ -39,7 +39,7 @@ LL | pub use self::t::*; LL | pub use super::dsl::*; | ------------- but the name `date_range` in the value namespace is also re-exported here -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -61,10 +61,10 @@ LL | use prelude::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate -error: aborting due to 2 previous errors; 2 warnings emitted +warning: 4 warnings emitted Future incompatibility report: Future breakage diagnostic: -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -85,10 +85,10 @@ note: `date_range` could also refer to the function imported here LL | use super::prelude::*; | ^^^^^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default Future breakage diagnostic: -error: `date_range` is ambiguous +warning: `date_range` is ambiguous --> $DIR/ambiguous-9.rs:23:5 | LL | date_range(); @@ -109,5 +109,5 @@ note: `date_range` could also refer to the function imported here LL | use prelude::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs new file mode 100644 index 000000000000..0277da46f750 --- /dev/null +++ b/tests/ui/imports/ambiguous-glob-vs-expanded-extern.rs @@ -0,0 +1,6 @@ +//@ check-pass +//@ aux-crate: glob_vs_expanded=glob-vs-expanded.rs + +fn main() { + glob_vs_expanded::mac!(); // OK +} diff --git a/tests/ui/imports/ambiguous-import-visibility-macro.rs b/tests/ui/imports/ambiguous-import-visibility-macro.rs new file mode 100644 index 000000000000..e1861cc5d4e0 --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-macro.rs @@ -0,0 +1,19 @@ +//@ check-pass +//@ edition:2018 +//@ proc-macro: same-res-ambigious-extern-macro.rs + +macro_rules! globbing{ + () => { + pub use same_res_ambigious_extern_macro::*; + } +} + +#[macro_use] // this imports the `RustEmbed` macro with `pub(crate)` visibility +extern crate same_res_ambigious_extern_macro; +globbing! {} // this imports the same `RustEmbed` macro with `pub` visibility + +pub trait RustEmbed {} + +pub use RustEmbed as Embed; //~ WARN ambiguous import visibility + //~| WARN this was previously accepted +fn main() {} diff --git a/tests/ui/imports/ambiguous-import-visibility-macro.stderr b/tests/ui/imports/ambiguous-import-visibility-macro.stderr new file mode 100644 index 000000000000..ed6eb6f893af --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-macro.stderr @@ -0,0 +1,29 @@ +warning: ambiguous import visibility: pub(crate) or pub + --> $DIR/ambiguous-import-visibility-macro.rs:17:9 + | +LL | pub use RustEmbed as Embed; + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #149145 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `RustEmbed` could refer to the derive macro imported here + --> $DIR/ambiguous-import-visibility-macro.rs:7:17 + | +LL | pub use same_res_ambigious_extern_macro::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | globbing! {} // this imports the same `RustEmbed` macro with `pub` visibility + | ------------ in this macro invocation + = help: consider adding an explicit import of `RustEmbed` to disambiguate + = help: or use `crate::RustEmbed` to refer to this derive macro unambiguously +note: `RustEmbed` could also refer to the derive macro imported here + --> $DIR/ambiguous-import-visibility-macro.rs:11:1 + | +LL | #[macro_use] // this imports the `RustEmbed` macro with `pub(crate)` visibility + | ^^^^^^^^^^^^ + = note: `#[warn(ambiguous_import_visibilities)]` (part of `#[warn(future_incompatible)]`) on by default + = note: this warning originates in the macro `globbing` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 1 warning emitted + diff --git a/tests/ui/imports/ambiguous-import-visibility-module.rs b/tests/ui/imports/ambiguous-import-visibility-module.rs new file mode 100644 index 000000000000..35c6da8b21a4 --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-module.rs @@ -0,0 +1,24 @@ +//@ check-pass +//@ edition:2018.. + +mod reexport { + mod m { + pub struct S {} + } + + macro_rules! mac { + () => { + use m::S; + }; + } + + pub use m::*; + mac!(); + + pub use S as Z; //~ WARN ambiguous import visibility + //~| WARN this was previously accepted +} + +fn main() { + reexport::Z {}; +} diff --git a/tests/ui/imports/ambiguous-import-visibility-module.stderr b/tests/ui/imports/ambiguous-import-visibility-module.stderr new file mode 100644 index 000000000000..a97070c20a62 --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility-module.stderr @@ -0,0 +1,29 @@ +warning: ambiguous import visibility: pub or pub(in crate::reexport) + --> $DIR/ambiguous-import-visibility-module.rs:18:13 + | +LL | pub use S as Z; + | ^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #149145 + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `S` could refer to the struct imported here + --> $DIR/ambiguous-import-visibility-module.rs:11:17 + | +LL | use m::S; + | ^^^^ +... +LL | mac!(); + | ------ in this macro invocation + = help: use `self::S` to refer to this struct unambiguously +note: `S` could also refer to the struct imported here + --> $DIR/ambiguous-import-visibility-module.rs:15:13 + | +LL | pub use m::*; + | ^^^^ + = help: use `self::S` to refer to this struct unambiguously + = note: `#[warn(ambiguous_import_visibilities)]` (part of `#[warn(future_incompatible)]`) on by default + = note: this warning originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 1 warning emitted + diff --git a/tests/ui/imports/ambiguous-import-visibility.rs b/tests/ui/imports/ambiguous-import-visibility.rs new file mode 100644 index 000000000000..4cb8b763fbc9 --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ edition:2018 +//@ proc-macro: same-res-ambigious-extern-macro.rs + +#[macro_use] // this imports the `RustEmbed` macro with `pub(crate)` visibility +extern crate same_res_ambigious_extern_macro; +// this imports the same `RustEmbed` macro with `pub` visibility +pub use same_res_ambigious_extern_macro::*; + +pub trait RustEmbed {} + +pub use RustEmbed as Embed; //~ WARN ambiguous import visibility + //~| WARN this was previously accepted +fn main() {} diff --git a/tests/ui/imports/ambiguous-import-visibility.stderr b/tests/ui/imports/ambiguous-import-visibility.stderr new file mode 100644 index 000000000000..30cddca4697d --- /dev/null +++ b/tests/ui/imports/ambiguous-import-visibility.stderr @@ -0,0 +1,25 @@ +warning: ambiguous import visibility: pub(crate) or pub + --> $DIR/ambiguous-import-visibility.rs:12:9 + | +LL | pub use RustEmbed as Embed; + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #149145 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `RustEmbed` could refer to the derive macro imported here + --> $DIR/ambiguous-import-visibility.rs:8:9 + | +LL | pub use same_res_ambigious_extern_macro::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `RustEmbed` to disambiguate + = help: or use `crate::RustEmbed` to refer to this derive macro unambiguously +note: `RustEmbed` could also refer to the derive macro imported here + --> $DIR/ambiguous-import-visibility.rs:5:1 + | +LL | #[macro_use] // this imports the `RustEmbed` macro with `pub(crate)` visibility + | ^^^^^^^^^^^^ + = note: `#[warn(ambiguous_import_visibilities)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs new file mode 100644 index 000000000000..6d37fbb7fdea --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.rs @@ -0,0 +1,16 @@ +//@ edition: 2024 +#![crate_type = "lib"] +mod m1 { + pub use core::prelude::v1::*; +} + +mod m2 { + pub use std::prelude::v1::*; +} + +use m2::*; +fn foo() { + use m1::*; + + panic!(); //~ ERROR: `panic` is ambiguous [E0659] +} diff --git a/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr new file mode 100644 index 000000000000..450a18478092 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-glob-vs-multiouter.stderr @@ -0,0 +1,23 @@ +error[E0659]: `panic` is ambiguous + --> $DIR/ambiguous-panic-glob-vs-multiouter.rs:15:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-glob-vs-multiouter.rs:13:9 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate +note: `panic` could also refer to the macro imported here + --> $DIR/ambiguous-panic-glob-vs-multiouter.rs:11:5 + | +LL | use m2::*; + | ^^^^^ + = help: use `crate::panic` to refer to this macro unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/ambiguous-panic-globvsglob.rs b/tests/ui/imports/ambiguous-panic-globvsglob.rs new file mode 100644 index 000000000000..335fba74b208 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-globvsglob.rs @@ -0,0 +1,23 @@ +//@ edition: 2024 +#![crate_type = "lib"] +mod m1 { + pub use core::prelude::v1::*; +} +//@ check-pass +mod m2 { + pub use std::prelude::v1::*; +} + +fn foo() { + use m1::*; + use m2::*; + + // I had hoped that this would not produce the globvsglob error because it would never be + // resolving `panic` via one of the ambiguous glob imports above but it appears to do so, not + // sure why + panic!(); + //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports] + //~| WARN: this was previously accepted by the compiler + //~| WARN: `panic` is ambiguous [ambiguous_glob_imports] + //~| WARN: this was previously accepted by the compiler +} diff --git a/tests/ui/imports/ambiguous-panic-globvsglob.stderr b/tests/ui/imports/ambiguous-panic-globvsglob.stderr new file mode 100644 index 000000000000..8e216b21734f --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-globvsglob.stderr @@ -0,0 +1,68 @@ +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-globvsglob.rs:18:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-globvsglob.rs:12:9 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate +note: `panic` could also refer to the macro imported here + --> $DIR/ambiguous-panic-globvsglob.rs:13:9 + | +LL | use m2::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-globvsglob.rs:18:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147319 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-globvsglob.rs:12:9 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 2 warnings emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-globvsglob.rs:18:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-globvsglob.rs:12:9 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate +note: `panic` could also refer to the macro imported here + --> $DIR/ambiguous-panic-globvsglob.rs:13:9 + | +LL | use m2::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs new file mode 100644 index 000000000000..1239cc67cd39 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.rs @@ -0,0 +1,16 @@ +//@ edition: 2024 +#![crate_type = "lib"] +#![no_implicit_prelude] + +mod m1 { + macro_rules! panic { + () => {}; + } + + pub(crate) use panic; +} + +fn foo() { + use m1::*; + panic!(); //~ERROR: `panic` is ambiguous [E0659] +} diff --git a/tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr new file mode 100644 index 000000000000..fa41409acb2c --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-no-implicit-prelude.stderr @@ -0,0 +1,19 @@ +error[E0659]: `panic` is ambiguous + --> $DIR/ambiguous-panic-no-implicit-prelude.rs:15:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-no-implicit-prelude.rs:14:9 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs new file mode 100644 index 000000000000..e8b6e208c08b --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.rs @@ -0,0 +1,11 @@ +//@ edition: 2024 +//@ check-pass +#![crate_type = "lib"] + +use ::core::*; + +fn f() { + panic!(); + //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr new file mode 100644 index 000000000000..5317d8d6d312 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-non-prelude-core-glob.stderr @@ -0,0 +1,22 @@ +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-non-prelude-core-glob.rs:8:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147319 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-non-prelude-core-glob.rs:5:5 + | +LL | use ::core::*; + | ^^^^^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = help: or use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs new file mode 100644 index 000000000000..0e63f97ec98a --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.rs @@ -0,0 +1,12 @@ +//@ check-pass +#![crate_type = "lib"] +#![no_std] + +extern crate std; +use ::std::*; + +fn f() { + panic!(); + //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} diff --git a/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr new file mode 100644 index 000000000000..b7434e3737b8 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-non-prelude-std-glob.stderr @@ -0,0 +1,22 @@ +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-non-prelude-std-glob.rs:9:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147319 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-non-prelude-std-glob.rs:6:5 + | +LL | use ::std::*; + | ^^^^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = help: or use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL + = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/ambiguous-panic-pick-core.rs b/tests/ui/imports/ambiguous-panic-pick-core.rs new file mode 100644 index 000000000000..bcb8494b10d7 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-pick-core.rs @@ -0,0 +1,11 @@ +//@ edition: 2018 +//@ check-pass +#![crate_type = "lib"] +use ::core::prelude::v1::*; + +fn f() { + panic!(&std::string::String::new()); + //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~| WARN: panic message is not a string literal [non_fmt_panics] +} diff --git a/tests/ui/imports/ambiguous-panic-pick-core.stderr b/tests/ui/imports/ambiguous-panic-pick-core.stderr new file mode 100644 index 000000000000..5729311fabd0 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-pick-core.stderr @@ -0,0 +1,37 @@ +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-pick-core.rs:7:5 + | +LL | panic!(&std::string::String::new()); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147319 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-pick-core.rs:4:5 + | +LL | use ::core::prelude::v1::*; + | ^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = help: or use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: panic message is not a string literal + --> $DIR/ambiguous-panic-pick-core.rs:7:12 + | +LL | panic!(&std::string::String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 + = note: for more information, see + = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: add a "{}" format string to `Display` the message + | +LL | panic!("{}", &std::string::String::new()); + | +++++ + +warning: 2 warnings emitted + diff --git a/tests/ui/imports/ambiguous-panic-pick-std.rs b/tests/ui/imports/ambiguous-panic-pick-std.rs new file mode 100644 index 000000000000..67b285ee430a --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-pick-std.rs @@ -0,0 +1,14 @@ +//@ edition: 2018 +//@ check-pass +#![crate_type = "lib"] +#![no_std] + +extern crate std; +use ::std::prelude::v1::*; + +fn f() { + panic!(std::string::String::new()); + //~^ WARN: `panic` is ambiguous [ambiguous_panic_imports] + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~| WARN: panic message is not a string literal [non_fmt_panics] +} diff --git a/tests/ui/imports/ambiguous-panic-pick-std.stderr b/tests/ui/imports/ambiguous-panic-pick-std.stderr new file mode 100644 index 000000000000..1b5b508a7965 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-pick-std.stderr @@ -0,0 +1,37 @@ +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-pick-std.rs:10:5 + | +LL | panic!(std::string::String::new()); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147319 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-pick-std.rs:7:5 + | +LL | use ::std::prelude::v1::*; + | ^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = help: or use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL + = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: panic message is not a string literal + --> $DIR/ambiguous-panic-pick-std.rs:10:12 + | +LL | panic!(std::string::String::new()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see + = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 + = note: for more information, see + = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: add a "{}" format string to `Display` the message + | +LL | panic!("{}", std::string::String::new()); + | +++++ + +warning: 2 warnings emitted + diff --git a/tests/ui/imports/ambiguous-panic-re-emit.rs b/tests/ui/imports/ambiguous-panic-re-emit.rs new file mode 100644 index 000000000000..dd3c0211b3a7 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-re-emit.rs @@ -0,0 +1,23 @@ +#![crate_type = "lib"] +#![no_std] + +macro_rules! re_emit { + ($($i:item)*) => ($($i)*) +} + +// By re-emitting the prelude import via a macro, we run into the delayed bugs code path. +re_emit! { + extern crate std; + use std::prelude::v1::*; +} + +fn xx() { + panic!(); + //~^ WARNING `panic` is ambiguous + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + + // We can't deny the above lint, or else it *won't* run into the problematic issue of *not* + // having reported an error. So we crate a dummy error. + let _ = unknown_item; + //~^ ERROR: cannot find value `unknown_item` +} diff --git a/tests/ui/imports/ambiguous-panic-re-emit.stderr b/tests/ui/imports/ambiguous-panic-re-emit.stderr new file mode 100644 index 000000000000..ca30c54b84fe --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-re-emit.stderr @@ -0,0 +1,29 @@ +error[E0425]: cannot find value `unknown_item` in this scope + --> $DIR/ambiguous-panic-re-emit.rs:21:13 + | +LL | let _ = unknown_item; + | ^^^^^^^^^^^^ not found in this scope + +warning: `panic` is ambiguous + --> $DIR/ambiguous-panic-re-emit.rs:15:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147319 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-re-emit.rs:11:9 + | +LL | use std::prelude::v1::*; + | ^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = help: or use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL + = note: `#[warn(ambiguous_panic_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/ambiguous-panic-rename-builtin.rs b/tests/ui/imports/ambiguous-panic-rename-builtin.rs new file mode 100644 index 000000000000..63dfa540c2a2 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-rename-builtin.rs @@ -0,0 +1,15 @@ +//@ edition: 2024 +#![crate_type = "lib"] +#![no_std] + +extern crate std; +mod m1 { + pub use std::prelude::v1::env as panic; +} +use m1::*; + +fn xx() { + panic!(); + //~^ ERROR: `env!()` takes 1 or 2 arguments + //~| ERROR: `panic` is ambiguous [E0659] +} diff --git a/tests/ui/imports/ambiguous-panic-rename-builtin.stderr b/tests/ui/imports/ambiguous-panic-rename-builtin.stderr new file mode 100644 index 000000000000..146863762eaf --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-rename-builtin.stderr @@ -0,0 +1,26 @@ +error: `env!()` takes 1 or 2 arguments + --> $DIR/ambiguous-panic-rename-builtin.rs:12:5 + | +LL | panic!(); + | ^^^^^^^^ + +error[E0659]: `panic` is ambiguous + --> $DIR/ambiguous-panic-rename-builtin.rs:12:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic-rename-builtin.rs:9:5 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = help: or use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/ambiguous-panic-rename-panics.rs b/tests/ui/imports/ambiguous-panic-rename-panics.rs new file mode 100644 index 000000000000..fbe23a223c93 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-rename-panics.rs @@ -0,0 +1,17 @@ +//@ edition: 2024 +#![crate_type = "lib"] + +mod m1 { + pub use core::prelude::v1::panic as p; +} + +mod m2 { + pub use std::prelude::v1::panic as p; +} + +use m2::*; +fn xx() { + use m1::*; + + p!(); //~ ERROR: `p` is ambiguous [E0659] +} diff --git a/tests/ui/imports/ambiguous-panic-rename-panics.stderr b/tests/ui/imports/ambiguous-panic-rename-panics.stderr new file mode 100644 index 000000000000..0838b6bdf2c0 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic-rename-panics.stderr @@ -0,0 +1,23 @@ +error[E0659]: `p` is ambiguous + --> $DIR/ambiguous-panic-rename-panics.rs:16:5 + | +LL | p!(); + | ^ ambiguous name + | + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `p` could refer to the macro imported here + --> $DIR/ambiguous-panic-rename-panics.rs:14:9 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `p` to disambiguate +note: `p` could also refer to the macro imported here + --> $DIR/ambiguous-panic-rename-panics.rs:12:5 + | +LL | use m2::*; + | ^^^^^ + = help: use `crate::p` to refer to this macro unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/ambiguous-panic.rs b/tests/ui/imports/ambiguous-panic.rs new file mode 100644 index 000000000000..5a32fe22f31b --- /dev/null +++ b/tests/ui/imports/ambiguous-panic.rs @@ -0,0 +1,12 @@ +#![deny(ambiguous_panic_imports)] +#![crate_type = "lib"] +#![no_std] + +extern crate std; +use std::prelude::v1::*; + +fn xx() { + panic!(); + //~^ ERROR `panic` is ambiguous + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} diff --git a/tests/ui/imports/ambiguous-panic.stderr b/tests/ui/imports/ambiguous-panic.stderr new file mode 100644 index 000000000000..781424eede48 --- /dev/null +++ b/tests/ui/imports/ambiguous-panic.stderr @@ -0,0 +1,26 @@ +error: `panic` is ambiguous + --> $DIR/ambiguous-panic.rs:9:5 + | +LL | panic!(); + | ^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147319 + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution +note: `panic` could refer to the macro imported here + --> $DIR/ambiguous-panic.rs:6:5 + | +LL | use std::prelude::v1::*; + | ^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `panic` to disambiguate + = help: or use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/core/src/prelude/mod.rs:LL:COL +note: the lint level is defined here + --> $DIR/ambiguous-panic.rs:1:9 + | +LL | #![deny(ambiguous_panic_imports)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/ambiguous-reachable.rs b/tests/ui/imports/ambiguous-reachable.rs new file mode 100644 index 000000000000..fc92315622aa --- /dev/null +++ b/tests/ui/imports/ambiguous-reachable.rs @@ -0,0 +1,8 @@ +//@ build-pass +//@ aux-crate: ambiguous_reachable_extern=ambiguous-reachable-extern.rs + +#![allow(ambiguous_glob_imports)] + +fn main() { + ambiguous_reachable_extern::generic::(); +} diff --git a/tests/ui/imports/ambiguous-reachable.stderr b/tests/ui/imports/ambiguous-reachable.stderr new file mode 100644 index 000000000000..78a0d76d68b5 --- /dev/null +++ b/tests/ui/imports/ambiguous-reachable.stderr @@ -0,0 +1,23 @@ +Future incompatibility report: Future breakage diagnostic: +warning: `generic` is ambiguous + --> $DIR/ambiguous-reachable.rs:7:33 + | +LL | ambiguous_reachable_extern::generic::(); + | ^^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `generic` could refer to the function defined here + --> $DIR/auxiliary/ambiguous-reachable-extern.rs:13:9 + | +LL | pub use m1::*; + | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `generic` could also refer to the function defined here + --> $DIR/auxiliary/ambiguous-reachable-extern.rs:14:9 + | +LL | pub use m2::*; + | ^^ + diff --git a/tests/ui/imports/ambiguous-trait-in-scope.rs b/tests/ui/imports/ambiguous-trait-in-scope.rs new file mode 100644 index 000000000000..d12276297396 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-in-scope.rs @@ -0,0 +1,84 @@ +//@ edition:2018 +//@ aux-crate:external=ambiguous-trait-reexport.rs + +mod m1 { + pub trait Trait { + fn method1(&self) {} + } + impl Trait for u8 {} +} +mod m2 { + pub trait Trait { + fn method2(&self) {} + } + impl Trait for u8 {} +} +mod m1_reexport { + pub use crate::m1::Trait; +} +mod m2_reexport { + pub use crate::m2::Trait; +} + +mod ambig_reexport { + pub use crate::m1::*; + pub use crate::m2::*; +} + +fn test1() { + // Create an ambiguous import for `Trait` in one order + use m1::*; + use m2::*; + 0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + 0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope +} + +fn test2() { + // Create an ambiguous import for `Trait` in another order + use m2::*; + use m1::*; + 0u8.method1(); //~ ERROR: no method named `method1` found for type `u8` in the current scope + 0u8.method2(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} + +fn test_indirect_reexport() { + use m1_reexport::*; + use m2_reexport::*; + 0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + 0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope +} + +fn test_ambig_reexport() { + use ambig_reexport::*; + 0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + 0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope +} + +fn test_external() { + use external::m1::*; + use external::m2::*; + 0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + 0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope +} + +fn test_external_indirect_reexport() { + use external::m1_reexport::*; + use external::m2_reexport::*; + 0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + 0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope +} + +fn test_external_ambig_reexport() { + use external::ambig_reexport::*; + 0u8.method1(); //~ WARNING Use of ambiguously glob imported trait `Trait` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + 0u8.method2(); //~ ERROR: no method named `method2` found for type `u8` in the current scope +} + +fn main() {} diff --git a/tests/ui/imports/ambiguous-trait-in-scope.stderr b/tests/ui/imports/ambiguous-trait-in-scope.stderr new file mode 100644 index 000000000000..cac1f4bb73fb --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-in-scope.stderr @@ -0,0 +1,191 @@ +warning: Use of ambiguously glob imported trait `Trait` + --> $DIR/ambiguous-trait-in-scope.rs:32:9 + | +LL | use m1::*; + | -- `Trait` imported ambiguously here +LL | use m2::*; +LL | 0u8.method1(); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147992 + = help: Import `Trait` explicitly + = note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default + +error[E0599]: no method named `method2` found for type `u8` in the current scope + --> $DIR/ambiguous-trait-in-scope.rs:34:9 + | +LL | 0u8.method2(); + | ^^^^^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them + | +LL + use ambiguous_trait_reexport::m2::Trait; + | +LL + use crate::m2::Trait; + | + +error[E0599]: no method named `method1` found for type `u8` in the current scope + --> $DIR/ambiguous-trait-in-scope.rs:41:9 + | +LL | 0u8.method1(); + | ^^^^^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `method1` are implemented but not in scope; perhaps you want to import one of them + | +LL + use ambiguous_trait_reexport::m1::Trait; + | +LL + use crate::m1::Trait; + | + +warning: Use of ambiguously glob imported trait `Trait` + --> $DIR/ambiguous-trait-in-scope.rs:42:9 + | +LL | use m2::*; + | -- `Trait` imported ambiguously here +... +LL | 0u8.method2(); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147992 + = help: Import `Trait` explicitly + +warning: Use of ambiguously glob imported trait `Trait` + --> $DIR/ambiguous-trait-in-scope.rs:49:9 + | +LL | use m1_reexport::*; + | ----------- `Trait` imported ambiguously here +LL | use m2_reexport::*; +LL | 0u8.method1(); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147992 + = help: Import `Trait` explicitly + +error[E0599]: no method named `method2` found for type `u8` in the current scope + --> $DIR/ambiguous-trait-in-scope.rs:51:9 + | +LL | 0u8.method2(); + | ^^^^^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them + | +LL + use ambiguous_trait_reexport::m2::Trait; + | +LL + use crate::m2::Trait; + | + +warning: Use of ambiguously glob imported trait `Trait` + --> $DIR/ambiguous-trait-in-scope.rs:56:9 + | +LL | use ambig_reexport::*; + | -------------- `Trait` imported ambiguously here +LL | 0u8.method1(); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147992 + = help: Import `Trait` explicitly + +error[E0599]: no method named `method2` found for type `u8` in the current scope + --> $DIR/ambiguous-trait-in-scope.rs:58:9 + | +LL | 0u8.method2(); + | ^^^^^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them + | +LL + use ambiguous_trait_reexport::m2::Trait; + | +LL + use crate::m2::Trait; + | + +warning: Use of ambiguously glob imported trait `Trait` + --> $DIR/ambiguous-trait-in-scope.rs:64:9 + | +LL | use external::m1::*; + | ------------ `Trait` imported ambiguously here +LL | use external::m2::*; +LL | 0u8.method1(); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147992 + = help: Import `Trait` explicitly + +error[E0599]: no method named `method2` found for type `u8` in the current scope + --> $DIR/ambiguous-trait-in-scope.rs:66:9 + | +LL | 0u8.method2(); + | ^^^^^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them + | +LL + use ambiguous_trait_reexport::m2::Trait; + | +LL + use crate::m2::Trait; + | + +warning: Use of ambiguously glob imported trait `Trait` + --> $DIR/ambiguous-trait-in-scope.rs:72:9 + | +LL | use external::m1_reexport::*; + | --------------------- `Trait` imported ambiguously here +LL | use external::m2_reexport::*; +LL | 0u8.method1(); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147992 + = help: Import `Trait` explicitly + +error[E0599]: no method named `method2` found for type `u8` in the current scope + --> $DIR/ambiguous-trait-in-scope.rs:74:9 + | +LL | 0u8.method2(); + | ^^^^^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them + | +LL + use ambiguous_trait_reexport::m2::Trait; + | +LL + use crate::m2::Trait; + | + +warning: Use of ambiguously glob imported trait `Trait` + --> $DIR/ambiguous-trait-in-scope.rs:79:9 + | +LL | use external::ambig_reexport::*; + | ------------------------ `Trait` imported ambiguously here +LL | 0u8.method1(); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #147992 + = help: Import `Trait` explicitly + +error[E0599]: no method named `method2` found for type `u8` in the current scope + --> $DIR/ambiguous-trait-in-scope.rs:81:9 + | +LL | 0u8.method2(); + | ^^^^^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `method2` are implemented but not in scope; perhaps you want to import one of them + | +LL + use ambiguous_trait_reexport::m2::Trait; + | +LL + use crate::m2::Trait; + | + +error: aborting due to 7 previous errors; 7 warnings emitted + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/imports/auxiliary/ambiguous-reachable-extern.rs b/tests/ui/imports/auxiliary/ambiguous-reachable-extern.rs new file mode 100644 index 000000000000..af81812560e3 --- /dev/null +++ b/tests/ui/imports/auxiliary/ambiguous-reachable-extern.rs @@ -0,0 +1,14 @@ +mod m1 { + pub fn generic() { + let x = 10; + let y = 11; + println!("hello {x} world {:?}", y); + } +} + +mod m2 { + pub fn generic() {} +} + +pub use m1::*; +pub use m2::*; diff --git a/tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs b/tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs new file mode 100644 index 000000000000..77fb0c7d3934 --- /dev/null +++ b/tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs @@ -0,0 +1,23 @@ +pub mod m1 { + pub trait Trait { + fn method1(&self) {} + } + impl Trait for u8 {} +} +pub mod m2 { + pub trait Trait { + fn method2(&self) {} + } + impl Trait for u8 {} +} +pub mod m1_reexport { + pub use crate::m1::Trait; +} +pub mod m2_reexport { + pub use crate::m2::Trait; +} + +pub mod ambig_reexport { + pub use crate::m1::*; + pub use crate::m2::*; +} diff --git a/tests/ui/imports/auxiliary/glob-vs-expanded.rs b/tests/ui/imports/auxiliary/glob-vs-expanded.rs new file mode 100644 index 000000000000..fcbe54f73264 --- /dev/null +++ b/tests/ui/imports/auxiliary/glob-vs-expanded.rs @@ -0,0 +1,11 @@ +#![feature(decl_macro)] + +// Glob import in macro namespace +mod inner { pub macro mac() {} } +pub use inner::*; + +// Macro-expanded single import in macro namespace +macro_rules! define_mac { + () => { pub macro mac() {} } +} +define_mac!(); diff --git a/tests/ui/imports/duplicate-empty-imports.rs b/tests/ui/imports/duplicate-empty-imports.rs new file mode 100644 index 000000000000..7768dcfbbdac --- /dev/null +++ b/tests/ui/imports/duplicate-empty-imports.rs @@ -0,0 +1,7 @@ +//! regression test for issue #47673 +//@ check-pass +#![allow(unused_imports)] + +use {{}, {}}; + +fn main() {} diff --git a/tests/ui/imports/duplicate.rs b/tests/ui/imports/duplicate.rs index 0a652889ca8a..ef54726c9a93 100644 --- a/tests/ui/imports/duplicate.rs +++ b/tests/ui/imports/duplicate.rs @@ -34,7 +34,7 @@ fn main() { e::foo(); f::foo(); //~ ERROR `foo` is ambiguous g::foo(); - //~^ ERROR `foo` is ambiguous + //~^ WARN `foo` is ambiguous //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/duplicate.stderr b/tests/ui/imports/duplicate.stderr index 5cd3b0c2c8a5..9252a041749d 100644 --- a/tests/ui/imports/duplicate.stderr +++ b/tests/ui/imports/duplicate.stderr @@ -68,7 +68,7 @@ LL | use self::m2::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/duplicate.rs:36:8 | LL | g::foo(); @@ -78,25 +78,25 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:24:13 + --> $DIR/duplicate.rs:29:13 | LL | pub use crate::a::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:25:13 + --> $DIR/duplicate.rs:30:13 | -LL | pub use crate::b::*; +LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0252, E0659. For more information about an error, try `rustc --explain E0252`. Future incompatibility report: Future breakage diagnostic: -error: `foo` is ambiguous +warning: `foo` is ambiguous --> $DIR/duplicate.rs:36:8 | LL | g::foo(); @@ -106,16 +106,16 @@ LL | g::foo(); = note: for more information, see issue #114095 = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:24:13 + --> $DIR/duplicate.rs:29:13 | LL | pub use crate::a::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:25:13 + --> $DIR/duplicate.rs:30:13 | -LL | pub use crate::b::*; +LL | pub use crate::f::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/imports/extern-prelude-extern-crate-fail.rs b/tests/ui/imports/extern-prelude-extern-crate-fail.rs index 84751ecc02b6..7412706dcf39 100644 --- a/tests/ui/imports/extern-prelude-extern-crate-fail.rs +++ b/tests/ui/imports/extern-prelude-extern-crate-fail.rs @@ -7,7 +7,7 @@ mod n { mod m { fn check() { - two_macros::m!(); //~ ERROR failed to resolve: use of unresolved module or unlinked crate `two_macros` + two_macros::m!(); //~ ERROR cannot find } } diff --git a/tests/ui/imports/extern-prelude-extern-crate-fail.stderr b/tests/ui/imports/extern-prelude-extern-crate-fail.stderr index ec53730afa02..42735ff90c90 100644 --- a/tests/ui/imports/extern-prelude-extern-crate-fail.stderr +++ b/tests/ui/imports/extern-prelude-extern-crate-fail.stderr @@ -9,7 +9,7 @@ LL | define_std_as_non_existent!(); | = note: this error originates in the macro `define_std_as_non_existent` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `two_macros` +error[E0433]: cannot find module or crate `two_macros` in this scope --> $DIR/extern-prelude-extern-crate-fail.rs:10:9 | LL | two_macros::m!(); diff --git a/tests/ui/imports/extern-with-ambiguous-2.rs b/tests/ui/imports/extern-with-ambiguous-2.rs index dcab2bcc18ea..477d29ad0120 100644 --- a/tests/ui/imports/extern-with-ambiguous-2.rs +++ b/tests/ui/imports/extern-with-ambiguous-2.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ edition: 2021 //@ aux-build: extern-with-ambiguous-2-extern.rs @@ -11,8 +10,6 @@ mod s { } use s::*; use extern_with_ambiguous_2_extern::*; -use error::*; -//^ FIXME: An ambiguity error should be thrown for `error`, -// as there is ambiguity present within `extern-with-ambiguous-2-extern.rs`. +use error::*; //~ ERROR `error` is ambiguous fn main() {} diff --git a/tests/ui/imports/extern-with-ambiguous-2.stderr b/tests/ui/imports/extern-with-ambiguous-2.stderr new file mode 100644 index 000000000000..2fd66932e4ed --- /dev/null +++ b/tests/ui/imports/extern-with-ambiguous-2.stderr @@ -0,0 +1,23 @@ +error[E0659]: `error` is ambiguous + --> $DIR/extern-with-ambiguous-2.rs:13:5 + | +LL | use error::*; + | ^^^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `error` could refer to the module imported here + --> $DIR/extern-with-ambiguous-2.rs:11:5 + | +LL | use s::*; + | ^^^^ + = help: consider adding an explicit import of `error` to disambiguate +note: `error` could also refer to the module imported here + --> $DIR/extern-with-ambiguous-2.rs:12:5 + | +LL | use extern_with_ambiguous_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `error` to disambiguate + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/extern-with-ambiguous-3.rs b/tests/ui/imports/extern-with-ambiguous-3.rs index c65fedbe2c1d..c0c4741ec56a 100644 --- a/tests/ui/imports/extern-with-ambiguous-3.rs +++ b/tests/ui/imports/extern-with-ambiguous-3.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ edition: 2021 //@ aux-build: extern-with-ambiguous-3-extern.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1643974121 @@ -12,8 +11,6 @@ mod s { } use s::*; use extern_with_ambiguous_3_extern::*; -use error::*; -//^ FIXME: An ambiguity error should be thrown for `error`, -// as there is ambiguity present within `extern-with-ambiguous-3-extern.rs`. +use error::*; //~ ERROR `error` is ambiguous fn main() {} diff --git a/tests/ui/imports/extern-with-ambiguous-3.stderr b/tests/ui/imports/extern-with-ambiguous-3.stderr new file mode 100644 index 000000000000..95a1175c56b3 --- /dev/null +++ b/tests/ui/imports/extern-with-ambiguous-3.stderr @@ -0,0 +1,23 @@ +error[E0659]: `error` is ambiguous + --> $DIR/extern-with-ambiguous-3.rs:14:5 + | +LL | use error::*; + | ^^^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `error` could refer to the module imported here + --> $DIR/extern-with-ambiguous-3.rs:12:5 + | +LL | use s::*; + | ^^^^ + = help: consider adding an explicit import of `error` to disambiguate +note: `error` could also refer to the module imported here + --> $DIR/extern-with-ambiguous-3.rs:13:5 + | +LL | use extern_with_ambiguous_3_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `error` to disambiguate + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs index 6e3200329616..787fa36db2d9 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -1,13 +1,11 @@ //@ edition:2015 //@ aux-build:glob-conflict.rs - +//@ check-pass extern crate glob_conflict; fn main() { - glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` - //^ FIXME: `glob_conflict::f` should raise an - // ambiguity error instead of a not found error. - glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` - //^ FIXME: `glob_conflict::glob::f` should raise an - // ambiguity error instead of a not found error. + glob_conflict::f(); //~ WARN `f` is ambiguous + //~| WARN this was previously accepted + glob_conflict::glob::f(); //~ WARN `f` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr index cf40076ecb86..4eb27729b41a 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-1.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -1,15 +1,95 @@ -error[E0425]: cannot find function `f` in crate `glob_conflict` +warning: `f` is ambiguous --> $DIR/glob-conflict-cross-crate-1.rs:7:20 | LL | glob_conflict::f(); - | ^ not found in `glob_conflict` + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error[E0425]: cannot find function `f` in module `glob_conflict::glob` - --> $DIR/glob-conflict-cross-crate-1.rs:10:26 +warning: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:9:26 | LL | glob_conflict::glob::f(); - | ^ not found in `glob_conflict::glob` + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ -error: aborting due to 2 previous errors +warning: 2 warnings emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:7:20 + | +LL | glob_conflict::f(); + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +Future breakage diagnostic: +warning: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:9:26 + | +LL | glob_conflict::glob::f(); + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:12:9 + | +LL | pub use m1::*; + | ^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `f` could also refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:13:9 + | +LL | pub use m2::*; + | ^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.rs b/tests/ui/imports/glob-conflict-cross-crate-2.rs index b764685dd579..018a74d35d7f 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-2.rs @@ -1,10 +1,10 @@ //@ aux-build:glob-conflict-cross-crate-2-extern.rs - +//@ check-pass extern crate glob_conflict_cross_crate_2_extern; use glob_conflict_cross_crate_2_extern::*; fn main() { - let _a: C = 1; //~ ERROR cannot find type `C` in this scope - //^ FIXME: `C` should be identified as an ambiguous item. + let _a: C = 1; //~ WARN `C` is ambiguous + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.stderr b/tests/ui/imports/glob-conflict-cross-crate-2.stderr index 41912ed63f42..6ff36477e45f 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-2.stderr +++ b/tests/ui/imports/glob-conflict-cross-crate-2.stderr @@ -1,9 +1,49 @@ -error[E0425]: cannot find type `C` in this scope +warning: `C` is ambiguous --> $DIR/glob-conflict-cross-crate-2.rs:8:13 | LL | let _a: C = 1; - | ^ not found in this scope + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 1 previous error +warning: 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-2.rs:8:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.rs b/tests/ui/imports/glob-conflict-cross-crate-3.rs index 7797b5b7c069..a7b215359090 100644 --- a/tests/ui/imports/glob-conflict-cross-crate-3.rs +++ b/tests/ui/imports/glob-conflict-cross-crate-3.rs @@ -1,6 +1,5 @@ -//@ check-pass //@ aux-build:glob-conflict-cross-crate-2-extern.rs - +//@ check-pass extern crate glob_conflict_cross_crate_2_extern; mod a { @@ -12,5 +11,8 @@ use a::*; fn main() { let _a: C = 1; - //^ FIXME: `C` should be identified as an ambiguous item. + //~^ WARN `C` is ambiguous + //~| WARN `C` is ambiguous + //~| WARN this was previously accepted + //~| WARN this was previously accepted } diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.stderr b/tests/ui/imports/glob-conflict-cross-crate-3.stderr new file mode 100644 index 000000000000..9b6867774ebe --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-3.stderr @@ -0,0 +1,95 @@ +warning: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:9:5 + | +LL | use glob_conflict_cross_crate_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `C` to disambiguate +note: `C` could also refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:10:5 + | +LL | use a::*; + | ^^^^ + = help: consider adding an explicit import of `C` to disambiguate + +warning: 2 warnings emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `C` could also refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +Future breakage diagnostic: +warning: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:13:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:9:5 + | +LL | use glob_conflict_cross_crate_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `C` to disambiguate +note: `C` could also refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:10:5 + | +LL | use a::*; + | ^^^^ + = help: consider adding an explicit import of `C` to disambiguate + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/glob-resolve1.stderr b/tests/ui/imports/glob-resolve1.stderr index 1356255a0850..5e02c933836d 100644 --- a/tests/ui/imports/glob-resolve1.stderr +++ b/tests/ui/imports/glob-resolve1.stderr @@ -75,13 +75,18 @@ LL | pub enum B { | ---------- similarly named enum `B` defined here ... LL | foo::(); - | ^ help: an enum with a similar name exists: `B` + | ^ | note: enum `bar::A` exists but is inaccessible --> $DIR/glob-resolve1.rs:12:5 | LL | enum A { | ^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - foo::(); +LL + foo::(); + | error[E0425]: cannot find type `C` in this scope --> $DIR/glob-resolve1.rs:34:11 @@ -90,13 +95,18 @@ LL | pub enum B { | ---------- similarly named enum `B` defined here ... LL | foo::(); - | ^ help: an enum with a similar name exists: `B` + | ^ | note: struct `bar::C` exists but is inaccessible --> $DIR/glob-resolve1.rs:19:5 | LL | struct C; | ^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - foo::(); +LL + foo::(); + | error[E0425]: cannot find type `D` in this scope --> $DIR/glob-resolve1.rs:35:11 @@ -105,13 +115,18 @@ LL | pub enum B { | ---------- similarly named enum `B` defined here ... LL | foo::(); - | ^ help: an enum with a similar name exists: `B` + | ^ | note: type alias `bar::D` exists but is inaccessible --> $DIR/glob-resolve1.rs:21:5 | LL | type D = isize; | ^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - foo::(); +LL + foo::(); + | error: aborting due to 8 previous errors diff --git a/tests/ui/imports/glob-shadowing.stderr b/tests/ui/imports/glob-shadowing.stderr index 0ce8d4f54f8d..025147d08f01 100644 --- a/tests/ui/imports/glob-shadowing.stderr +++ b/tests/ui/imports/glob-shadowing.stderr @@ -5,14 +5,15 @@ LL | let x = env!("PATH"); | ^^^ ambiguous name | = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution - = note: `env` could refer to a macro from prelude -note: `env` could also refer to the macro imported here +note: `env` could refer to the macro imported here --> $DIR/glob-shadowing.rs:9:9 | LL | use crate::m::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `env` to disambiguate = help: or use `self::env` to refer to this macro unambiguously +note: `env` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL error[E0659]: `env` is ambiguous --> $DIR/glob-shadowing.rs:19:21 @@ -21,13 +22,14 @@ LL | let x = env!("PATH"); | ^^^ ambiguous name | = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution - = note: `env` could refer to a macro from prelude -note: `env` could also refer to the macro imported here +note: `env` could refer to the macro imported here --> $DIR/glob-shadowing.rs:17:13 | LL | use crate::m::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `env` to disambiguate +note: `env` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL error[E0659]: `fenv` is ambiguous --> $DIR/glob-shadowing.rs:29:21 diff --git a/tests/ui/imports/issue-114682-1.stderr b/tests/ui/imports/issue-114682-1.stderr index 85fb7f7919e4..fd2776f50ad7 100644 --- a/tests/ui/imports/issue-114682-1.stderr +++ b/tests/ui/imports/issue-114682-1.stderr @@ -4,7 +4,7 @@ error[E0659]: `A` is ambiguous LL | A!(); | ^ ambiguous name | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `A` could refer to the macro defined here --> $DIR/issue-114682-1.rs:7:9 | @@ -15,12 +15,13 @@ LL | | } ... LL | mac!(); | ------ in this macro invocation + = help: use `crate::A` to refer to this macro unambiguously note: `A` could also refer to the macro imported here --> $DIR/issue-114682-1.rs:19:9 | LL | pub use m::*; | ^^^^ - = help: consider adding an explicit import of `A` to disambiguate + = help: use `crate::A` to refer to this macro unambiguously = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/imports/issue-114682-2.rs b/tests/ui/imports/issue-114682-2.rs index e99bcf77ab62..da145f3addc0 100644 --- a/tests/ui/imports/issue-114682-2.rs +++ b/tests/ui/imports/issue-114682-2.rs @@ -1,19 +1,12 @@ //@ aux-build: issue-114682-2-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1879998900 - +//@ check-pass extern crate issue_114682_2_extern; -use issue_114682_2_extern::max; +use issue_114682_2_extern::max; //~ WARN `max` is ambiguous + //~| WARN this was previously accepted -type A = issue_114682_2_extern::max; -//~^ ERROR: expected type, found function `issue_114682_2_extern::max` -// FIXME: -// The above error was emitted due to `(Mod(issue_114682_2_extern), Namespace(Type), Ident(max))` -// being identified as an ambiguous item. -// However, there are two points worth discussing: -// First, should this ambiguous item be omitted considering the maximum visibility -// of `issue_114682_2_extern::m::max` in the type namespace is only within the extern crate. -// Second, if we retain the ambiguous item of the extern crate, should it be treated -// as an ambiguous item within the local crate for the same reasoning? +type A = issue_114682_2_extern::max; //~ WARN `max` is ambiguous + //~| WARN this was previously accepted fn main() {} diff --git a/tests/ui/imports/issue-114682-2.stderr b/tests/ui/imports/issue-114682-2.stderr index 972bcecb56bc..92fac9f0a424 100644 --- a/tests/ui/imports/issue-114682-2.stderr +++ b/tests/ui/imports/issue-114682-2.stderr @@ -1,9 +1,95 @@ -error[E0573]: expected type, found function `issue_114682_2_extern::max` - --> $DIR/issue-114682-2.rs:8:10 +warning: `max` is ambiguous + --> $DIR/issue-114682-2.rs:6:28 + | +LL | use issue_114682_2_extern::max; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: `max` is ambiguous + --> $DIR/issue-114682-2.rs:9:33 | LL | type A = issue_114682_2_extern::max; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not a type + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ -error: aborting due to 1 previous error +warning: 2 warnings emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `max` is ambiguous + --> $DIR/issue-114682-2.rs:6:28 + | +LL | use issue_114682_2_extern::max; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +Future breakage diagnostic: +warning: `max` is ambiguous + --> $DIR/issue-114682-2.rs:9:33 + | +LL | type A = issue_114682_2_extern::max; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `max` could also refer to the module defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:16:9 + | +LL | pub use self::d::*; + | ^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/imports/issue-114682-3.rs b/tests/ui/imports/issue-114682-3.rs index 6dc4df17a2da..ac603b49e321 100644 --- a/tests/ui/imports/issue-114682-3.rs +++ b/tests/ui/imports/issue-114682-3.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ aux-build: issue-114682-3-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1880625909 @@ -19,6 +18,5 @@ pub use self::auto::*; fn main() { let a: u8 = 1; a.ext(); - //^ FIXME: it should report `ext` not found because `SettingsExt` - // is an ambiguous item in `issue-114682-3-extern.rs`. + //~^ ERROR no method named `ext` found for type `u8` in the current scope } diff --git a/tests/ui/imports/issue-114682-3.stderr b/tests/ui/imports/issue-114682-3.stderr new file mode 100644 index 000000000000..6af7a4e02614 --- /dev/null +++ b/tests/ui/imports/issue-114682-3.stderr @@ -0,0 +1,18 @@ +error[E0599]: no method named `ext` found for type `u8` in the current scope + --> $DIR/issue-114682-3.rs:20:7 + | +LL | fn ext(&self) {} + | --- the method is available for `u8` here +... +LL | a.ext(); + | ^^^ method not found in `u8` + | + = help: items from traits can only be used if the trait is in scope +help: trait `SettingsExt` which provides `ext` is implemented but not in scope; perhaps you want to import it + | +LL + use auto::SettingsExt; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/imports/issue-114682-4.rs b/tests/ui/imports/issue-114682-4.rs index 32c2ca7b2609..29e175b5ed54 100644 --- a/tests/ui/imports/issue-114682-4.rs +++ b/tests/ui/imports/issue-114682-4.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ aux-build: issue-114682-4-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 @@ -6,7 +5,9 @@ extern crate issue_114682_4_extern; use issue_114682_4_extern::*; -fn a() -> Result { // FIXME: `Result` should be identified as an ambiguous item. +//~v ERROR type alias takes 1 generic argument but 2 generic arguments were supplied +fn a() -> Result { //~ WARN `Result` is ambiguous + //~| WARN this was previously accepted Ok(1) } diff --git a/tests/ui/imports/issue-114682-4.stderr b/tests/ui/imports/issue-114682-4.stderr new file mode 100644 index 000000000000..5b012e21ea81 --- /dev/null +++ b/tests/ui/imports/issue-114682-4.stderr @@ -0,0 +1,64 @@ +warning: `Result` is ambiguous + --> $DIR/issue-114682-4.rs:9:11 + | +LL | fn a() -> Result { + | ^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `Result` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `Result` could also refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +error[E0107]: type alias takes 1 generic argument but 2 generic arguments were supplied + --> $DIR/issue-114682-4.rs:9:11 + | +LL | fn a() -> Result { + | ^^^^^^ ---- help: remove the unnecessary generic argument + | | + | expected 1 generic argument + | +note: type alias defined here, with 1 generic parameter: `T` + --> $DIR/auxiliary/issue-114682-4-extern.rs:2:14 + | +LL | pub type Result = std::result::Result; + | ^^^^^^ - + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0107`. +Future incompatibility report: Future breakage diagnostic: +warning: `Result` is ambiguous + --> $DIR/issue-114682-4.rs:9:11 + | +LL | fn a() -> Result { + | ^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `Result` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `Result` could also refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:10:9 + | +LL | pub use b::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/issue-114682-5.rs b/tests/ui/imports/issue-114682-5.rs index 7c6132ebd6ff..1408a8105d75 100644 --- a/tests/ui/imports/issue-114682-5.rs +++ b/tests/ui/imports/issue-114682-5.rs @@ -1,4 +1,3 @@ -//@ check-pass //@ edition: 2018 //@ aux-build: issue-114682-5-extern-1.rs //@ aux-build: issue-114682-5-extern-2.rs @@ -9,7 +8,9 @@ extern crate issue_114682_5_extern_2; use issue_114682_5_extern_2::p::*; use issue_114682_5_extern_1::Url; -// FIXME: The `issue_114682_5_extern_1` should be considered an ambiguous item, -// as it has already been recognized as ambiguous in `issue_114682_5_extern_2`. +//~^ ERROR `issue_114682_5_extern_1` is ambiguous +//~| WARN `issue_114682_5_extern_1` is ambiguous +//~| ERROR unresolved import `issue_114682_5_extern_1::Url` +//~| WARN this was previously accepted fn main() {} diff --git a/tests/ui/imports/issue-114682-5.stderr b/tests/ui/imports/issue-114682-5.stderr new file mode 100644 index 000000000000..5937f6f33117 --- /dev/null +++ b/tests/ui/imports/issue-114682-5.stderr @@ -0,0 +1,81 @@ +error[E0432]: unresolved import `issue_114682_5_extern_1::Url` + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Url` in `types::issue_114682_5_extern_1` + | +help: consider importing this struct instead + | +LL | use ::issue_114682_5_extern_1::Url; + | ++ + +error[E0659]: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution + = note: `issue_114682_5_extern_1` could refer to a crate passed with `--extern` + = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously +note: `issue_114682_5_extern_1` could also refer to the module imported here + --> $DIR/issue-114682-5.rs:9:5 + | +LL | use issue_114682_5_extern_2::p::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `issue_114682_5_extern_1` to disambiguate + = help: or use `crate::issue_114682_5_extern_1` to refer to this module unambiguously + +warning: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `issue_114682_5_extern_1` could refer to the module defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:6:13 + | +LL | pub use crate::types::*; + | ^^^^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `issue_114682_5_extern_1` could also refer to the crate defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:7:13 + | +LL | pub use crate::*; + | ^^^^^ + = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0432, E0659. +For more information about an error, try `rustc --explain E0432`. +Future incompatibility report: Future breakage diagnostic: +warning: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `issue_114682_5_extern_1` could refer to the module defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:6:13 + | +LL | pub use crate::types::*; + | ^^^^^^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `issue_114682_5_extern_1` could also refer to the crate defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:7:13 + | +LL | pub use crate::*; + | ^^^^^ + = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/issue-114682-6.rs b/tests/ui/imports/issue-114682-6.rs index d47b9f8a4e85..480caedb70a1 100644 --- a/tests/ui/imports/issue-114682-6.rs +++ b/tests/ui/imports/issue-114682-6.rs @@ -1,13 +1,12 @@ -//@ check-pass //@ aux-build: issue-114682-6-extern.rs // https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 - +//@ check-pass extern crate issue_114682_6_extern; use issue_114682_6_extern::*; fn main() { - let log = 2; - //^ `log` should be identified as an ambiguous item. + let log = 2; //~ WARN `log` is ambiguous + //~| WARN this was previously accepted let _ = log; } diff --git a/tests/ui/imports/issue-114682-6.stderr b/tests/ui/imports/issue-114682-6.stderr new file mode 100644 index 000000000000..a2e9afb6eedb --- /dev/null +++ b/tests/ui/imports/issue-114682-6.stderr @@ -0,0 +1,49 @@ +warning: `log` is ambiguous + --> $DIR/issue-114682-6.rs:9:9 + | +LL | let log = 2; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `log` could refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:8:9 + | +LL | pub use self::a::*; + | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `log` could also refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:9:9 + | +LL | pub use self::b::*; + | ^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `log` is ambiguous + --> $DIR/issue-114682-6.rs:9:9 + | +LL | let log = 2; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `log` could refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:8:9 + | +LL | pub use self::a::*; + | ^^^^^^^ + = help: consider updating this dependency to resolve this error + = help: if updating the dependency does not resolve the problem report the problem to the author of the relevant crate +note: `log` could also refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:9:9 + | +LL | pub use self::b::*; + | ^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/issue-55884-1.rs b/tests/ui/imports/issue-55884-1.rs index 21744aa5d7bf..3c9c033c158e 100644 --- a/tests/ui/imports/issue-55884-1.rs +++ b/tests/ui/imports/issue-55884-1.rs @@ -17,5 +17,5 @@ mod m { fn main() { use m::S; //~ ERROR `S` is ambiguous - let s = S {}; + let s = S {}; //~ ERROR `S` is ambiguous } diff --git a/tests/ui/imports/issue-55884-1.stderr b/tests/ui/imports/issue-55884-1.stderr index ae8edb049564..a0b63ddc9108 100644 --- a/tests/ui/imports/issue-55884-1.stderr +++ b/tests/ui/imports/issue-55884-1.stderr @@ -18,6 +18,26 @@ LL | pub use self::m2::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `S` to disambiguate -error: aborting due to 1 previous error +error[E0659]: `S` is ambiguous + --> $DIR/issue-55884-1.rs:20:13 + | +LL | let s = S {}; + | ^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `S` could refer to the struct imported here + --> $DIR/issue-55884-1.rs:14:13 + | +LL | pub use self::m1::*; + | ^^^^^^^^^^^ + = help: consider adding an explicit import of `S` to disambiguate +note: `S` could also refer to the struct imported here + --> $DIR/issue-55884-1.rs:15:13 + | +LL | pub use self::m2::*; + | ^^^^^^^^^^^ + = help: consider adding an explicit import of `S` to disambiguate + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.stderr b/tests/ui/imports/local-modularized-tricky-fail-1.stderr index 52a01e8bcdfe..0d1a29027845 100644 --- a/tests/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/tests/ui/imports/local-modularized-tricky-fail-1.stderr @@ -4,7 +4,7 @@ error[E0659]: `exported` is ambiguous LL | exported!(); | ^^^^^^^^ ambiguous name | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `exported` could refer to the macro defined here --> $DIR/local-modularized-tricky-fail-1.rs:6:5 | @@ -15,12 +15,13 @@ LL | | } ... LL | define_exported!(); | ------------------ in this macro invocation + = help: use `crate::exported` to refer to this macro unambiguously note: `exported` could also refer to the macro imported here --> $DIR/local-modularized-tricky-fail-1.rs:23:5 | LL | use inner1::*; | ^^^^^^^^^ - = help: consider adding an explicit import of `exported` to disambiguate + = help: use `crate::exported` to refer to this macro unambiguously = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `panic` is ambiguous @@ -30,8 +31,7 @@ LL | panic!(); | ^^^^^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution - = note: `panic` could refer to a macro from prelude -note: `panic` could also refer to the macro defined here +note: `panic` could refer to the macro defined here --> $DIR/local-modularized-tricky-fail-1.rs:12:5 | LL | / macro_rules! panic { @@ -42,6 +42,8 @@ LL | | } LL | define_panic!(); | --------------- in this macro invocation = help: use `crate::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL = note: this error originates in the macro `define_panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `include` is ambiguous @@ -51,8 +53,7 @@ LL | include!(); | ^^^^^^^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution - = note: `include` could refer to a macro from prelude -note: `include` could also refer to the macro defined here +note: `include` could refer to the macro defined here --> $DIR/local-modularized-tricky-fail-1.rs:18:5 | LL | / macro_rules! include { @@ -63,6 +64,8 @@ LL | | } LL | define_include!(); | ----------------- in this macro invocation = help: use `crate::include` to refer to this macro unambiguously +note: `include` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL = note: this error originates in the macro `define_include` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/imports/macro-paths.stderr b/tests/ui/imports/macro-paths.stderr index 5f113ce2bee5..56a40e908258 100644 --- a/tests/ui/imports/macro-paths.stderr +++ b/tests/ui/imports/macro-paths.stderr @@ -4,7 +4,7 @@ error[E0659]: `bar` is ambiguous LL | bar::m! { | ^^^ ambiguous name | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `bar` could refer to the module defined here --> $DIR/macro-paths.rs:14:9 | @@ -15,7 +15,6 @@ note: `bar` could also refer to the module imported here | LL | use foo::*; | ^^^^^^ - = help: consider adding an explicit import of `bar` to disambiguate error[E0659]: `baz` is ambiguous --> $DIR/macro-paths.rs:23:5 diff --git a/tests/ui/imports/macros.rs b/tests/ui/imports/macros.rs index cf67e08c87a3..121f1f7ae043 100644 --- a/tests/ui/imports/macros.rs +++ b/tests/ui/imports/macros.rs @@ -13,7 +13,7 @@ mod m1 { mod m2 { use two_macros::*; - m! { //~ ERROR ambiguous + m! { //~ ERROR `m` is ambiguous use crate::foo::m; } } diff --git a/tests/ui/imports/macros.stderr b/tests/ui/imports/macros.stderr index 25a678c6b375..9c081cc7af8b 100644 --- a/tests/ui/imports/macros.stderr +++ b/tests/ui/imports/macros.stderr @@ -4,18 +4,19 @@ error[E0659]: `m` is ambiguous LL | m! { | ^ ambiguous name | - = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `m` could refer to the macro imported here --> $DIR/macros.rs:17:13 | LL | use crate::foo::m; | ^^^^^^^^^^^^^ + = help: use `self::m` to refer to this macro unambiguously note: `m` could also refer to the macro imported here --> $DIR/macros.rs:15:9 | LL | use two_macros::*; | ^^^^^^^^^^^^^ - = help: consider adding an explicit import of `m` to disambiguate + = help: use `self::m` to refer to this macro unambiguously error[E0659]: `m` is ambiguous --> $DIR/macros.rs:29:9 diff --git a/tests/ui/imports/nested-import-root-symbol-150103.rs b/tests/ui/imports/nested-import-root-symbol-150103.rs new file mode 100644 index 000000000000..7e126d8188c7 --- /dev/null +++ b/tests/ui/imports/nested-import-root-symbol-150103.rs @@ -0,0 +1,13 @@ +// Issue: https://github.com/rust-lang/rust/issues/150103 +// ICE when using `::` at start of nested imports +// caused by `{{root}}` appearing in diagnostic suggestions + +mod A { + use Iuse::{ ::Fish }; //~ ERROR cannot find module or crate `Iuse` in the crate root +} + +mod B { + use A::{::Fish}; //~ ERROR the crate root in paths can only be used in start position +} + +fn main() {} diff --git a/tests/ui/imports/nested-import-root-symbol-150103.stderr b/tests/ui/imports/nested-import-root-symbol-150103.stderr new file mode 100644 index 000000000000..e5240ceef268 --- /dev/null +++ b/tests/ui/imports/nested-import-root-symbol-150103.stderr @@ -0,0 +1,20 @@ +error[E0433]: cannot find module or crate `Iuse` in the crate root + --> $DIR/nested-import-root-symbol-150103.rs:6:9 + | +LL | use Iuse::{ ::Fish }; + | ^^^^ use of unresolved module or unlinked crate `Iuse` + | +help: you might be missing a crate named `Iuse`, add it to your project and import it in your code + | +LL + extern crate Iuse; + | + +error[E0433]: the crate root in paths can only be used in start position + --> $DIR/nested-import-root-symbol-150103.rs:10:13 + | +LL | use A::{::Fish}; + | ^ can only be used in path start position + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/imports/no-ambiguous-trait-lint-on-redundant-import.rs b/tests/ui/imports/no-ambiguous-trait-lint-on-redundant-import.rs new file mode 100644 index 000000000000..ee08fd8ea800 --- /dev/null +++ b/tests/ui/imports/no-ambiguous-trait-lint-on-redundant-import.rs @@ -0,0 +1,27 @@ +//@ check-pass +// The AMBIGUOUS_GLOB_IMPORTED_TRAITS lint is reported on uses of traits that are +// ambiguously glob imported. This test checks that we don't report this lint +// when the same trait is glob imported multiple times. + +mod t { + pub trait Trait { + fn method(&self) {} + } + + impl Trait for i8 {} +} + +mod m1 { + pub use t::Trait; +} + +mod m2 { + pub use t::Trait; +} + +use m1::*; +use m2::*; + +fn main() { + 0i8.method(); +} diff --git a/tests/ui/imports/overwrite-deep-glob.rs b/tests/ui/imports/overwrite-deep-glob.rs new file mode 100644 index 000000000000..261b22f6e0a0 --- /dev/null +++ b/tests/ui/imports/overwrite-deep-glob.rs @@ -0,0 +1,22 @@ +//@ check-pass + +mod openssl { + pub use self::handwritten::*; + + mod handwritten { + mod m1 { + pub struct S {} + } + mod m2 { + #[derive(Default)] + pub struct S {} + } + + pub use self::m1::*; //~ WARN ambiguous glob re-exports + pub use self::m2::*; + } +} + +pub use openssl::*; + +fn main() {} diff --git a/tests/ui/imports/overwrite-deep-glob.stderr b/tests/ui/imports/overwrite-deep-glob.stderr new file mode 100644 index 000000000000..093478c57c93 --- /dev/null +++ b/tests/ui/imports/overwrite-deep-glob.stderr @@ -0,0 +1,12 @@ +warning: ambiguous glob re-exports + --> $DIR/overwrite-deep-glob.rs:15:17 + | +LL | pub use self::m1::*; + | ^^^^^^^^^^^ the name `S` in the type namespace is first re-exported here +LL | pub use self::m2::*; + | ----------- but the name `S` in the type namespace is also re-exported here + | + = note: `#[warn(ambiguous_glob_reexports)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/overwrite-different-ambig-2.rs b/tests/ui/imports/overwrite-different-ambig-2.rs new file mode 100644 index 000000000000..1d6416c00fdc --- /dev/null +++ b/tests/ui/imports/overwrite-different-ambig-2.rs @@ -0,0 +1,26 @@ +//@ check-pass + +mod m1 { + mod inner { + pub struct S {} + } + pub use self::inner::*; + + #[derive(Debug)] + pub struct S {} +} + +mod m2 { + pub struct S {} +} + +// First we have a glob ambiguity in this glob (with `m2::*`). +// Then we re-fetch `m1::*` because non-glob `m1::S` materializes from derive, +// and we need to make sure that the glob ambiguity is not lost during re-fetching. +use m1::*; +use m2::*; + +fn main() { + let _: m1::S = S {}; //~ WARN `S` is ambiguous + //~| WARN this was previously accepted +} diff --git a/tests/ui/imports/overwrite-different-ambig-2.stderr b/tests/ui/imports/overwrite-different-ambig-2.stderr new file mode 100644 index 000000000000..2d8446585717 --- /dev/null +++ b/tests/ui/imports/overwrite-different-ambig-2.stderr @@ -0,0 +1,49 @@ +warning: `S` is ambiguous + --> $DIR/overwrite-different-ambig-2.rs:24:20 + | +LL | let _: m1::S = S {}; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `S` could refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:20:5 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate +note: `S` could also refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:21:5 + | +LL | use m2::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: `S` is ambiguous + --> $DIR/overwrite-different-ambig-2.rs:24:20 + | +LL | let _: m1::S = S {}; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `S` could refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:20:5 + | +LL | use m1::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate +note: `S` could also refer to the struct imported here + --> $DIR/overwrite-different-ambig-2.rs:21:5 + | +LL | use m2::*; + | ^^^^^ + = help: consider adding an explicit import of `S` to disambiguate + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/imports/overwrite-different-ambig.rs b/tests/ui/imports/overwrite-different-ambig.rs new file mode 100644 index 000000000000..9aee63e18973 --- /dev/null +++ b/tests/ui/imports/overwrite-different-ambig.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ edition:2024 + +mod a { + mod b { + mod c { + pub struct E; + } + mod d { + mod c { + pub struct E; + } + mod d { + #[derive(Debug)] + pub struct E; + } + pub use c::*; + use d::*; + } + use c::*; + use d::*; + } +} + +fn main() {} diff --git a/tests/ui/imports/overwrite-different-vis-2.rs b/tests/ui/imports/overwrite-different-vis-2.rs new file mode 100644 index 000000000000..50369eafb41c --- /dev/null +++ b/tests/ui/imports/overwrite-different-vis-2.rs @@ -0,0 +1,18 @@ +// Regression test for issue #152347. + +//@ check-pass +//@ edition: 2018.. + +use outer::*; // must be before `mod outer` +mod outer { + mod inner { + pub fn f() {} + } + + use inner::*; + pub use inner::*; +} + +fn main() { + f(); +} diff --git a/tests/ui/imports/overwrite-different-vis-3.rs b/tests/ui/imports/overwrite-different-vis-3.rs new file mode 100644 index 000000000000..f45c5cdfb3ab --- /dev/null +++ b/tests/ui/imports/overwrite-different-vis-3.rs @@ -0,0 +1,14 @@ +// Regression test for issue #152606. + +//@ check-pass + +mod outer { + mod inner { + use super::*; // should go before the ambiguous glob imports + } + + use crate::*; + pub use crate::*; +} + +fn main() {} diff --git a/tests/ui/imports/overwrite-different-vis.rs b/tests/ui/imports/overwrite-different-vis.rs new file mode 100644 index 000000000000..edcc441bcb77 --- /dev/null +++ b/tests/ui/imports/overwrite-different-vis.rs @@ -0,0 +1,21 @@ +//@ check-pass + +mod b { + pub mod http { + pub struct HeaderMap; + } + + pub(crate) use self::http::*; + #[derive(Debug)] + pub struct HeaderMap; +} + +mod a { + pub use crate::b::*; + + fn check_type() { + let _: HeaderMap = crate::b::HeaderMap; + } +} + +fn main() {} diff --git a/tests/ui/imports/overwrite-different-warn-ambiguity.rs b/tests/ui/imports/overwrite-different-warn-ambiguity.rs new file mode 100644 index 000000000000..f843208b37d6 --- /dev/null +++ b/tests/ui/imports/overwrite-different-warn-ambiguity.rs @@ -0,0 +1,28 @@ +//@ check-pass +//@ edition:2024 + +mod framing { + mod public_message_in { + mod public_message { + mod public_message { + pub struct ConfirmedTranscriptHashInput; + } + mod public_message_in { + use super::*; + #[derive(Debug)] + pub struct ConfirmedTranscriptHashInput; + } + pub use public_message::*; + use public_message_in::*; + } + mod public_message_in { + #[derive(Debug)] + pub struct ConfirmedTranscriptHashInput; + } + pub use public_message::*; + use public_message_in::*; + } + use public_message_in::*; +} + +fn main() {} diff --git a/tests/ui/imports/overwrite-vis-unused.rs b/tests/ui/imports/overwrite-vis-unused.rs new file mode 100644 index 000000000000..0217fb625083 --- /dev/null +++ b/tests/ui/imports/overwrite-vis-unused.rs @@ -0,0 +1,12 @@ +// Regression test for issues #152004 and #151124. + +#![deny(unused)] + +mod m { + pub struct S {} +} + +use m::*; //~ ERROR unused import: `m::*` +pub use m::*; + +fn main() {} diff --git a/tests/ui/imports/overwrite-vis-unused.stderr b/tests/ui/imports/overwrite-vis-unused.stderr new file mode 100644 index 000000000000..a38aa4d5f070 --- /dev/null +++ b/tests/ui/imports/overwrite-vis-unused.stderr @@ -0,0 +1,15 @@ +error: unused import: `m::*` + --> $DIR/overwrite-vis-unused.rs:9:5 + | +LL | use m::*; + | ^^^^ + | +note: the lint level is defined here + --> $DIR/overwrite-vis-unused.rs:3:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_imports)]` implied by `#[deny(unused)]` + +error: aborting due to 1 previous error + diff --git a/tests/ui/imports/overwritten-glob-ambig.rs b/tests/ui/imports/overwritten-glob-ambig.rs new file mode 100644 index 000000000000..a5918568c62a --- /dev/null +++ b/tests/ui/imports/overwritten-glob-ambig.rs @@ -0,0 +1,26 @@ +// Test for a regression introduced by splitting module scope into two scopes +// (similar to issue #145575). + +//@ check-pass +//@ edition: 2018.. + +#[macro_use] +mod one { + // Macro that is in a different module, but still in scope due to `macro_use` + macro_rules! mac { () => {} } + pub(crate) use mac; +} + +mod other { + macro_rules! mac { () => {} } + pub(crate) use mac; +} + +// Single import of the same in the current module. +use one::mac; +// Glob import of a different macro in the current module (should be an ambiguity). +use other::*; + +fn main() { + mac!(); // OK for now, the ambiguity is not reported +} diff --git a/tests/ui/imports/shadow_builtin_macros.stderr b/tests/ui/imports/shadow_builtin_macros.stderr index c828b1193d81..7799fb230d43 100644 --- a/tests/ui/imports/shadow_builtin_macros.stderr +++ b/tests/ui/imports/shadow_builtin_macros.stderr @@ -5,14 +5,15 @@ LL | fn f() { panic!(); } | ^^^^^ ambiguous name | = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution - = note: `panic` could refer to a macro from prelude -note: `panic` could also refer to the macro imported here +note: `panic` could refer to the macro imported here --> $DIR/shadow_builtin_macros.rs:14:9 | LL | use crate::foo::*; | ^^^^^^^^^^^^^ = help: consider adding an explicit import of `panic` to disambiguate = help: or use `self::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL error[E0659]: `panic` is ambiguous --> $DIR/shadow_builtin_macros.rs:33:5 @@ -21,8 +22,7 @@ LL | panic!(); | ^^^^^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution - = note: `panic` could refer to a macro from prelude -note: `panic` could also refer to the macro defined here +note: `panic` could refer to the macro defined here --> $DIR/shadow_builtin_macros.rs:30:9 | LL | macro_rules! panic { () => {} } @@ -30,6 +30,8 @@ LL | macro_rules! panic { () => {} } LL | } } LL | m!(); | ---- in this macro invocation +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `n` is ambiguous @@ -59,13 +61,14 @@ LL | fn f() { panic!(); } | ^^^^^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution - = note: `panic` could refer to a macro from prelude -note: `panic` could also refer to the macro imported here +note: `panic` could refer to the macro imported here --> $DIR/shadow_builtin_macros.rs:19:26 | LL | ::two_macros::m!(use crate::foo::panic;); | ^^^^^^^^^^^^^^^^^ = help: use `self::panic` to refer to this macro unambiguously +note: `panic` could also refer to a macro from prelude + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL error: aborting due to 4 previous errors diff --git a/tests/ui/imports/suggest-import-issue-120074.edition2015.stderr b/tests/ui/imports/suggest-import-issue-120074.edition2015.stderr index 91fad1fb3099..b079471e809c 100644 --- a/tests/ui/imports/suggest-import-issue-120074.edition2015.stderr +++ b/tests/ui/imports/suggest-import-issue-120074.edition2015.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: unresolved import +error[E0433]: cannot find `bar` in `crate` --> $DIR/suggest-import-issue-120074.rs:14:35 | LL | println!("Hello, {}!", crate::bar::do_the_thing); diff --git a/tests/ui/imports/suggest-import-issue-120074.edition2021.stderr b/tests/ui/imports/suggest-import-issue-120074.edition2021.stderr deleted file mode 100644 index 91fad1fb3099..000000000000 --- a/tests/ui/imports/suggest-import-issue-120074.edition2021.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0433]: failed to resolve: unresolved import - --> $DIR/suggest-import-issue-120074.rs:14:35 - | -LL | println!("Hello, {}!", crate::bar::do_the_thing); - | ^^^ unresolved import - | -help: a similar path exists - | -LL | println!("Hello, {}!", crate::foo::bar::do_the_thing); - | +++++ -help: consider importing this module - | -LL + use foo::bar; - | -help: if you import `bar`, refer to it directly - | -LL - println!("Hello, {}!", crate::bar::do_the_thing); -LL + println!("Hello, {}!", bar::do_the_thing); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/imports/suggest-import-issue-120074.post2015.stderr b/tests/ui/imports/suggest-import-issue-120074.post2015.stderr index f334fb31a3dc..045a7df3feea 100644 --- a/tests/ui/imports/suggest-import-issue-120074.post2015.stderr +++ b/tests/ui/imports/suggest-import-issue-120074.post2015.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: unresolved import +error[E0433]: cannot find `bar` in `crate` --> $DIR/suggest-import-issue-120074.rs:14:35 | LL | println!("Hello, {}!", crate::bar::do_the_thing); diff --git a/tests/ui/imports/suggest-import-issue-120074.rs b/tests/ui/imports/suggest-import-issue-120074.rs index 4ca0d52b1f3e..27027405f4de 100644 --- a/tests/ui/imports/suggest-import-issue-120074.rs +++ b/tests/ui/imports/suggest-import-issue-120074.rs @@ -11,5 +11,5 @@ pub mod foo { } fn main() { - println!("Hello, {}!", crate::bar::do_the_thing); //~ ERROR failed to resolve: unresolved import + println!("Hello, {}!", crate::bar::do_the_thing); //~ ERROR cannot find `bar` in `crate` } diff --git a/tests/ui/imports/tool-mod-child.rs b/tests/ui/imports/tool-mod-child.rs index c0978046719a..6f67d200c2d7 100644 --- a/tests/ui/imports/tool-mod-child.rs +++ b/tests/ui/imports/tool-mod-child.rs @@ -1,8 +1,8 @@ //@ edition:2015 use clippy::a; //~ ERROR unresolved import `clippy` -use clippy::a::b; //~ ERROR failed to resolve: use of unresolved module or unlinked crate `clippy` +use clippy::a::b; //~ ERROR cannot find use rustdoc::a; //~ ERROR unresolved import `rustdoc` -use rustdoc::a::b; //~ ERROR failed to resolve: use of unresolved module or unlinked crate `rustdoc` +use rustdoc::a::b; //~ ERROR cannot find fn main() {} diff --git a/tests/ui/imports/tool-mod-child.stderr b/tests/ui/imports/tool-mod-child.stderr index 3e216c492d34..babb5e21cbf7 100644 --- a/tests/ui/imports/tool-mod-child.stderr +++ b/tests/ui/imports/tool-mod-child.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `clippy` +error[E0433]: cannot find module or crate `clippy` in the crate root --> $DIR/tool-mod-child.rs:3:5 | LL | use clippy::a::b; @@ -20,7 +20,7 @@ help: you might be missing a crate named `clippy`, add it to your project and im LL + extern crate clippy; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `rustdoc` +error[E0433]: cannot find module or crate `rustdoc` in the crate root --> $DIR/tool-mod-child.rs:6:5 | LL | use rustdoc::a::b; diff --git a/tests/ui/underscore-imports/auxiliary/duplicate.rs b/tests/ui/imports/underscore-imports/auxiliary/duplicate.rs similarity index 100% rename from tests/ui/underscore-imports/auxiliary/duplicate.rs rename to tests/ui/imports/underscore-imports/auxiliary/duplicate.rs diff --git a/tests/ui/underscore-imports/auxiliary/underscore-imports.rs b/tests/ui/imports/underscore-imports/auxiliary/underscore-imports.rs similarity index 100% rename from tests/ui/underscore-imports/auxiliary/underscore-imports.rs rename to tests/ui/imports/underscore-imports/auxiliary/underscore-imports.rs diff --git a/tests/ui/underscore-imports/basic.rs b/tests/ui/imports/underscore-imports/basic.rs similarity index 100% rename from tests/ui/underscore-imports/basic.rs rename to tests/ui/imports/underscore-imports/basic.rs diff --git a/tests/ui/underscore-imports/basic.stderr b/tests/ui/imports/underscore-imports/basic.stderr similarity index 100% rename from tests/ui/underscore-imports/basic.stderr rename to tests/ui/imports/underscore-imports/basic.stderr diff --git a/tests/ui/underscore-imports/cycle.rs b/tests/ui/imports/underscore-imports/cycle.rs similarity index 100% rename from tests/ui/underscore-imports/cycle.rs rename to tests/ui/imports/underscore-imports/cycle.rs diff --git a/tests/ui/underscore-imports/duplicate.rs b/tests/ui/imports/underscore-imports/duplicate.rs similarity index 100% rename from tests/ui/underscore-imports/duplicate.rs rename to tests/ui/imports/underscore-imports/duplicate.rs diff --git a/tests/ui/underscore-imports/hygiene-2.rs b/tests/ui/imports/underscore-imports/hygiene-2.rs similarity index 100% rename from tests/ui/underscore-imports/hygiene-2.rs rename to tests/ui/imports/underscore-imports/hygiene-2.rs diff --git a/tests/ui/underscore-imports/hygiene.rs b/tests/ui/imports/underscore-imports/hygiene.rs similarity index 100% rename from tests/ui/underscore-imports/hygiene.rs rename to tests/ui/imports/underscore-imports/hygiene.rs diff --git a/tests/ui/underscore-imports/intercrate.rs b/tests/ui/imports/underscore-imports/intercrate.rs similarity index 100% rename from tests/ui/underscore-imports/intercrate.rs rename to tests/ui/imports/underscore-imports/intercrate.rs diff --git a/tests/ui/imports/underscore-imports/invalid-path-110164.ed2015.stderr b/tests/ui/imports/underscore-imports/invalid-path-110164.ed2015.stderr new file mode 100644 index 000000000000..e023ec58d1ad --- /dev/null +++ b/tests/ui/imports/underscore-imports/invalid-path-110164.ed2015.stderr @@ -0,0 +1,39 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:8:5 + | +LL | use _::a; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:10:5 + | +LL | use _::*; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:14:9 + | +LL | use _::a; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:16:9 + | +LL | use _::*; + | ^ expected identifier, found reserved identifier + +error[E0432]: unresolved import `self::*` + --> $DIR/invalid-path-110164.rs:4:5 + | +LL | use self::*; + | ^^^^^^^ cannot glob-import a module into itself + +error[E0432]: unresolved import `crate::*` + --> $DIR/invalid-path-110164.rs:6:5 + | +LL | use crate::*; + | ^^^^^^^^ cannot glob-import a module into itself + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/imports/underscore-imports/invalid-path-110164.ed2021.stderr b/tests/ui/imports/underscore-imports/invalid-path-110164.ed2021.stderr new file mode 100644 index 000000000000..e023ec58d1ad --- /dev/null +++ b/tests/ui/imports/underscore-imports/invalid-path-110164.ed2021.stderr @@ -0,0 +1,39 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:8:5 + | +LL | use _::a; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:10:5 + | +LL | use _::*; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:14:9 + | +LL | use _::a; + | ^ expected identifier, found reserved identifier + +error: expected identifier, found reserved identifier `_` + --> $DIR/invalid-path-110164.rs:16:9 + | +LL | use _::*; + | ^ expected identifier, found reserved identifier + +error[E0432]: unresolved import `self::*` + --> $DIR/invalid-path-110164.rs:4:5 + | +LL | use self::*; + | ^^^^^^^ cannot glob-import a module into itself + +error[E0432]: unresolved import `crate::*` + --> $DIR/invalid-path-110164.rs:6:5 + | +LL | use crate::*; + | ^^^^^^^^ cannot glob-import a module into itself + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/underscore-imports/issue-110164.rs b/tests/ui/imports/underscore-imports/invalid-path-110164.rs similarity index 100% rename from tests/ui/underscore-imports/issue-110164.rs rename to tests/ui/imports/underscore-imports/invalid-path-110164.rs diff --git a/tests/ui/underscore-imports/macro-expanded.rs b/tests/ui/imports/underscore-imports/macro-expanded.rs similarity index 100% rename from tests/ui/underscore-imports/macro-expanded.rs rename to tests/ui/imports/underscore-imports/macro-expanded.rs diff --git a/tests/ui/imports/multiple-extern-by-macro-for-underscore.ed2015.stderr b/tests/ui/imports/underscore-imports/multiple-extern-by-macro-for-underscore.ed2015.stderr similarity index 100% rename from tests/ui/imports/multiple-extern-by-macro-for-underscore.ed2015.stderr rename to tests/ui/imports/underscore-imports/multiple-extern-by-macro-for-underscore.ed2015.stderr diff --git a/tests/ui/imports/multiple-extern-by-macro-for-underscore.ed2021.stderr b/tests/ui/imports/underscore-imports/multiple-extern-by-macro-for-underscore.ed2021.stderr similarity index 100% rename from tests/ui/imports/multiple-extern-by-macro-for-underscore.ed2021.stderr rename to tests/ui/imports/underscore-imports/multiple-extern-by-macro-for-underscore.ed2021.stderr diff --git a/tests/ui/imports/multiple-extern-by-macro-for-underscore.rs b/tests/ui/imports/underscore-imports/multiple-extern-by-macro-for-underscore.rs similarity index 100% rename from tests/ui/imports/multiple-extern-by-macro-for-underscore.rs rename to tests/ui/imports/underscore-imports/multiple-extern-by-macro-for-underscore.rs diff --git a/tests/ui/underscore-imports/multiple-uses.ed2015.stderr b/tests/ui/imports/underscore-imports/multiple-uses.ed2015.stderr similarity index 100% rename from tests/ui/underscore-imports/multiple-uses.ed2015.stderr rename to tests/ui/imports/underscore-imports/multiple-uses.ed2015.stderr diff --git a/tests/ui/underscore-imports/multiple-uses.ed2021.stderr b/tests/ui/imports/underscore-imports/multiple-uses.ed2021.stderr similarity index 100% rename from tests/ui/underscore-imports/multiple-uses.ed2021.stderr rename to tests/ui/imports/underscore-imports/multiple-uses.ed2021.stderr diff --git a/tests/ui/underscore-imports/multiple-uses.rs b/tests/ui/imports/underscore-imports/multiple-uses.rs similarity index 100% rename from tests/ui/underscore-imports/multiple-uses.rs rename to tests/ui/imports/underscore-imports/multiple-uses.rs diff --git a/tests/ui/underscore-imports/shadow.rs b/tests/ui/imports/underscore-imports/shadow.rs similarity index 100% rename from tests/ui/underscore-imports/shadow.rs rename to tests/ui/imports/underscore-imports/shadow.rs diff --git a/tests/ui/underscore-imports/shadow.stderr b/tests/ui/imports/underscore-imports/shadow.stderr similarity index 100% rename from tests/ui/underscore-imports/shadow.stderr rename to tests/ui/imports/underscore-imports/shadow.stderr diff --git a/tests/ui/underscore-imports/unused-2018.rs b/tests/ui/imports/underscore-imports/unused-2018.rs similarity index 100% rename from tests/ui/underscore-imports/unused-2018.rs rename to tests/ui/imports/underscore-imports/unused-2018.rs diff --git a/tests/ui/underscore-imports/unused-2018.stderr b/tests/ui/imports/underscore-imports/unused-2018.stderr similarity index 100% rename from tests/ui/underscore-imports/unused-2018.stderr rename to tests/ui/imports/underscore-imports/unused-2018.stderr diff --git a/tests/ui/imports/unresolved-seg-after-ambiguous.rs b/tests/ui/imports/unresolved-seg-after-ambiguous.rs index 67366deabaaf..820f579ae3bb 100644 --- a/tests/ui/imports/unresolved-seg-after-ambiguous.rs +++ b/tests/ui/imports/unresolved-seg-after-ambiguous.rs @@ -18,7 +18,7 @@ mod a { use self::a::E::in_exist; //~^ ERROR: unresolved import `self::a::E` -//~| ERROR: `E` is ambiguous +//~| WARN: `E` is ambiguous //~| WARNING: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! fn main() {} diff --git a/tests/ui/imports/unresolved-seg-after-ambiguous.stderr b/tests/ui/imports/unresolved-seg-after-ambiguous.stderr index 67316462a27e..411cd1dbe5ef 100644 --- a/tests/ui/imports/unresolved-seg-after-ambiguous.stderr +++ b/tests/ui/imports/unresolved-seg-after-ambiguous.stderr @@ -4,7 +4,7 @@ error[E0432]: unresolved import `self::a::E` LL | use self::a::E::in_exist; | ^ `E` is a struct, not a module -error: `E` is ambiguous +warning: `E` is ambiguous --> $DIR/unresolved-seg-after-ambiguous.rs:19:14 | LL | use self::a::E::in_exist; @@ -25,13 +25,13 @@ note: `E` could also refer to the struct imported here LL | pub use self::d::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `E` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default -error: aborting due to 2 previous errors +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0432`. Future incompatibility report: Future breakage diagnostic: -error: `E` is ambiguous +warning: `E` is ambiguous --> $DIR/unresolved-seg-after-ambiguous.rs:19:14 | LL | use self::a::E::in_exist; @@ -52,5 +52,5 @@ note: `E` could also refer to the struct imported here LL | pub use self::d::*; | ^^^^^^^^^^ = help: consider adding an explicit import of `E` to disambiguate - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default + = note: `#[warn(ambiguous_glob_imports)]` (part of `#[warn(future_incompatible)]`) on by default diff --git a/tests/ui/include-macros/auxiliary/shebang-expr.rs b/tests/ui/include-macros/auxiliary/shebang-expr.rs new file mode 100644 index 000000000000..73e92b5a889e --- /dev/null +++ b/tests/ui/include-macros/auxiliary/shebang-expr.rs @@ -0,0 +1,3 @@ +#!/usr/bin/env my-rust-expr-evaluator + +2 * (1 + 3) diff --git a/tests/ui/include-macros/auxiliary/shebang-items.rs b/tests/ui/include-macros/auxiliary/shebang-items.rs new file mode 100644 index 000000000000..b9011b62cc91 --- /dev/null +++ b/tests/ui/include-macros/auxiliary/shebang-items.rs @@ -0,0 +1,3 @@ +#!/usr/bin/env my-rust-script-runner + +fn main() {} diff --git a/tests/ui/include-macros/invalid-utf8-binary-file.rs b/tests/ui/include-macros/invalid-utf8-binary-file.rs index 0bbdbac611fd..c733f07c26f0 100644 --- a/tests/ui/include-macros/invalid-utf8-binary-file.rs +++ b/tests/ui/include-macros/invalid-utf8-binary-file.rs @@ -5,6 +5,8 @@ //! Ensure that ICE does not occur when reading an invalid UTF8 file with an absolute path. //! regression test for issue -#![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] //~ ERROR: wasn't a utf-8 file +#![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] +//~^ ERROR: wasn't a utf-8 file +//~| ERROR: attribute value must be a literal fn main() {} diff --git a/tests/ui/include-macros/invalid-utf8-binary-file.stderr b/tests/ui/include-macros/invalid-utf8-binary-file.stderr index 4ac4def1b00a..232cb5042b72 100644 --- a/tests/ui/include-macros/invalid-utf8-binary-file.stderr +++ b/tests/ui/include-macros/invalid-utf8-binary-file.stderr @@ -6,5 +6,11 @@ LL | #![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] | = note: invalid utf-8 at byte `$BYTE` -error: aborting due to 1 previous error +error: attribute value must be a literal + --> $DIR/invalid-utf8-binary-file.rs:8:10 + | +LL | #![doc = include_str!(concat!(env!("INVALID_UTF8_BIN")))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/include-macros/shebang-in-expr-ctxt.rs b/tests/ui/include-macros/shebang-in-expr-ctxt.rs new file mode 100644 index 000000000000..b6d3fa9e076f --- /dev/null +++ b/tests/ui/include-macros/shebang-in-expr-ctxt.rs @@ -0,0 +1,16 @@ +// Check that we *don't* strip shebang in files that were `include`d in an expression or +// expression statement context. +// We do that to be consistent with frontmatter (see test `frontmatter/include-in-expr-ctxt.rs`). +// While there could be niche use cases for such shebang, it seems more confusing than beneficial. + +fn main() { + // expr ctxt + _ = include!("auxiliary/shebang-expr.rs"); + //~^ ERROR non-expression macro in expression position + //~? ERROR expected `[`, found `/` + + // stmt ctxt (reuses expr expander) + include!("auxiliary/shebang-expr.rs"); + //~^ ERROR non-statement macro in statement position + //~? ERROR expected `[`, found `/` +} diff --git a/tests/ui/include-macros/shebang-in-expr-ctxt.stderr b/tests/ui/include-macros/shebang-in-expr-ctxt.stderr new file mode 100644 index 000000000000..9e95b02a78dc --- /dev/null +++ b/tests/ui/include-macros/shebang-in-expr-ctxt.stderr @@ -0,0 +1,33 @@ +error: expected `[`, found `/` + --> $DIR/auxiliary/shebang-expr.rs:1:3 + | +LL | #!/usr/bin/env my-rust-expr-evaluator + | ^ expected `[` + | + = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not + = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file + +error: non-expression macro in expression position: include + --> $DIR/shebang-in-expr-ctxt.rs:8:9 + | +LL | _ = include!("auxiliary/shebang-expr.rs"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected `[`, found `/` + --> $DIR/auxiliary/shebang-expr.rs:1:3 + | +LL | #!/usr/bin/env my-rust-expr-evaluator + | ^ expected `[` + | + = note: the token sequence `#!` here looks like the start of a shebang interpreter directive but it is not + = help: if you meant this to be a shebang interpreter directive, move it to the very start of the file + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: non-statement macro in statement position: include + --> $DIR/shebang-in-expr-ctxt.rs:13:5 + | +LL | include!("auxiliary/shebang-expr.rs"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/include-macros/shebang-in-item-ctxt.rs b/tests/ui/include-macros/shebang-in-item-ctxt.rs new file mode 100644 index 000000000000..3e0718e287f0 --- /dev/null +++ b/tests/ui/include-macros/shebang-in-item-ctxt.rs @@ -0,0 +1,4 @@ +// Ensure that we strip shebang in files `include`d in item contexts. +//@ check-pass + +include!("auxiliary/shebang-items.rs"); diff --git a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs new file mode 100644 index 000000000000..b13b6f418d42 --- /dev/null +++ b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.rs @@ -0,0 +1,8 @@ +use std::rc::Rc; +pub struct Foo; + +pub type Function = Rc; + +impl Function {} +//~^ ERROR cannot define inherent `impl` for a type outside of the crate where the type is defined [E0116] +fn main(){} diff --git a/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr new file mode 100644 index 000000000000..a62f7f82ba9d --- /dev/null +++ b/tests/ui/incoherent-inherent-impls/insufficient-suggestion-issue-141679.stderr @@ -0,0 +1,17 @@ +error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined + --> $DIR/insufficient-suggestion-issue-141679.rs:6:1 + | +LL | impl Function {} + | ^^^^^^^^^^^^^ impl for type defined outside of crate + | + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see +note: `Function` does not define a new type, only an alias of `Rc` defined here + --> $DIR/insufficient-suggestion-issue-141679.rs:4:1 + | +LL | pub type Function = Rc; + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0116`. diff --git a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr index f8491697910c..de61c3900d46 100644 --- a/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr +++ b/tests/ui/incoherent-inherent-impls/no-attr-empty-impl.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::StructWithAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/no-attr-empty-impl.rs:7:1 @@ -12,7 +13,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::StructNoAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/no-attr-empty-impl.rs:10:1 @@ -20,7 +22,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::EnumWithAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined --> $DIR/no-attr-empty-impl.rs:13:1 @@ -28,7 +31,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl extern_crate::EnumNoAttr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error[E0390]: cannot define inherent `impl` for primitive types --> $DIR/no-attr-empty-impl.rs:16:1 diff --git a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr index 2a33262f8389..f01817e29443 100644 --- a/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr +++ b/tests/ui/incoherent-inherent-impls/no-other-unrelated-errors.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl Vec {} | ^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error: aborting due to 1 previous error diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index 7bfb678df5fc..e5f9f7854f7b 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -13,8 +13,6 @@ help: the following other types implement trait `SliceIndex` | = note: `usize` implements `SliceIndex` = note: required for `[{integer}]` to implement `Index` - = note: 1 redundant requirement hidden - = note: required for `[{integer}; 1]` to implement `Index` error[E0308]: mismatched types --> $DIR/indexing-requires-a-uint.rs:12:18 diff --git a/tests/ui/indexing/point-at-index-for-obligation-failure.rs b/tests/ui/indexing/point-at-index-for-obligation-failure.rs index e9c429b53ced..4ff9069936fe 100644 --- a/tests/ui/indexing/point-at-index-for-obligation-failure.rs +++ b/tests/ui/indexing/point-at-index-for-obligation-failure.rs @@ -1,7 +1,7 @@ fn main() { let a = std::collections::HashMap::::new(); let s = "hello"; - let _b = a[ - &s //~ ERROR E0277 + let _b = a[ //~ ERROR E0277 + &s ]; } diff --git a/tests/ui/indexing/point-at-index-for-obligation-failure.stderr b/tests/ui/indexing/point-at-index-for-obligation-failure.stderr index a221e4337891..22f48d61985f 100644 --- a/tests/ui/indexing/point-at-index-for-obligation-failure.stderr +++ b/tests/ui/indexing/point-at-index-for-obligation-failure.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `String: Borrow<&str>` is not satisfied - --> $DIR/point-at-index-for-obligation-failure.rs:5:9 + --> $DIR/point-at-index-for-obligation-failure.rs:4:14 | -LL | &s - | ^^ the trait `Borrow<&str>` is not implemented for `String` +LL | let _b = a[ + | ______________^ +LL | | &s +LL | | ]; + | |_____^ the trait `Borrow<&str>` is not implemented for `String` | help: the trait `Borrow<&_>` is not implemented for `String` but trait `Borrow<_>` is implemented for it diff --git a/tests/ui/indexing/ref-array-indexing.rs b/tests/ui/indexing/ref-array-indexing.rs new file mode 100644 index 000000000000..302255798df2 --- /dev/null +++ b/tests/ui/indexing/ref-array-indexing.rs @@ -0,0 +1,6 @@ +//! regression test for https://github.com/rust-lang/rust/issues/43205 +//@ run-pass +fn main() { + let _ = &&[()][0]; + println!("{:?}", &[(), ()][1]); +} diff --git a/tests/ui/inference/inference-thread-loop-closure.rs b/tests/ui/inference/inference-thread-loop-closure.rs new file mode 100644 index 000000000000..78b1b145367e --- /dev/null +++ b/tests/ui/inference/inference-thread-loop-closure.rs @@ -0,0 +1,16 @@ +//! regression test for +//@ check-pass +#![allow(unused_must_use)] +use std::thread; + +fn _foo() { + thread::spawn(move || { + // no need for -> () + loop { + println!("hello"); + } + }) + .join(); +} + +fn main() {} diff --git a/tests/ui/inference/inference-variable-behind-raw-pointer.stderr b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr index 50202ea3db3e..360d4dd22ceb 100644 --- a/tests/ui/inference/inference-variable-behind-raw-pointer.stderr +++ b/tests/ui/inference/inference-variable-behind-raw-pointer.stderr @@ -5,7 +5,7 @@ LL | if data.is_null() {} | ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see = note: `#[warn(tyvar_behind_raw_pointer)]` (part of `#[warn(rust_2018_compatibility)]`) on by default warning: 1 warning emitted diff --git a/tests/ui/inference/issue-71732.stderr b/tests/ui/inference/issue-71732.stderr index af8b310fd1d9..e79131694856 100644 --- a/tests/ui/inference/issue-71732.stderr +++ b/tests/ui/inference/issue-71732.stderr @@ -10,7 +10,7 @@ LL | .get(&"key".into()) - impl Borrow for String; - impl Borrow for T where T: ?Sized; -note: required by a bound in `HashMap::::get` +note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying the generic argument | diff --git a/tests/ui/inference/issue-72616.stderr b/tests/ui/inference/issue-72616.stderr index 6b47d5688113..8eba3216a846 100644 --- a/tests/ui/inference/issue-72616.stderr +++ b/tests/ui/inference/issue-72616.stderr @@ -8,8 +8,11 @@ LL | if String::from("a") == "a".try_into().unwrap() {} | = note: multiple `impl`s satisfying `String: PartialEq<_>` found in the following crates: `alloc`, `std`: - impl PartialEq for String; + - impl PartialEq for String; + - impl PartialEq for String; - impl PartialEq for String; - impl PartialEq for String; + - impl PartialEq for String; help: try using a fully qualified path to specify the expected types | LL - if String::from("a") == "a".try_into().unwrap() {} diff --git a/tests/ui/inference/iterator-sum-array-15673.rs b/tests/ui/inference/iterator-sum-array-15673.rs index c3d94415affd..b8d9fd994218 100644 --- a/tests/ui/inference/iterator-sum-array-15673.rs +++ b/tests/ui/inference/iterator-sum-array-15673.rs @@ -1,9 +1,6 @@ //! Regression test for https://github.com/rust-lang/rust/issues/15673 //@ run-pass -#![allow(stable_features)] - -#![feature(iter_arith)] fn main() { let x: [u64; 3] = [1, 2, 3]; diff --git a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr index 3de317d2af6d..ff668f88d4d1 100644 --- a/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr +++ b/tests/ui/inference/need_type_info/issue-107745-avoid-expr-from-macro-expansion.stderr @@ -3,8 +3,6 @@ error[E0282]: type annotations needed | LL | println!("{:?}", []); | ^^ cannot infer type - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/inference/note-and-explain-ReVar-124973.stderr b/tests/ui/inference/note-and-explain-ReVar-124973.stderr index bb37e6231a32..2b5e79e9a1c6 100644 --- a/tests/ui/inference/note-and-explain-ReVar-124973.stderr +++ b/tests/ui/inference/note-and-explain-ReVar-124973.stderr @@ -8,9 +8,9 @@ error[E0700]: hidden type for `impl Future` captures lifetime that --> $DIR/note-and-explain-ReVar-124973.rs:5:76 | LL | async unsafe extern "C" fn multiple_named_lifetimes<'a, 'b>(_: u8, _: ...) {} - | -------------------------------------------------------------------------- ^^ - | | - | opaque type defined here + | -^^ + | | + | opaque type defined here | = note: hidden type `{async fn body of multiple_named_lifetimes<'a, 'b>()}` captures lifetime `'_` diff --git a/tests/ui/infinite/issue-41731-infinite-macro-print.stderr b/tests/ui/infinite/issue-41731-infinite-macro-print.stderr index 84436de9aa37..5f5d2c75525d 100644 --- a/tests/ui/infinite/issue-41731-infinite-macro-print.stderr +++ b/tests/ui/infinite/issue-41731-infinite-macro-print.stderr @@ -1,8 +1,11 @@ error: recursion limit reached while expanding `$crate::format_args!` - --> $DIR/issue-41731-infinite-macro-print.rs:14:5 + --> $DIR/issue-41731-infinite-macro-print.rs:8:13 | +LL | print!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_print`) = note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -23,10 +26,13 @@ LL | stack!("overflow"); = note: to `{ $crate :: io :: _print($crate :: format_args! (stack! ("overflow"))); }` error: format argument must be a string literal - --> $DIR/issue-41731-infinite-macro-print.rs:14:5 + --> $DIR/issue-41731-infinite-macro-print.rs:8:13 | +LL | print!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = note: this error originates in the macro `print` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might be missing a string literal to format with diff --git a/tests/ui/infinite/issue-41731-infinite-macro-println.stderr b/tests/ui/infinite/issue-41731-infinite-macro-println.stderr index 6d0432abe4c5..c19039e305e2 100644 --- a/tests/ui/infinite/issue-41731-infinite-macro-println.stderr +++ b/tests/ui/infinite/issue-41731-infinite-macro-println.stderr @@ -1,8 +1,11 @@ error: recursion limit reached while expanding `$crate::format_args_nl!` - --> $DIR/issue-41731-infinite-macro-println.rs:14:5 + --> $DIR/issue-41731-infinite-macro-println.rs:8:13 | +LL | println!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "10"]` attribute to your crate (`issue_41731_infinite_macro_println`) = note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -23,10 +26,13 @@ LL | stack!("overflow"); = note: to `{ $crate :: io :: _print($crate :: format_args_nl! (stack! ("overflow"))); }` error: format argument must be a string literal - --> $DIR/issue-41731-infinite-macro-println.rs:14:5 + --> $DIR/issue-41731-infinite-macro-println.rs:8:13 | +LL | println!(stack!($overflow)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | stack!("overflow"); - | ^^^^^^^^^^^^^^^^^^ + | ------------------ in this macro invocation | = note: this error originates in the macro `println` which comes from the expansion of the macro `stack` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might be missing a string literal to format with diff --git a/tests/ui/inline-const/dont-eval-const-block-during-promotion.fail.stderr b/tests/ui/inline-const/dont-eval-const-block-during-promotion.fail.stderr new file mode 100644 index 000000000000..a4d133cbc011 --- /dev/null +++ b/tests/ui/inline-const/dont-eval-const-block-during-promotion.fail.stderr @@ -0,0 +1,42 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/dont-eval-const-block-during-promotion.rs:48:14 + | +LL | x = &([0][const { 0 }] & 0); + | ^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement + | | + | creates a temporary value which is freed while still in use +... +LL | (x, y, z); + | - borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/dont-eval-const-block-during-promotion.rs:50:14 + | +LL | y = &(1 / const { 1 }); + | ^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement + | | + | creates a temporary value which is freed while still in use +... +LL | (x, y, z); + | - borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/dont-eval-const-block-during-promotion.rs:52:14 + | +LL | z = &(const { 1 } / -1); + | ^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement + | | + | creates a temporary value which is freed while still in use +LL | +LL | (x, y, z); + | - borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/inline-const/dont-eval-const-block-during-promotion.rs b/tests/ui/inline-const/dont-eval-const-block-during-promotion.rs new file mode 100644 index 000000000000..3ecf7acf8edc --- /dev/null +++ b/tests/ui/inline-const/dont-eval-const-block-during-promotion.rs @@ -0,0 +1,65 @@ +//! Test for #150464: as of #138499, trying to evaluate const blocks during constant promotion will +//! result in a query cycle, so we shouldn't do it. Evaluation can happen when trying to promote +//! integer division and array indexing, where it's necessary for the operation to succeed to be +//! able to use it in a promoted constant. +//@ revisions: pass fail +//@[pass] check-pass + +use std::mem::offset_of; + +struct Thing(i32); + +fn main() { + // For a temporary involving array indexing to be promoted, we evaluate the index to make sure + // it's in-bounds. As of #150557 we treat inline constants as maybe-out-of-bounds to avoid the + // query cycle from evaluating them. That allows this to compile: + let x = &([0][const { 0 }] & 0); + // Likewise, integer divisors must be nonzero. Avoiding the query cycle allows this to compile: + let y = &(1 / const { 1 }); + // Likewise, signed integer dividends can't be the integer minimum when the divisor is -1. + let z = &(const { 1 } / -1); + // These temporaries are all lifetime-extended, so they don't need to be promoted for references + // to them to be live later in the block. Generally, code with const blocks in these positions + // should compile as long as being promoted isn't necessary for borrow-checking to succeed. + (x, y, z); + + // A reduced example from real code (#150464): this can't be promoted since the array is a local + // variable, but it still resulted in a query cycle because the index was evaluated for the + // bounds-check before checking that. By not evaluating the const block, we avoid the cycle. + // Since this doesn't rely on promotion, it should borrow-check successfully. + let temp = [0u8]; + let _ = &(temp[const { 0usize }] & 0u8); + // #150464 was reported because `offset_of!` started desugaring to a const block in #148151. + let _ = &(temp[offset_of!(Thing, 0)] & 0u8); + + // Similarly, at the time #150464 was reported, the index here was evaluated before checking + // that the indexed expression is an array. As above, this can't be promoted, but still resulted + // in a query cycle. By not evaluating the const block, we avoid the cycle. Since this doesn't + // rely on promotion, it should borrow-check successfully. + let temp: &[u8] = &[0u8]; + let _ = &(temp[const { 0usize }] & 0u8); + + // By no longer promoting these temporaries, they're dropped at the ends of their respective + // statements, so we can't refer to them thereafter. This code no longer query-cycles, but it + // fails to borrow-check instead. + #[cfg(fail)] + { + let (x, y, z); + x = &([0][const { 0 }] & 0); + //[fail]~^ ERROR: temporary value dropped while borrowed + y = &(1 / const { 1 }); + //[fail]~^ ERROR: temporary value dropped while borrowed + z = &(const { 1 } / -1); + //[fail]~^ ERROR: temporary value dropped while borrowed + (x, y, z); + } + + // Sanity check: those temporaries do promote if the const blocks are removed. + // If constant promotion is changed so that these are no longer implicitly promoted, the + // comments on this test file should be reworded to reflect that. + let (x, y, z); + x = &([0][0] & 0); + y = &(1 / 1); + z = &(1 / -1); + (x, y, z); +} diff --git a/tests/ui/inline-const/in-pat-recovery.rs b/tests/ui/inline-const/in-pat-recovery.rs index a46e56e3be64..037c58d3bf98 100644 --- a/tests/ui/inline-const/in-pat-recovery.rs +++ b/tests/ui/inline-const/in-pat-recovery.rs @@ -8,4 +8,59 @@ fn main() { 2 => {} _ => {} } + + match 5 { + const { 1 } ..= 10 => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + 1 ..= const { 10 } => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + const { 1 } ..= const { 10 } => {} + //~^ ERROR const blocks cannot be used as patterns + //~| ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + const { 1 } .. 10 => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + 1 .. const { 10 } => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + const { 1 + 2 } ..= 10 => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + 1 ..= const { 5 + 5 } => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + const { 3 } .. => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } + + match 5 { + ..= const { 7 } => {} + //~^ ERROR const blocks cannot be used as patterns + _ => {} + } } diff --git a/tests/ui/inline-const/in-pat-recovery.stderr b/tests/ui/inline-const/in-pat-recovery.stderr index 0698cff1480d..55adb5c49a6d 100644 --- a/tests/ui/inline-const/in-pat-recovery.stderr +++ b/tests/ui/inline-const/in-pat-recovery.stderr @@ -6,5 +6,85 @@ LL | const { 1 + 7 } => {} | = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead -error: aborting due to 1 previous error +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:13:15 + | +LL | const { 1 } ..= 10 => {} + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:19:21 + | +LL | 1 ..= const { 10 } => {} + | ^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:25:15 + | +LL | const { 1 } ..= const { 10 } => {} + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:25:31 + | +LL | const { 1 } ..= const { 10 } => {} + | ^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:32:15 + | +LL | const { 1 } .. 10 => {} + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:38:20 + | +LL | 1 .. const { 10 } => {} + | ^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:44:15 + | +LL | const { 1 + 2 } ..= 10 => {} + | ^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:50:21 + | +LL | 1 ..= const { 5 + 5 } => {} + | ^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:56:15 + | +LL | const { 3 } .. => {} + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/in-pat-recovery.rs:62:19 + | +LL | ..= const { 7 } => {} + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: aborting due to 11 previous errors diff --git a/tests/ui/inline-const/reject-const-block-pat-pre-expansion.rs b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.rs new file mode 100644 index 000000000000..9af4925c0432 --- /dev/null +++ b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.rs @@ -0,0 +1,12 @@ +//! Regression test for : reject inline const +//! patterns pre-expansion when possible. + +macro_rules! analyze { ($p:pat) => {}; } +analyze!(const { 0 }); +//~^ ERROR: const blocks cannot be used as patterns + +#[cfg(false)] +fn scope() { let const { 0 }; } +//~^ ERROR: const blocks cannot be used as patterns + +fn main() {} diff --git a/tests/ui/inline-const/reject-const-block-pat-pre-expansion.stderr b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.stderr new file mode 100644 index 000000000000..034b97699396 --- /dev/null +++ b/tests/ui/inline-const/reject-const-block-pat-pre-expansion.stderr @@ -0,0 +1,18 @@ +error: const blocks cannot be used as patterns + --> $DIR/reject-const-block-pat-pre-expansion.rs:9:24 + | +LL | fn scope() { let const { 0 }; } + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: const blocks cannot be used as patterns + --> $DIR/reject-const-block-pat-pre-expansion.rs:5:16 + | +LL | analyze!(const { 0 }); + | ^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error: aborting due to 2 previous errors + diff --git a/tests/ui/instrument-coverage/coverage-options.rs b/tests/ui/instrument-coverage/coverage-options.rs index ead2e3221d8c..091ccdf38a08 100644 --- a/tests/ui/instrument-coverage/coverage-options.rs +++ b/tests/ui/instrument-coverage/coverage-options.rs @@ -1,5 +1,5 @@ //@ revisions: block branch condition bad -//@ compile-flags -Cinstrument-coverage -Zno-profiler-runtime +//@ compile-flags: -Cinstrument-coverage -Zno-profiler-runtime //@ [block] check-pass //@ [block] compile-flags: -Zcoverage-options=block diff --git a/tests/ui/internal-lints/diagnostics_incorrect.rs b/tests/ui/internal-lints/diagnostics_incorrect.rs deleted file mode 100644 index c1532aa9d57e..000000000000 --- a/tests/ui/internal-lints/diagnostics_incorrect.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ compile-flags: -Z unstable-options - -#![feature(rustc_attrs)] - -#[rustc_lint_diagnostics] -//~^ ERROR attribute should be applied to a function -struct Foo; - -impl Foo { - #[rustc_lint_diagnostics(a)] - //~^ ERROR malformed `rustc_lint_diagnostics` - fn bar() {} -} - -fn main() {} diff --git a/tests/ui/internal-lints/diagnostics_incorrect.stderr b/tests/ui/internal-lints/diagnostics_incorrect.stderr deleted file mode 100644 index e849ca2829e4..000000000000 --- a/tests/ui/internal-lints/diagnostics_incorrect.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error: malformed `rustc_lint_diagnostics` attribute input - --> $DIR/diagnostics_incorrect.rs:10:5 - | -LL | #[rustc_lint_diagnostics(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_diagnostics]` - -error: attribute should be applied to a function definition - --> $DIR/diagnostics_incorrect.rs:5:1 - | -LL | #[rustc_lint_diagnostics] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Foo; - | ----------- not a function definition - -error: aborting due to 2 previous errors - diff --git a/tests/ui/internal-lints/query_stability_incorrect.rs b/tests/ui/internal-lints/query_stability_incorrect.rs index a428611caaa4..cefd89867711 100644 --- a/tests/ui/internal-lints/query_stability_incorrect.rs +++ b/tests/ui/internal-lints/query_stability_incorrect.rs @@ -3,7 +3,7 @@ #![feature(rustc_attrs)] #[rustc_lint_query_instability] -//~^ ERROR attribute should be applied to a function +//~^ ERROR `#[rustc_lint_query_instability]` attribute cannot be used on structs struct Foo; impl Foo { diff --git a/tests/ui/internal-lints/query_stability_incorrect.stderr b/tests/ui/internal-lints/query_stability_incorrect.stderr index 3f78b39edd96..8149ac3b9518 100644 --- a/tests/ui/internal-lints/query_stability_incorrect.stderr +++ b/tests/ui/internal-lints/query_stability_incorrect.stderr @@ -1,17 +1,20 @@ -error: malformed `rustc_lint_query_instability` attribute input - --> $DIR/query_stability_incorrect.rs:10:5 - | -LL | #[rustc_lint_query_instability(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_query_instability]` - -error: attribute should be applied to a function definition +error: `#[rustc_lint_query_instability]` attribute cannot be used on structs --> $DIR/query_stability_incorrect.rs:5:1 | LL | #[rustc_lint_query_instability] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Foo; - | ----------- not a function definition + | + = help: `#[rustc_lint_query_instability]` can only be applied to functions + +error[E0565]: malformed `rustc_lint_query_instability` attribute input + --> $DIR/query_stability_incorrect.rs:10:5 + | +LL | #[rustc_lint_query_instability(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[rustc_lint_query_instability]` error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0565`. diff --git a/tests/ui/internal/auxiliary/internal_unstable.rs b/tests/ui/internal/auxiliary/internal_unstable.rs index eb4d6cb380ef..bea153227a77 100644 --- a/tests/ui/internal/auxiliary/internal_unstable.rs +++ b/tests/ui/internal/auxiliary/internal_unstable.rs @@ -99,3 +99,10 @@ macro_rules! access_field_noallow { macro_rules! pass_through_noallow { ($e: expr) => { $e } } + +#[stable(feature = "stable", since = "1.0.0")] +#[allow_internal_unstable(asm_experimental_arch)] +#[macro_export] +macro_rules! asm_redirect { + ($($t:tt)*) => { core::arch::global_asm!($($t)*); } +} diff --git a/tests/ui/internal/internal-unstable-asm-experimental-arch.rs b/tests/ui/internal/internal-unstable-asm-experimental-arch.rs new file mode 100644 index 000000000000..6d97779ff911 --- /dev/null +++ b/tests/ui/internal/internal-unstable-asm-experimental-arch.rs @@ -0,0 +1,18 @@ +//@ only-wasm32-wasip1 +//@ compile-flags: --crate-type=lib +//@ build-pass +//@ aux-build:internal_unstable.rs + +#[macro_use] +extern crate internal_unstable; + +asm_redirect!( + "test:", + ".globl test", + ".functype test (i32) -> (i32)", + "local.get 0", + "i32.const 1", + "i32.add", + "end_function", + ".export_name test, test", +); diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr index 397eeaf600ad..aee60c94f106 100644 --- a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr +++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr @@ -1,4 +1,4 @@ thread 'main' ($TID) panicked at $DIR/const-eval-select-backtrace-std.rs:6:8: -byte index 1 is out of bounds of `` +start byte index 1 is out of bounds of `` note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.stderr b/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.stderr deleted file mode 100644 index 861510212f92..000000000000 --- a/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: invalid character '$' in crate name: `need_crate_arg_ignore_tidy$x` - | - = help: you can either pass `--crate-name` on the command line or add `#![crate_name = "…"]` to set the crate name - -error: aborting due to 1 previous error - diff --git a/tests/ui/invalid/invalid-crate-type.rs b/tests/ui/invalid/invalid-crate-type.rs index 6c44c3b4f2b1..c233e7d5e3db 100644 --- a/tests/ui/invalid/invalid-crate-type.rs +++ b/tests/ui/invalid/invalid-crate-type.rs @@ -26,7 +26,7 @@ #![crate_type="dlib"] //~^ ERROR invalid `crate_type` value //~| HELP did you mean -//~| SUGGESTION rlib +//~| SUGGESTION lib #![crate_type="lob"] //~^ ERROR invalid `crate_type` value diff --git a/tests/ui/invalid/invalid-crate-type.stderr b/tests/ui/invalid/invalid-crate-type.stderr index 59d5d7bc9bbf..3eae04678b4a 100644 --- a/tests/ui/invalid/invalid-crate-type.stderr +++ b/tests/ui/invalid/invalid-crate-type.stderr @@ -34,7 +34,7 @@ error: invalid `crate_type` value --> $DIR/invalid-crate-type.rs:26:15 | LL | #![crate_type="dlib"] - | ^^^^^^ help: did you mean: `"rlib"` + | ^^^^^^ help: did you mean: `"lib"` error: invalid `crate_type` value --> $DIR/invalid-crate-type.rs:31:15 diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs index 73a0363904ae..03a28fac95de 100644 --- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.rs @@ -9,20 +9,24 @@ fn foo2() {} #[rustc_legacy_const_generics(2)] //~ ERROR index exceeds number of arguments fn foo3(_: u8) {} -#[rustc_legacy_const_generics(a)] //~ ERROR arguments should be non-negative integers +#[rustc_legacy_const_generics(a)] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo4() {} -#[rustc_legacy_const_generics(1, a, 2, b)] //~ ERROR arguments should be non-negative integers +#[rustc_legacy_const_generics(1, a, 2, b)] +//~^ ERROR malformed `rustc_legacy_const_generics` attribute input +//~^^ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo5() {} -#[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function +#[rustc_legacy_const_generics(0)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on structs struct S; -#[rustc_legacy_const_generics(0usize)] //~ ERROR suffixed literals are not allowed in attributes +#[rustc_legacy_const_generics(0usize)] +//~^ ERROR suffixed literals are not allowed in attributes +//~^^ ERROR malformed `rustc_legacy_const_generics` attribute input fn foo6() {} extern "C" { - #[rustc_legacy_const_generics(1)] //~ ERROR attribute should be applied to a function + #[rustc_legacy_const_generics(1)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on foreign functions fn foo7(); //~ ERROR foreign items may not have const parameters } @@ -30,14 +34,14 @@ extern "C" { fn foo8() {} impl S { - #[rustc_legacy_const_generics(0)] //~ ERROR attribute should be applied to a function + #[rustc_legacy_const_generics(0)] //~ ERROR `#[rustc_legacy_const_generics]` attribute cannot be used on inherent methods fn foo9() {} } -#[rustc_legacy_const_generics] //~ ERROR malformed `rustc_legacy_const_generics` attribute +#[rustc_legacy_const_generics] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn bar1() {} -#[rustc_legacy_const_generics = 1] //~ ERROR malformed `rustc_legacy_const_generics` attribute +#[rustc_legacy_const_generics = 1] //~ ERROR malformed `rustc_legacy_const_generics` attribute input fn bar2() {} fn main() {} diff --git a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr index 1ced1433fe95..e4da6c86c83e 100644 --- a/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr +++ b/tests/ui/invalid/invalid-rustc_legacy_const_generics-arguments.stderr @@ -1,22 +1,88 @@ +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:12:1 + | +LL | #[rustc_legacy_const_generics(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:1 + | +LL | #[rustc_legacy_const_generics(1, a, 2, b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:1 + | +LL | #[rustc_legacy_const_generics(1, a, 2, b)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on structs + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:20:1 + | +LL | #[rustc_legacy_const_generics(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + error: suffixed literals are not allowed in attributes - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:21:31 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:23:31 | LL | #[rustc_legacy_const_generics(0usize)] | ^^^^^^ | = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) -error: malformed `rustc_legacy_const_generics` attribute input - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:37:1 +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:23:1 + | +LL | #[rustc_legacy_const_generics(0usize)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on foreign functions + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:5 + | +LL | #[rustc_legacy_const_generics(1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + +error: `#[rustc_legacy_const_generics]` attribute cannot be used on inherent methods + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:37:5 + | +LL | #[rustc_legacy_const_generics(0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_legacy_const_generics]` can only be applied to functions + +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:41:1 | LL | #[rustc_legacy_const_generics] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` -error: malformed `rustc_legacy_const_generics` attribute input - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:40:1 +error[E0539]: malformed `rustc_legacy_const_generics` attribute input + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:44:1 | LL | #[rustc_legacy_const_generics = 1] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_legacy_const_generics(N)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | expected this to be a list + | help: must be of the form: `#[rustc_legacy_const_generics(N)]` error: #[rustc_legacy_const_generics] must have one index for each generic parameter --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:3:1 @@ -38,58 +104,23 @@ error: index exceeds number of arguments LL | #[rustc_legacy_const_generics(2)] | ^ there are only 2 arguments -error: arguments should be non-negative integers - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:12:31 - | -LL | #[rustc_legacy_const_generics(a)] - | ^ - -error: arguments should be non-negative integers - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:15:34 - | -LL | #[rustc_legacy_const_generics(1, a, 2, b)] - | ^ ^ - -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:18:1 - | -LL | #[rustc_legacy_const_generics(0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | struct S; - | --------- not a function definition - error: #[rustc_legacy_const_generics] functions must only have const generics - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:29:1 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:33:1 | LL | #[rustc_legacy_const_generics(0)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | fn foo8() {} | - non-const generic parameter -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:33:5 - | -LL | #[rustc_legacy_const_generics(0)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | fn foo9() {} - | ---------------------------- not a function definition - -error: attribute should be applied to a function definition - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:25:5 - | -LL | #[rustc_legacy_const_generics(1)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | fn foo7(); - | -------------------------- not a function definition - error[E0044]: foreign items may not have const parameters - --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:26:5 + --> $DIR/invalid-rustc_legacy_const_generics-arguments.rs:30:5 | LL | fn foo7(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters | = help: replace the const parameters with concrete consts -error: aborting due to 13 previous errors +error: aborting due to 15 previous errors -For more information about this error, try `rustc --explain E0044`. +Some errors have detailed explanations: E0044, E0539. +For more information about an error, try `rustc --explain E0044`. diff --git a/tests/ui/issues/auxiliary/issue-11529.rs b/tests/ui/issues/auxiliary/issue-11529.rs deleted file mode 100644 index dd3ef4387057..000000000000 --- a/tests/ui/issues/auxiliary/issue-11529.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct A<'a>(pub &'a isize); diff --git a/tests/ui/issues/auxiliary/issue-11680.rs b/tests/ui/issues/auxiliary/issue-11680.rs deleted file mode 100644 index 74abbf0bf8cd..000000000000 --- a/tests/ui/issues/auxiliary/issue-11680.rs +++ /dev/null @@ -1,9 +0,0 @@ -enum Foo { - Bar(isize) -} - -pub mod test { - enum Foo { - Bar(isize) - } -} diff --git a/tests/ui/issues/issue-10656.rs b/tests/ui/issues/issue-10656.rs deleted file mode 100644 index 250c4bc442f9..000000000000 --- a/tests/ui/issues/issue-10656.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![deny(missing_docs)] -#![crate_type="lib"] -//~^^ ERROR missing documentation for the crate diff --git a/tests/ui/issues/issue-10656.stderr b/tests/ui/issues/issue-10656.stderr deleted file mode 100644 index 61828f9c02a6..000000000000 --- a/tests/ui/issues/issue-10656.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: missing documentation for the crate - --> $DIR/issue-10656.rs:1:1 - | -LL | / #![deny(missing_docs)] -LL | | #![crate_type="lib"] - | |____________________^ - | -note: the lint level is defined here - --> $DIR/issue-10656.rs:1:9 - | -LL | #![deny(missing_docs)] - | ^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-11382.rs b/tests/ui/issues/issue-11382.rs deleted file mode 100644 index 18c8c756f32e..000000000000 --- a/tests/ui/issues/issue-11382.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ run-pass -fn main() { - println!("{}", 1.2); -} diff --git a/tests/ui/issues/issue-11384.rs b/tests/ui/issues/issue-11384.rs deleted file mode 100644 index ad0affa4b0d2..000000000000 --- a/tests/ui/issues/issue-11384.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ check-pass - -trait Common { fn dummy(&self) { } } - -impl<'t, T> Common for (T, &'t T) {} - -impl<'t, T> Common for (&'t T, T) {} - -fn main() {} diff --git a/tests/ui/issues/issue-11529.rs b/tests/ui/issues/issue-11529.rs deleted file mode 100644 index 73940c22be4c..000000000000 --- a/tests/ui/issues/issue-11529.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ aux-build:issue-11529.rs - - -extern crate issue_11529 as a; - -fn main() { - let one = 1; - let _a = a::A(&one); -} diff --git a/tests/ui/issues/issue-11680.rs b/tests/ui/issues/issue-11680.rs deleted file mode 100644 index 9f3dfebcc812..000000000000 --- a/tests/ui/issues/issue-11680.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ aux-build:issue-11680.rs - -extern crate issue_11680 as other; - -fn main() { - let _b = other::Foo::Bar(1); - //~^ ERROR: enum `Foo` is private - - let _b = other::test::Foo::Bar(1); - //~^ ERROR: enum `Foo` is private -} diff --git a/tests/ui/issues/issue-11680.stderr b/tests/ui/issues/issue-11680.stderr deleted file mode 100644 index 5bcf93de811f..000000000000 --- a/tests/ui/issues/issue-11680.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0603]: enum `Foo` is private - --> $DIR/issue-11680.rs:6:21 - | -LL | let _b = other::Foo::Bar(1); - | ^^^ --- tuple variant `Bar` is not publicly re-exported - | | - | private enum - | -note: the enum `Foo` is defined here - --> $DIR/auxiliary/issue-11680.rs:1:1 - | -LL | enum Foo { - | ^^^^^^^^ - -error[E0603]: enum `Foo` is private - --> $DIR/issue-11680.rs:9:27 - | -LL | let _b = other::test::Foo::Bar(1); - | ^^^ --- tuple variant `Bar` is not publicly re-exported - | | - | private enum - | -note: the enum `Foo` is defined here - --> $DIR/auxiliary/issue-11680.rs:6:5 - | -LL | enum Foo { - | ^^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/issues/issue-11681.rs b/tests/ui/issues/issue-11681.rs deleted file mode 100644 index 6d8810d80520..000000000000 --- a/tests/ui/issues/issue-11681.rs +++ /dev/null @@ -1,19 +0,0 @@ -// This tests verifies that unary structs and enum variants -// are treated as rvalues and their lifetime is not bounded to -// the static scope. - -struct Test; - -impl Drop for Test { - fn drop (&mut self) {} -} - -fn createTest<'a>() -> &'a Test { - let testValue = &Test; - return testValue; //~ ERROR cannot return value referencing temporary value -} - - -pub fn main() { - createTest(); -} diff --git a/tests/ui/issues/issue-11681.stderr b/tests/ui/issues/issue-11681.stderr deleted file mode 100644 index 4f23ba86eecc..000000000000 --- a/tests/ui/issues/issue-11681.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0515]: cannot return value referencing temporary value - --> $DIR/issue-11681.rs:13:10 - | -LL | let testValue = &Test; - | ---- temporary value created here -LL | return testValue; - | ^^^^^^^^^ returns a value referencing data owned by the current function - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/issues/issue-12660.rs b/tests/ui/issues/issue-12660.rs deleted file mode 100644 index 3aa3426519af..000000000000 --- a/tests/ui/issues/issue-12660.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass -//@ aux-build:issue-12660-aux.rs - - -extern crate issue12660aux; - -use issue12660aux::{my_fn, MyStruct}; - -#[allow(path_statements)] -fn main() { - my_fn(MyStruct); - MyStruct; -} diff --git a/tests/ui/issues/issue-16648.rs b/tests/ui/issues/issue-16648.rs deleted file mode 100644 index 7f3d3217bee0..000000000000 --- a/tests/ui/issues/issue-16648.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -fn main() { - let x: (isize, &[isize]) = (2, &[1, 2]); - assert_eq!(match x { - (0, &[_, _]) => 0, - (1, _) => 1, - (2, &[_, _]) => 2, - (2, _) => 3, - _ => 4 - }, 2); -} diff --git a/tests/ui/issues/issue-16683.rs b/tests/ui/issues/issue-16683.rs deleted file mode 100644 index 72fa21bddd18..000000000000 --- a/tests/ui/issues/issue-16683.rs +++ /dev/null @@ -1,9 +0,0 @@ -trait T<'a> { - fn a(&'a self) -> &'a bool; - fn b(&self) { - self.a(); - //~^ ERROR lifetime may not live long enough - } -} - -fn main() {} diff --git a/tests/ui/issues/issue-16683.stderr b/tests/ui/issues/issue-16683.stderr deleted file mode 100644 index 39b22ed1f156..000000000000 --- a/tests/ui/issues/issue-16683.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/issue-16683.rs:4:9 - | -LL | trait T<'a> { - | -- lifetime `'a` defined here -LL | fn a(&'a self) -> &'a bool; -LL | fn b(&self) { - | - let's call the lifetime of this reference `'1` -LL | self.a(); - | ^^^^^^^^ argument requires that `'1` must outlive `'a` - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-16725.rs b/tests/ui/issues/issue-16725.rs deleted file mode 100644 index 7741f828c474..000000000000 --- a/tests/ui/issues/issue-16725.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ aux-build:issue-16725.rs - -extern crate issue_16725 as foo; - -fn main() { - unsafe { foo::bar(); } - //~^ ERROR: function `bar` is private -} diff --git a/tests/ui/issues/issue-16725.stderr b/tests/ui/issues/issue-16725.stderr deleted file mode 100644 index dcb7d58b0f96..000000000000 --- a/tests/ui/issues/issue-16725.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0603]: function `bar` is private - --> $DIR/issue-16725.rs:6:19 - | -LL | unsafe { foo::bar(); } - | ^^^ private function - | -note: the function `bar` is defined here - --> $DIR/auxiliary/issue-16725.rs:2:5 - | -LL | fn bar(); - | ^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/issues/issue-16745.rs b/tests/ui/issues/issue-16745.rs deleted file mode 100644 index 99c85bcffcf8..000000000000 --- a/tests/ui/issues/issue-16745.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -fn main() { - const X: u8 = 0; - let out: u8 = match 0u8 { - X => 99, - b'\t' => 1, - 1u8 => 2, - _ => 3, - }; - assert_eq!(out, 99); -} diff --git a/tests/ui/issues/issue-16783.rs b/tests/ui/issues/issue-16783.rs deleted file mode 100644 index 2ecc42b579d5..000000000000 --- a/tests/ui/issues/issue-16783.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass -#![allow(unused_variables)] - -pub fn main() { - let x = [1, 2, 3]; - let y = x; -} diff --git a/tests/ui/issues/issue-16819.rs b/tests/ui/issues/issue-16819.rs deleted file mode 100644 index 2805c82acfb2..000000000000 --- a/tests/ui/issues/issue-16819.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -#![allow(unused_variables)] -// `#[cfg]` on struct field permits empty unusable struct - -struct S { - #[cfg(false)] - a: int, -} - -fn main() { - let s = S {}; -} diff --git a/tests/ui/issues/issue-16966.rs b/tests/ui/issues/issue-16966.rs deleted file mode 100644 index 66a3fadac8d9..000000000000 --- a/tests/ui/issues/issue-16966.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ edition:2015..2021 -fn main() { - panic!(std::default::Default::default()); - //~^ ERROR type annotations needed -} diff --git a/tests/ui/issues/issue-16966.stderr b/tests/ui/issues/issue-16966.stderr deleted file mode 100644 index e294d8830de0..000000000000 --- a/tests/ui/issues/issue-16966.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0283]: type annotations needed - --> $DIR/issue-16966.rs:3:12 - | -LL | panic!(std::default::Default::default()); - | -------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- - | | | - | | cannot infer type - | required by a bound introduced by this call - | - = note: cannot satisfy `_: Any` -note: required by a bound in `begin_panic` - --> $SRC_DIR/std/src/panicking.rs:LL:COL - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/issues/issue-17001.rs b/tests/ui/issues/issue-17001.rs deleted file mode 100644 index 68cb2865fdc8..000000000000 --- a/tests/ui/issues/issue-17001.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod foo {} - -fn main() { - let p = foo { x: () }; //~ ERROR expected struct, variant or union type, found module `foo` -} diff --git a/tests/ui/issues/issue-17001.stderr b/tests/ui/issues/issue-17001.stderr deleted file mode 100644 index 6ea32e0a45c3..000000000000 --- a/tests/ui/issues/issue-17001.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found module `foo` - --> $DIR/issue-17001.rs:4:13 - | -LL | let p = foo { x: () }; - | ^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/issues/issue-17068.rs b/tests/ui/issues/issue-17068.rs deleted file mode 100644 index af565da3366b..000000000000 --- a/tests/ui/issues/issue-17068.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -// Test that regionck creates the right region links in the pattern -// binding of a for loop - -fn foo<'a>(v: &'a [usize]) -> &'a usize { - for &ref x in v { return x; } - unreachable!() -} - -fn main() { - assert_eq!(foo(&[0]), &0); -} diff --git a/tests/ui/issues/issue-17351.rs b/tests/ui/issues/issue-17351.rs deleted file mode 100644 index 86049377198c..000000000000 --- a/tests/ui/issues/issue-17351.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass - -trait Str { fn foo(&self) {} } //~ WARN method `foo` is never used -impl Str for str {} -impl<'a, S: ?Sized> Str for &'a S where S: Str {} - -fn main() { - let _: &dyn Str = &"x"; -} diff --git a/tests/ui/issues/issue-17351.stderr b/tests/ui/issues/issue-17351.stderr deleted file mode 100644 index 043d4ffc7808..000000000000 --- a/tests/ui/issues/issue-17351.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: method `foo` is never used - --> $DIR/issue-17351.rs:3:16 - | -LL | trait Str { fn foo(&self) {} } - | --- ^^^ - | | - | method in this trait - | - = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default - -warning: 1 warning emitted - diff --git a/tests/ui/issues/issue-17361.rs b/tests/ui/issues/issue-17361.rs deleted file mode 100644 index 6f6fc42db383..000000000000 --- a/tests/ui/issues/issue-17361.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -// Test that HIR ty lowering doesn't forget about mutability of `&mut str`. - - -fn main() { - fn foo(_: &mut T) {} - let _f: fn(&mut str) = foo; -} diff --git a/tests/ui/issues/issue-17373.rs b/tests/ui/issues/issue-17373.rs deleted file mode 100644 index dc3be48a7ead..000000000000 --- a/tests/ui/issues/issue-17373.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - *return //~ ERROR type `!` cannot be dereferenced - ; -} diff --git a/tests/ui/issues/issue-17373.stderr b/tests/ui/issues/issue-17373.stderr deleted file mode 100644 index 0e16d08c87d3..000000000000 --- a/tests/ui/issues/issue-17373.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0614]: type `!` cannot be dereferenced - --> $DIR/issue-17373.rs:2:5 - | -LL | *return - | ^^^^^^^ can't be dereferenced - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0614`. diff --git a/tests/ui/issues/issue-17405.rs b/tests/ui/issues/issue-17405.rs deleted file mode 100644 index 14781a7d3f7e..000000000000 --- a/tests/ui/issues/issue-17405.rs +++ /dev/null @@ -1,9 +0,0 @@ -enum Foo { - Bar(isize) -} - -fn main() { - match Foo::Bar(1) { - Foo { i } => () //~ ERROR expected struct, variant or union type, found enum `Foo` - } -} diff --git a/tests/ui/issues/issue-17405.stderr b/tests/ui/issues/issue-17405.stderr deleted file mode 100644 index 47f5bf4dc330..000000000000 --- a/tests/ui/issues/issue-17405.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found enum `Foo` - --> $DIR/issue-17405.rs:7:9 - | -LL | Foo { i } => () - | ^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/issues/issue-17441.rs b/tests/ui/issues/issue-17441.rs deleted file mode 100644 index e5f83c4ebadd..000000000000 --- a/tests/ui/issues/issue-17441.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - let _foo = &[1_usize, 2] as [usize]; - //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]` - - let _bar = Box::new(1_usize) as dyn std::fmt::Debug; - //~^ ERROR cast to unsized type: `Box` as `dyn Debug` - - let _baz = 1_usize as dyn std::fmt::Debug; - //~^ ERROR cast to unsized type: `usize` as `dyn Debug` - - let _quux = [1_usize, 2] as [usize]; - //~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]` -} diff --git a/tests/ui/issues/issue-17441.stderr b/tests/ui/issues/issue-17441.stderr deleted file mode 100644 index 96aad879e24d..000000000000 --- a/tests/ui/issues/issue-17441.stderr +++ /dev/null @@ -1,49 +0,0 @@ -error[E0620]: cast to unsized type: `&[usize; 2]` as `[usize]` - --> $DIR/issue-17441.rs:2:16 - | -LL | let _foo = &[1_usize, 2] as [usize]; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider casting to a reference instead - | -LL | let _foo = &[1_usize, 2] as &[usize]; - | + - -error[E0620]: cast to unsized type: `Box` as `dyn Debug` - --> $DIR/issue-17441.rs:5:16 - | -LL | let _bar = Box::new(1_usize) as dyn std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: you can cast to a `Box` instead - | -LL | let _bar = Box::new(1_usize) as Box; - | ++++ + - -error[E0620]: cast to unsized type: `usize` as `dyn Debug` - --> $DIR/issue-17441.rs:8:16 - | -LL | let _baz = 1_usize as dyn std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using a box or reference as appropriate - --> $DIR/issue-17441.rs:8:16 - | -LL | let _baz = 1_usize as dyn std::fmt::Debug; - | ^^^^^^^ - -error[E0620]: cast to unsized type: `[usize; 2]` as `[usize]` - --> $DIR/issue-17441.rs:11:17 - | -LL | let _quux = [1_usize, 2] as [usize]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | -help: consider using a box or reference as appropriate - --> $DIR/issue-17441.rs:11:17 - | -LL | let _quux = [1_usize, 2] as [usize]; - | ^^^^^^^^^^^^ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0620`. diff --git a/tests/ui/issues/issue-17450.rs b/tests/ui/issues/issue-17450.rs deleted file mode 100644 index d8b20169ee0c..000000000000 --- a/tests/ui/issues/issue-17450.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ build-pass -#![allow(dead_code, warnings)] - -static mut x: isize = 3; -static mut y: isize = unsafe { x }; - -fn main() {} diff --git a/tests/ui/issues/issue-17503.rs b/tests/ui/issues/issue-17503.rs deleted file mode 100644 index 6c966b5319cd..000000000000 --- a/tests/ui/issues/issue-17503.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -fn main() { - let s: &[isize] = &[0, 1, 2, 3, 4]; - let ss: &&[isize] = &s; - let sss: &&&[isize] = &ss; - - println!("{:?}", &s[..3]); - println!("{:?}", &ss[3..]); - println!("{:?}", &sss[2..4]); -} diff --git a/tests/ui/issues/issue-17651.rs b/tests/ui/issues/issue-17651.rs deleted file mode 100644 index 7629a5a3be1e..000000000000 --- a/tests/ui/issues/issue-17651.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Test that moves of unsized values within closures are caught -// and rejected. - -fn main() { - (|| Box::new(*(&[0][..])))(); - //~^ ERROR the size for values of type -} diff --git a/tests/ui/issues/issue-17651.stderr b/tests/ui/issues/issue-17651.stderr deleted file mode 100644 index 9519507320d8..000000000000 --- a/tests/ui/issues/issue-17651.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time - --> $DIR/issue-17651.rs:5:18 - | -LL | (|| Box::new(*(&[0][..])))(); - | -------- ^^^^^^^^^^^ doesn't have a size known at compile-time - | | - | required by a bound introduced by this call - | - = help: the trait `Sized` is not implemented for `[{integer}]` -note: required by a bound in `Box::::new` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression - | -LL - (|| Box::new(*(&[0][..])))(); -LL + (|| Box::new((&[0][..])))(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-17758.rs b/tests/ui/issues/issue-17758.rs deleted file mode 100644 index e2ee84694e39..000000000000 --- a/tests/ui/issues/issue-17758.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Test that regionck suggestions in a provided method of a trait -// don't ICE - -trait Foo<'a> { - fn foo(&'a self); - fn bar(&self) { - self.foo(); - //~^ ERROR lifetime may not live long enough - } -} - -fn main() {} diff --git a/tests/ui/issues/issue-17758.stderr b/tests/ui/issues/issue-17758.stderr deleted file mode 100644 index 7a7d2374ef87..000000000000 --- a/tests/ui/issues/issue-17758.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/issue-17758.rs:7:9 - | -LL | trait Foo<'a> { - | -- lifetime `'a` defined here -LL | fn foo(&'a self); -LL | fn bar(&self) { - | - let's call the lifetime of this reference `'1` -LL | self.foo(); - | ^^^^^^^^^^ argument requires that `'1` must outlive `'a` - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-17877.rs b/tests/ui/issues/issue-17877.rs deleted file mode 100644 index 7df0fffa41c8..000000000000 --- a/tests/ui/issues/issue-17877.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass - -fn main() { - assert_eq!(match [0u8; 1024] { - _ => 42_usize, - }, 42_usize); - - assert_eq!(match [0u8; 1024] { - [1, ..] => 0_usize, - [0, ..] => 1_usize, - _ => 2_usize - }, 1_usize); -} diff --git a/tests/ui/issues/issue-17933.rs b/tests/ui/issues/issue-17933.rs deleted file mode 100644 index 6da4e6e15284..000000000000 --- a/tests/ui/issues/issue-17933.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub static X: usize = 1; - -fn main() { - match 1 { - self::X => { }, - //~^ ERROR expected unit struct, unit variant or constant, found static `self::X` - _ => { }, - } -} diff --git a/tests/ui/issues/issue-17933.stderr b/tests/ui/issues/issue-17933.stderr deleted file mode 100644 index 42a7e0442073..000000000000 --- a/tests/ui/issues/issue-17933.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0532]: expected unit struct, unit variant or constant, found static `self::X` - --> $DIR/issue-17933.rs:5:9 - | -LL | self::X => { }, - | ^^^^^^^ not a unit struct, unit variant or constant - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0532`. diff --git a/tests/ui/issues/issue-17994.rs b/tests/ui/issues/issue-17994.rs deleted file mode 100644 index ab37a172eaa7..000000000000 --- a/tests/ui/issues/issue-17994.rs +++ /dev/null @@ -1,3 +0,0 @@ -trait Tr {} -type Huh where T: Tr = isize; //~ ERROR type parameter `T` is never used -fn main() {} diff --git a/tests/ui/issues/issue-17994.stderr b/tests/ui/issues/issue-17994.stderr deleted file mode 100644 index f149e5d08faa..000000000000 --- a/tests/ui/issues/issue-17994.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0091]: type parameter `T` is never used - --> $DIR/issue-17994.rs:2:10 - | -LL | type Huh where T: Tr = isize; - | ^ unused type parameter - | - = help: consider removing `T` or referring to it in the body of the type alias - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0091`. diff --git a/tests/ui/issues/issue-18110.rs b/tests/ui/issues/issue-18110.rs deleted file mode 100644 index 6d563a5bae1c..000000000000 --- a/tests/ui/issues/issue-18110.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-pass -#![allow(unreachable_code)] - -fn main() { - ({return},); -} diff --git a/tests/ui/issues/issue-18119.rs b/tests/ui/issues/issue-18119.rs deleted file mode 100644 index e48dc51a2c64..000000000000 --- a/tests/ui/issues/issue-18119.rs +++ /dev/null @@ -1,12 +0,0 @@ -const X: u8 = 1; -static Y: u8 = 1; -fn foo() {} - -impl X {} -//~^ ERROR expected type, found constant `X` -impl Y {} -//~^ ERROR expected type, found static `Y` -impl foo {} -//~^ ERROR expected type, found function `foo` - -fn main() {} diff --git a/tests/ui/issues/issue-18119.stderr b/tests/ui/issues/issue-18119.stderr deleted file mode 100644 index ddee5a9da7a4..000000000000 --- a/tests/ui/issues/issue-18119.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0573]: expected type, found constant `X` - --> $DIR/issue-18119.rs:5:6 - | -LL | impl X {} - | ^ not a type - -error[E0573]: expected type, found static `Y` - --> $DIR/issue-18119.rs:7:6 - | -LL | impl Y {} - | ^ not a type - -error[E0573]: expected type, found function `foo` - --> $DIR/issue-18119.rs:9:6 - | -LL | impl foo {} - | ^^^ not a type - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/issues/issue-18159.rs b/tests/ui/issues/issue-18159.rs deleted file mode 100644 index bd347d632984..000000000000 --- a/tests/ui/issues/issue-18159.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - let x; //~ ERROR type annotations needed -} diff --git a/tests/ui/issues/issue-18159.stderr b/tests/ui/issues/issue-18159.stderr deleted file mode 100644 index 5de13a5c314c..000000000000 --- a/tests/ui/issues/issue-18159.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-18159.rs:2:9 - | -LL | let x; - | ^ - | -help: consider giving `x` an explicit type - | -LL | let x: /* Type */; - | ++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-18352.rs b/tests/ui/issues/issue-18352.rs deleted file mode 100644 index 8b6aa82ea8c0..000000000000 --- a/tests/ui/issues/issue-18352.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass - -const X: &'static str = "12345"; - -fn test(s: String) -> bool { - match &*s { - X => true, - _ => false - } -} - -fn main() { - assert!(test("12345".to_string())); -} diff --git a/tests/ui/issues/issue-18353.rs b/tests/ui/issues/issue-18353.rs deleted file mode 100644 index 378caa9f3697..000000000000 --- a/tests/ui/issues/issue-18353.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -// Test that wrapping an unsized struct in an enum which gets optimised does -// not ICE. - - -struct Str { - f: [u8] -} - -fn main() { - let str: Option<&Str> = None; - let _ = str.is_some(); -} diff --git a/tests/ui/issues/issue-18389.rs b/tests/ui/issues/issue-18389.rs deleted file mode 100644 index 0ab3f1454572..000000000000 --- a/tests/ui/issues/issue-18389.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ check-pass - -use std::any::Any; -use std::any::TypeId; - -trait Private { - fn call(&self, p: P, r: R); -} -pub trait Public: Private< -//~^ WARNING trait `Private<::P, ::R>` is more private than the item `Public` - ::P, - ::R -> { - type P; - type R; - - fn call_inner(&self); -} - -fn main() {} diff --git a/tests/ui/issues/issue-18389.stderr b/tests/ui/issues/issue-18389.stderr deleted file mode 100644 index 4706d1ba1779..000000000000 --- a/tests/ui/issues/issue-18389.stderr +++ /dev/null @@ -1,19 +0,0 @@ -warning: trait `Private<::P, ::R>` is more private than the item `Public` - --> $DIR/issue-18389.rs:9:1 - | -LL | / pub trait Public: Private< -LL | | -LL | | ::P, -LL | | ::R -LL | | > { - | |_^ trait `Public` is reachable at visibility `pub` - | -note: but trait `Private<::P, ::R>` is only usable at visibility `pub(crate)` - --> $DIR/issue-18389.rs:6:1 - | -LL | trait Private { - | ^^^^^^^^^^^^^^^^^^^ - = note: `#[warn(private_bounds)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/issues/issue-18423.rs b/tests/ui/issues/issue-18423.rs deleted file mode 100644 index 675fd041154b..000000000000 --- a/tests/ui/issues/issue-18423.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Test that `Box` cannot be used with a lifetime argument. - -struct Foo<'a> { - x: Box<'a, isize> - //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied -} - -fn main() { } diff --git a/tests/ui/issues/issue-18423.stderr b/tests/ui/issues/issue-18423.stderr deleted file mode 100644 index b5f19b5c9b23..000000000000 --- a/tests/ui/issues/issue-18423.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/issue-18423.rs:4:8 - | -LL | x: Box<'a, isize> - | ^^^ -- help: remove the lifetime argument - | | - | expected 0 lifetime arguments - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/issues/issue-18464.rs b/tests/ui/issues/issue-18464.rs deleted file mode 100644 index 995064719839..000000000000 --- a/tests/ui/issues/issue-18464.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -#![deny(dead_code)] - -const LOW_RANGE: char = '0'; -const HIGH_RANGE: char = '9'; - -fn main() { - match '5' { - LOW_RANGE..=HIGH_RANGE => (), - _ => () - }; -} diff --git a/tests/ui/issues/issue-18532.rs b/tests/ui/issues/issue-18532.rs deleted file mode 100644 index 31fd87961dc9..000000000000 --- a/tests/ui/issues/issue-18532.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Test that overloaded call parameter checking does not ICE -// when a type error or unconstrained type variable propagates -// into it. - -fn main() { - (return)((),()); //~ ERROR expected function, found `!` -} diff --git a/tests/ui/issues/issue-18532.stderr b/tests/ui/issues/issue-18532.stderr deleted file mode 100644 index 059c7f137819..000000000000 --- a/tests/ui/issues/issue-18532.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0618]: expected function, found `!` - --> $DIR/issue-18532.rs:6:5 - | -LL | (return)((),()); - | ^^^^^^^^------- - | | - | call expression requires function - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/issues/issue-18767.rs b/tests/ui/issues/issue-18767.rs deleted file mode 100644 index 87762406da60..000000000000 --- a/tests/ui/issues/issue-18767.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -// Test that regionck uses the right memcat for patterns in for loops -// and doesn't ICE. - - -fn main() { - for &&x in Some(&0_usize).iter() { - assert_eq!(x, 0) - } -} diff --git a/tests/ui/issues/issue-19097.rs b/tests/ui/issues/issue-19097.rs deleted file mode 100644 index a329ba6f073e..000000000000 --- a/tests/ui/issues/issue-19097.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -// regression test for #19097 - -struct Foo(T); - -impl<'a, T> Foo<&'a T> { - fn foo(&self) {} -} -impl<'a, T> Foo<&'a mut T> { - fn foo(&self) {} -} - -fn main() {} diff --git a/tests/ui/issues/issue-19398.rs b/tests/ui/issues/issue-19398.rs deleted file mode 100644 index 473e43650c2c..000000000000 --- a/tests/ui/issues/issue-19398.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ check-pass - -trait T { - unsafe extern "Rust" fn foo(&self); -} - -impl T for () { - unsafe extern "Rust" fn foo(&self) {} -} - -fn main() {} diff --git a/tests/ui/issues/issue-19482.stderr b/tests/ui/issues/issue-19482.stderr index 903a9f98c758..7683e16610e6 100644 --- a/tests/ui/issues/issue-19482.stderr +++ b/tests/ui/issues/issue-19482.stderr @@ -5,7 +5,7 @@ LL | type A; | ------ `A` defined here ... LL | fn bar(x: &dyn Foo) {} - | ^^^ help: specify the associated type: `Foo` + | ^^^ help: specify the associated type: `Foo` error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-19499.rs b/tests/ui/issues/issue-19499.rs deleted file mode 100644 index d2a6862e05c4..000000000000 --- a/tests/ui/issues/issue-19499.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -#![allow(path_statements)] -#![allow(unused_variables)] -// Regression test for issue #19499. Due to incorrect caching of trait -// results for closures with upvars whose types were not fully -// computed, this rather bizarre little program (along with many more -// reasonable examples) let to ambiguity errors about not being able -// to infer sufficient type information. - - -fn main() { - let n = 0; - let it = Some(1_usize).into_iter().inspect(|_| {n;}); -} diff --git a/tests/ui/issues/issue-19601.rs b/tests/ui/issues/issue-19601.rs deleted file mode 100644 index e97819e4122d..000000000000 --- a/tests/ui/issues/issue-19601.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ check-pass - -trait A {} -struct B where B: A> { t: T } - -fn main() {} diff --git a/tests/ui/issues/issue-19692.rs b/tests/ui/issues/issue-19692.rs deleted file mode 100644 index 99eccc8a8175..000000000000 --- a/tests/ui/issues/issue-19692.rs +++ /dev/null @@ -1,8 +0,0 @@ -struct Homura; - -fn akemi(homura: Homura) { - let Some(ref madoka) = Some(homura.kaname()); //~ ERROR no method named `kaname` found - madoka.clone(); -} - -fn main() { } diff --git a/tests/ui/issues/issue-19692.stderr b/tests/ui/issues/issue-19692.stderr deleted file mode 100644 index 1e3d7a2e2f51..000000000000 --- a/tests/ui/issues/issue-19692.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `kaname` found for struct `Homura` in the current scope - --> $DIR/issue-19692.rs:4:40 - | -LL | struct Homura; - | ------------- method `kaname` not found for this struct -... -LL | let Some(ref madoka) = Some(homura.kaname()); - | ^^^^^^ method not found in `Homura` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-19734.rs b/tests/ui/issues/issue-19734.rs deleted file mode 100644 index fe4a327aef49..000000000000 --- a/tests/ui/issues/issue-19734.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() {} - -struct Type; - -impl Type { - undef!(); - //~^ ERROR cannot find macro `undef` in this scope -} diff --git a/tests/ui/issues/issue-19734.stderr b/tests/ui/issues/issue-19734.stderr deleted file mode 100644 index ed48714fe507..000000000000 --- a/tests/ui/issues/issue-19734.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: cannot find macro `undef` in this scope - --> $DIR/issue-19734.rs:6:5 - | -LL | undef!(); - | ^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-19922.rs b/tests/ui/issues/issue-19922.rs deleted file mode 100644 index fede86f22afd..000000000000 --- a/tests/ui/issues/issue-19922.rs +++ /dev/null @@ -1,8 +0,0 @@ -enum Homura { - Akemi { madoka: () } -} - -fn main() { - let homura = Homura::Akemi { kaname: () }; - //~^ ERROR variant `Homura::Akemi` has no field named `kaname` -} diff --git a/tests/ui/issues/issue-19922.stderr b/tests/ui/issues/issue-19922.stderr deleted file mode 100644 index 0355d3a89710..000000000000 --- a/tests/ui/issues/issue-19922.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0559]: variant `Homura::Akemi` has no field named `kaname` - --> $DIR/issue-19922.rs:6:34 - | -LL | let homura = Homura::Akemi { kaname: () }; - | ^^^^^^ `Homura::Akemi` does not have this field - | - = note: available fields are: `madoka` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0559`. diff --git a/tests/ui/issues/issue-20162.rs b/tests/ui/issues/issue-20162.rs deleted file mode 100644 index b491bc37f515..000000000000 --- a/tests/ui/issues/issue-20162.rs +++ /dev/null @@ -1,7 +0,0 @@ -struct X { x: i32 } - -fn main() { - let mut b: Vec = vec![]; - b.sort(); - //~^ ERROR `X: Ord` is not satisfied -} diff --git a/tests/ui/issues/issue-20162.stderr b/tests/ui/issues/issue-20162.stderr deleted file mode 100644 index 8f45f0d36c71..000000000000 --- a/tests/ui/issues/issue-20162.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0277]: the trait bound `X: Ord` is not satisfied - --> $DIR/issue-20162.rs:5:7 - | -LL | b.sort(); - | ^^^^ the trait `Ord` is not implemented for `X` - | -note: required by a bound in `slice::::sort` - --> $SRC_DIR/alloc/src/slice.rs:LL:COL -help: consider annotating `X` with `#[derive(Ord)]` - | -LL + #[derive(Ord)] -LL | struct X { x: i32 } - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-20427.rs b/tests/ui/issues/issue-20427.rs deleted file mode 100644 index 4018043c371e..000000000000 --- a/tests/ui/issues/issue-20427.rs +++ /dev/null @@ -1,88 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_imports)] -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(deprecated, deprecated_in_future)] - -//@ aux-build:i8.rs - -extern crate i8; -use std::string as i16; -static i32: i32 = 0; -const i64: i64 = 0; -fn u8(f32: f32) {} -fn f(f64: f64) {} -enum u32 {} -struct u64; -trait bool {} - -mod char { - extern crate i8; - static i32_: i32 = 0; - const i64_: i64 = 0; - fn u8_(f32: f32) {} - fn f_(f64: f64_) {} - type u16_ = u16; - enum u32_ {} - struct u64_; - trait bool_ {} - mod char_ {} - - mod str { - use super::i8 as i8; - use super::i32_ as i32; - use super::i64_ as i64; - use super::u8_ as u8; - use super::f_ as f64; - use super::u16_ as u16; - use super::u32_ as u32; - use super::u64_ as u64; - use super::bool_ as bool; - use super::{bool_ as str}; - use super::char_ as char; - } -} - -trait isize_ { - type isize; -} - -fn usize<'usize>(usize: &'usize usize) -> &'usize usize { usize } - -mod reuse { - use std::mem::size_of; - - type u8 = u64; - use std::string::String as i16; - - pub fn check() { - assert_eq!(size_of::(), 8); - assert_eq!(size_of::(), 0); - assert_eq!(size_of::(), 3 * size_of::<*const ()>()); - assert_eq!(size_of::(), 0); - } -} - -mod guard { - pub fn check() { - use std::u8; // bring module u8 in scope - fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8 - u8::max_value() // OK, resolves to associated function ::max_value, - // not to non-existent std::u8::max_value - } - assert_eq!(f(), u8::MAX); // OK, resolves to std::u8::MAX - } -} - -fn main() { - let bool = true; - let _ = match bool { - str @ true => if str { i32 as i64 } else { i64 }, - false => i64, - }; - - reuse::check::(); - guard::check(); -} diff --git a/tests/ui/issues/issue-20454.rs b/tests/ui/issues/issue-20454.rs deleted file mode 100644 index e56f2ffa371a..000000000000 --- a/tests/ui/issues/issue-20454.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ check-pass -#![allow(unused_must_use)] -use std::thread; - -fn _foo() { - thread::spawn(move || { // no need for -> () - loop { - println!("hello"); - } - }).join(); -} - -fn main() {} diff --git a/tests/ui/issues/issue-20644.rs b/tests/ui/issues/issue-20644.rs index 5f7e4054f776..09a2ee7217c3 100644 --- a/tests/ui/issues/issue-20644.rs +++ b/tests/ui/issues/issue-20644.rs @@ -1,14 +1,10 @@ //@ build-pass #![allow(dead_code)] #![allow(unused_imports)] -#![allow(stable_features)] // A reduced version of the rustbook ice. The problem this encountered // had to do with codegen ignoring binders. - -#![feature(os)] - use std::iter; use std::os; use std::fs::File; diff --git a/tests/ui/issues/issue-20676.rs b/tests/ui/issues/issue-20676.rs deleted file mode 100644 index 2059365c7d62..000000000000 --- a/tests/ui/issues/issue-20676.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -// Regression test for #20676. Error was that we didn't support -// UFCS-style calls to a method in `Trait` where `Self` was bound to a -// trait object of type `Trait`. See also `ufcs-trait-object.rs`. - - -use std::fmt; - -fn main() { - let a: &dyn fmt::Debug = &1; - let _ = format!("{:?}", a); -} diff --git a/tests/ui/issues/issue-20714.rs b/tests/ui/issues/issue-20714.rs deleted file mode 100644 index 3aa39bb7388f..000000000000 --- a/tests/ui/issues/issue-20714.rs +++ /dev/null @@ -1,5 +0,0 @@ -struct G; - -fn main() { - let g = G(); //~ ERROR: expected function, found struct `G` -} diff --git a/tests/ui/issues/issue-20714.stderr b/tests/ui/issues/issue-20714.stderr deleted file mode 100644 index f537a01582b6..000000000000 --- a/tests/ui/issues/issue-20714.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0618]: expected function, found struct `G` - --> $DIR/issue-20714.rs:4:13 - | -LL | struct G; - | -------- struct `G` defined here -... -LL | let g = G(); - | ^-- - | | - | call expression requires function - | -help: `G` is a unit struct, and does not take parentheses to be constructed - | -LL - let g = G(); -LL + let g = G; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/issues/issue-2074.rs b/tests/ui/issues/issue-2074.rs deleted file mode 100644 index b6e3fb1fa23a..000000000000 --- a/tests/ui/issues/issue-2074.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass - -#![allow(non_camel_case_types)] - -pub fn main() { - let one = || { - enum r { a } - r::a as usize - }; - let two = || { - enum r { a } - r::a as usize - }; - one(); two(); -} diff --git a/tests/ui/issues/issue-20772.rs b/tests/ui/issues/issue-20772.rs deleted file mode 100644 index 1500bc831528..000000000000 --- a/tests/ui/issues/issue-20772.rs +++ /dev/null @@ -1,5 +0,0 @@ -trait T : Iterator -//~^ ERROR cycle detected -{} - -fn main() {} diff --git a/tests/ui/issues/issue-20772.stderr b/tests/ui/issues/issue-20772.stderr deleted file mode 100644 index 81f80aef5944..000000000000 --- a/tests/ui/issues/issue-20772.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0391]: cycle detected when computing the super traits of `T` with associated type name `Item` - --> $DIR/issue-20772.rs:1:1 - | -LL | trait T : Iterator - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: ...which immediately requires computing the super traits of `T` with associated type name `Item` again -note: cycle used when computing the super predicates of `T` - --> $DIR/issue-20772.rs:1:1 - | -LL | trait T : Iterator - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/issues/issue-20847.rs b/tests/ui/issues/issue-20847.rs deleted file mode 100644 index 364b07bf6922..000000000000 --- a/tests/ui/issues/issue-20847.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -#![feature(fn_traits)] - -fn say(x: u32, y: u32) { - println!("{} {}", x, y); -} - -fn main() { - Fn::call(&say, (1, 2)); -} diff --git a/tests/ui/issues/issue-21177.rs b/tests/ui/issues/issue-21177.rs deleted file mode 100644 index 258e362d1317..000000000000 --- a/tests/ui/issues/issue-21177.rs +++ /dev/null @@ -1,9 +0,0 @@ -trait Trait { - type A; - type B; -} - -fn foo>() { } -//~^ ERROR cycle detected - -fn main() { } diff --git a/tests/ui/issues/issue-21177.stderr b/tests/ui/issues/issue-21177.stderr deleted file mode 100644 index 9f66f43a195a..000000000000 --- a/tests/ui/issues/issue-21177.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0391]: cycle detected when computing the bounds for type parameter `T` - --> $DIR/issue-21177.rs:6:21 - | -LL | fn foo>() { } - | ^^^^ - | - = note: ...which immediately requires computing the bounds for type parameter `T` again -note: cycle used when computing explicit predicates of `foo` - --> $DIR/issue-21177.rs:6:21 - | -LL | fn foo>() { } - | ^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/issues/issue-21291.rs b/tests/ui/issues/issue-21291.rs deleted file mode 100644 index 06f50ac6996d..000000000000 --- a/tests/ui/issues/issue-21291.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ needs-threads - -// Regression test for unwrapping the result of `join`, issue #21291 - -use std::thread; - -fn main() { - thread::spawn(|| {}).join().unwrap() -} diff --git a/tests/ui/issues/issue-21306.rs b/tests/ui/issues/issue-21306.rs deleted file mode 100644 index bf42e70a5bc0..000000000000 --- a/tests/ui/issues/issue-21306.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass - -use std::sync::Arc; - -fn main() { - let x = 5; - let command = Arc::new(Box::new(|| { x*2 })); - assert_eq!(command(), 10); -} diff --git a/tests/ui/issues/issue-21449.rs b/tests/ui/issues/issue-21449.rs deleted file mode 100644 index 00ce2b7fffa8..000000000000 --- a/tests/ui/issues/issue-21449.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod MyMod {} - -fn main() { - let myVar = MyMod { T: 0 }; - //~^ ERROR expected struct, variant or union type, found module `MyMod` -} diff --git a/tests/ui/issues/issue-21449.stderr b/tests/ui/issues/issue-21449.stderr deleted file mode 100644 index cd1059d48993..000000000000 --- a/tests/ui/issues/issue-21449.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found module `MyMod` - --> $DIR/issue-21449.rs:4:17 - | -LL | let myVar = MyMod { T: 0 }; - | ^^^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/issues/issue-2151.rs b/tests/ui/issues/issue-2151.rs deleted file mode 100644 index 82cf49de8227..000000000000 --- a/tests/ui/issues/issue-2151.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let x = panic!(); //~ ERROR type annotations needed - x.clone(); -} diff --git a/tests/ui/issues/issue-2151.stderr b/tests/ui/issues/issue-2151.stderr deleted file mode 100644 index b130f162414d..000000000000 --- a/tests/ui/issues/issue-2151.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-2151.rs:2:9 - | -LL | let x = panic!(); - | ^ -LL | x.clone(); - | - type must be known at this point - | -help: consider giving `x` an explicit type - | -LL | let x: /* Type */ = panic!(); - | ++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-21554.rs b/tests/ui/issues/issue-21554.rs deleted file mode 100644 index c176b1247cea..000000000000 --- a/tests/ui/issues/issue-21554.rs +++ /dev/null @@ -1,6 +0,0 @@ -struct Inches(i32); - -fn main() { - Inches as f32; - //~^ ERROR casting -} diff --git a/tests/ui/issues/issue-21554.stderr b/tests/ui/issues/issue-21554.stderr deleted file mode 100644 index b1b59af6ec2b..000000000000 --- a/tests/ui/issues/issue-21554.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0606]: casting `fn(i32) -> Inches {Inches}` as `f32` is invalid - --> $DIR/issue-21554.rs:4:5 - | -LL | Inches as f32; - | ^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/issues/issue-21634.rs b/tests/ui/issues/issue-21634.rs index 270a893474ad..475a33eca58e 100644 --- a/tests/ui/issues/issue-21634.rs +++ b/tests/ui/issues/issue-21634.rs @@ -1,7 +1,4 @@ //@ run-pass -#![allow(stable_features)] - -#![feature(cfg_target_feature)] #[cfg(any(not(target_arch = "x86"), target_feature = "sse2"))] fn main() { diff --git a/tests/ui/issues/issue-21891.rs b/tests/ui/issues/issue-21891.rs deleted file mode 100644 index 0da6071cdac4..000000000000 --- a/tests/ui/issues/issue-21891.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ build-pass -#![allow(dead_code)] -#![allow(non_upper_case_globals)] - - -static foo: [usize; 3] = [1, 2, 3]; - -static slice_1: &'static [usize] = &foo; -static slice_2: &'static [usize] = &foo; - -fn main() {} diff --git a/tests/ui/issues/issue-2190-1.rs b/tests/ui/issues/issue-2190-1.rs deleted file mode 100644 index e4e4bf9dbbee..000000000000 --- a/tests/ui/issues/issue-2190-1.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ check-pass - -use std::thread::Builder; - -static GENERATIONS: usize = 1024+256+128+49; - -fn spawn(mut f: Box) { - Builder::new().stack_size(32 * 1024).spawn(move || f()); -} - -fn child_no(x: usize) -> Box { - Box::new(move || { - if x < GENERATIONS { - spawn(child_no(x+1)); - } - }) -} - -pub fn main() { - spawn(child_no(0)); -} diff --git a/tests/ui/issues/issue-2214.rs b/tests/ui/issues/issue-2214.rs deleted file mode 100644 index 453bb58a6221..000000000000 --- a/tests/ui/issues/issue-2214.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ run-pass -//@ ignore-wasm32 wasi-libc does not have lgamma -//@ ignore-sgx no libc - -use std::ffi::{c_double, c_int}; -use std::mem; - -fn to_c_int(v: &mut isize) -> &mut c_int { - unsafe { mem::transmute_copy(&v) } -} - -fn lgamma(n: c_double, value: &mut isize) -> c_double { - unsafe { - return m::lgamma(n, to_c_int(value)); - } -} - -mod m { - use std::ffi::{c_double, c_int}; - extern "C" { - #[cfg(all(unix, not(target_os = "vxworks")))] - #[link_name="lgamma_r"] - pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; - #[cfg(windows)] - #[link_name = "lgamma"] - pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; - #[cfg(target_os = "vxworks")] - #[link_name = "lgamma"] - pub fn lgamma(n: c_double, sign: &mut c_int) -> c_double; - } -} - -pub fn main() { - let mut y: isize = 5; - let x: &mut isize = &mut y; - assert_eq!(lgamma(1.0 as c_double, x), 0.0 as c_double); -} diff --git a/tests/ui/issues/issue-22289.rs b/tests/ui/issues/issue-22289.rs deleted file mode 100644 index e1b3dfe5b61b..000000000000 --- a/tests/ui/issues/issue-22289.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - 0 as &dyn std::any::Any; //~ ERROR non-primitive cast -} diff --git a/tests/ui/issues/issue-22289.stderr b/tests/ui/issues/issue-22289.stderr deleted file mode 100644 index 560fbc73bbdc..000000000000 --- a/tests/ui/issues/issue-22289.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0605]: non-primitive cast: `i32` as `&(dyn Any + 'static)` - --> $DIR/issue-22289.rs:2:5 - | -LL | 0 as &dyn std::any::Any; - | ^^^^^^^^^^^^^^^^^^^^^^^ invalid cast - | -help: consider borrowing the value - | -LL | &0 as &dyn std::any::Any; - | + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/issues/issue-22370.stderr b/tests/ui/issues/issue-22370.stderr index b02d867eb7dd..cd1580e844ca 100644 --- a/tests/ui/issues/issue-22370.stderr +++ b/tests/ui/issues/issue-22370.stderr @@ -7,11 +7,11 @@ LL | LL | fn f(a: &dyn A) {} | ^ | - = note: because the parameter default references `Self`, the parameter must be specified on the object type -help: set the type parameter to the desired type + = note: because the parameter default references `Self`, the parameter must be specified on the trait object type +help: explicitly specify the type parameter | -LL | fn f(a: &dyn A) {} - | +++ +LL | fn f(a: &dyn A) {} + | +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-22403.rs b/tests/ui/issues/issue-22403.rs deleted file mode 100644 index 89c956913f93..000000000000 --- a/tests/ui/issues/issue-22403.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-pass -fn main() { - let x = Box::new([1, 2, 3]); - let y = x as Box<[i32]>; - println!("y: {:?}", y); -} diff --git a/tests/ui/issues/issue-22426.rs b/tests/ui/issues/issue-22426.rs deleted file mode 100644 index 0857ac9dfb4d..000000000000 --- a/tests/ui/issues/issue-22426.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass - -fn main() { - match 42 { - x if x < 7 => (), - _ => () - } -} diff --git a/tests/ui/issues/issue-22468.rs b/tests/ui/issues/issue-22468.rs deleted file mode 100644 index 197a19c038c4..000000000000 --- a/tests/ui/issues/issue-22468.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let foo = "bar"; - let x = foo("baz"); - //~^ ERROR: expected function, found `&str` -} - -fn foo(file: &str) -> bool { - true -} diff --git a/tests/ui/issues/issue-22468.stderr b/tests/ui/issues/issue-22468.stderr deleted file mode 100644 index 052888d2029b..000000000000 --- a/tests/ui/issues/issue-22468.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0618]: expected function, found `&str` - --> $DIR/issue-22468.rs:3:13 - | -LL | let foo = "bar"; - | --- `foo` has type `&str` -LL | let x = foo("baz"); - | ^^^------- - | | - | call expression requires function -... -LL | fn foo(file: &str) -> bool { - | -------------------------- this function of the same name is available here, but it's shadowed by the local binding - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/issues/issue-22577.rs b/tests/ui/issues/issue-22577.rs deleted file mode 100644 index 0fa284cc7c0c..000000000000 --- a/tests/ui/issues/issue-22577.rs +++ /dev/null @@ -1,25 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -use std::{fs, net}; - -fn assert_both() {} -fn assert_send() {} - -fn main() { - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); - assert_both::(); -} diff --git a/tests/ui/issues/issue-22599.rs b/tests/ui/issues/issue-22599.rs deleted file mode 100644 index 05096e5c1853..000000000000 --- a/tests/ui/issues/issue-22599.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![deny(unused_variables)] - -fn f(_: i32) {} - -fn main() { - let mut v = 0; - f(v); - v = match 0 { a => 0 }; //~ ERROR: unused variable: `a` - f(v); -} diff --git a/tests/ui/issues/issue-22599.stderr b/tests/ui/issues/issue-22599.stderr deleted file mode 100644 index b599f6febe31..000000000000 --- a/tests/ui/issues/issue-22599.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unused variable: `a` - --> $DIR/issue-22599.rs:8:19 - | -LL | v = match 0 { a => 0 }; - | ^ help: if this is intentional, prefix it with an underscore: `_a` - | -note: the lint level is defined here - --> $DIR/issue-22599.rs:1:9 - | -LL | #![deny(unused_variables)] - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-22644.rs b/tests/ui/issues/issue-22644.rs deleted file mode 100644 index e3ada65049d5..000000000000 --- a/tests/ui/issues/issue-22644.rs +++ /dev/null @@ -1,27 +0,0 @@ -fn main() { - let a: usize = 0; - let long_name: usize = 0; - - println!("{}", a as usize > long_name); - println!("{}", a as usize < long_name); //~ ERROR `<` is interpreted as a start of generic - println!("{}{}", a as usize < long_name, long_name); - //~^ ERROR `<` is interpreted as a start of generic - println!("{}", a as usize < 4); //~ ERROR `<` is interpreted as a start of generic - - println!("{}", a - as - usize - < //~ ERROR `<` is interpreted as a start of generic - 4); - println!("{}", a - - - as - - - usize - < //~ ERROR `<` is interpreted as a start of generic - 5); - - println!("{}", a as usize << long_name); //~ ERROR `<<` is interpreted as a start of generic -} diff --git a/tests/ui/issues/issue-22644.stderr b/tests/ui/issues/issue-22644.stderr deleted file mode 100644 index c6d41cc856dd..000000000000 --- a/tests/ui/issues/issue-22644.stderr +++ /dev/null @@ -1,86 +0,0 @@ -error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:6:31 - | -LL | println!("{}", a as usize < long_name); - | ^ --------- interpreted as generic arguments - | | - | not interpreted as comparison - | -help: try comparing the cast value - | -LL | println!("{}", (a as usize) < long_name); - | + + - -error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:7:33 - | -LL | println!("{}{}", a as usize < long_name, long_name); - | ^ -------------------- interpreted as generic arguments - | | - | not interpreted as comparison - | -help: try comparing the cast value - | -LL | println!("{}{}", (a as usize) < long_name, long_name); - | + + - -error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:9:31 - | -LL | println!("{}", a as usize < 4); - | ^ - interpreted as generic arguments - | | - | not interpreted as comparison - | -help: try comparing the cast value - | -LL | println!("{}", (a as usize) < 4); - | + + - -error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:14:20 - | -LL | < - | ^ not interpreted as comparison -LL | 4); - | - interpreted as generic arguments - | -help: try comparing the cast value - | -LL ~ println!("{}", (a -LL | as -LL ~ usize) - | - -error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison - --> $DIR/issue-22644.rs:23:20 - | -LL | < - | ^ not interpreted as comparison -LL | 5); - | - interpreted as generic arguments - | -help: try comparing the cast value - | -LL ~ println!("{}", (a -LL | -... -LL | -LL ~ usize) - | - -error: `<<` is interpreted as a start of generic arguments for `usize`, not a shift - --> $DIR/issue-22644.rs:26:31 - | -LL | println!("{}", a as usize << long_name); - | ^^ --------- interpreted as generic arguments - | | - | not interpreted as shift - | -help: try shifting the cast value - | -LL | println!("{}", (a as usize) << long_name); - | + + - -error: aborting due to 6 previous errors - diff --git a/tests/ui/issues/issue-22706.rs b/tests/ui/issues/issue-22706.rs deleted file mode 100644 index bb8a58d3d2ec..000000000000 --- a/tests/ui/issues/issue-22706.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn is_copy::Copy>() {} -//~^ ERROR type arguments are not allowed on module `marker` [E0109] -fn main() {} diff --git a/tests/ui/issues/issue-22706.stderr b/tests/ui/issues/issue-22706.stderr deleted file mode 100644 index 309e11a25f1a..000000000000 --- a/tests/ui/issues/issue-22706.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0109]: type arguments are not allowed on module `marker` - --> $DIR/issue-22706.rs:1:29 - | -LL | fn is_copy::Copy>() {} - | ------ ^^^ type argument not allowed - | | - | not allowed on module `marker` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/issues/issue-2288.rs b/tests/ui/issues/issue-2288.rs deleted file mode 100644 index f424cca79d3c..000000000000 --- a/tests/ui/issues/issue-2288.rs +++ /dev/null @@ -1,33 +0,0 @@ -//@ run-pass -#![allow(non_camel_case_types)] - -trait clam { - fn chowder(&self, y: A); -} - -#[derive(Copy, Clone)] -struct foo { - x: A, -} - -impl clam for foo { - fn chowder(&self, _y: A) { - } -} - -fn foo(b: A) -> foo { - foo { - x: b - } -} - -fn f(x: Box>, a: A) { - x.chowder(a); -} - -pub fn main() { - - let c = foo(42); - let d: Box> = Box::new(c) as Box>; - f(d, c.x); -} diff --git a/tests/ui/issues/issue-22894.rs b/tests/ui/issues/issue-22894.rs deleted file mode 100644 index e8fc680f0422..000000000000 --- a/tests/ui/issues/issue-22894.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ build-pass -#[allow(dead_code)] -static X: &'static str = &*""; -fn main() {} diff --git a/tests/ui/issues/issue-23036.rs b/tests/ui/issues/issue-23036.rs deleted file mode 100644 index 5186fccd042b..000000000000 --- a/tests/ui/issues/issue-23036.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass - -use std::collections::HashMap; -use std::path::Path; - -fn main() { - let mut map = HashMap::new(); - map.insert(Path::new("a"), 0); - map.get(Path::new("a")); -} diff --git a/tests/ui/issues/issue-2311-2.rs b/tests/ui/issues/issue-2311-2.rs deleted file mode 100644 index 5a0b49a501fc..000000000000 --- a/tests/ui/issues/issue-2311-2.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - -trait clam { - fn get(self) -> A; -} - -struct foo { - x: A, -} - -impl foo { - pub fn bar>(&self, _c: C) -> B { - panic!(); - } -} - -fn foo(b: A) -> foo { - foo { - x: b - } -} - -pub fn main() { } diff --git a/tests/ui/issues/issue-2311.rs b/tests/ui/issues/issue-2311.rs deleted file mode 100644 index 5388e634c096..000000000000 --- a/tests/ui/issues/issue-2311.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ check-pass -#![allow(non_camel_case_types)] - - -trait clam { fn get(self) -> A; } -trait foo { - fn bar>(&self, c: C) -> B; -} - -pub fn main() { } diff --git a/tests/ui/issues/issue-2312.rs b/tests/ui/issues/issue-2312.rs deleted file mode 100644 index ecd296aac7a1..000000000000 --- a/tests/ui/issues/issue-2312.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -// Testing that the B's are resolved - - -trait clam { fn get(self) -> A; } - -struct foo(isize); - -impl foo { - pub fn bar>(&self, _c: C) -> B { panic!(); } -} - -pub fn main() { } diff --git a/tests/ui/issues/issue-23173.rs b/tests/ui/issues/issue-23173.rs deleted file mode 100644 index 92f4c546440a..000000000000 --- a/tests/ui/issues/issue-23173.rs +++ /dev/null @@ -1,13 +0,0 @@ -enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } -struct Struct { - a: usize, -} - -fn use_token(token: &Token) { unimplemented!() } - -fn main() { - use_token(&Token::Homura); //~ ERROR no variant or associated item named `Homura` - Struct::method(); //~ ERROR no function or associated item named `method` found - Struct::method; //~ ERROR no function or associated item named `method` found - Struct::Assoc; //~ ERROR no associated item named `Assoc` found -} diff --git a/tests/ui/issues/issue-23173.stderr b/tests/ui/issues/issue-23173.stderr deleted file mode 100644 index d07d1a7caaf2..000000000000 --- a/tests/ui/issues/issue-23173.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0599]: no variant or associated item named `Homura` found for enum `Token` in the current scope - --> $DIR/issue-23173.rs:9:23 - | -LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } - | ---------- variant or associated item `Homura` not found for this enum -... -LL | use_token(&Token::Homura); - | ^^^^^^ variant or associated item not found in `Token` - -error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope - --> $DIR/issue-23173.rs:10:13 - | -LL | struct Struct { - | ------------- function or associated item `method` not found for this struct -... -LL | Struct::method(); - | ^^^^^^ function or associated item not found in `Struct` - -error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope - --> $DIR/issue-23173.rs:11:13 - | -LL | struct Struct { - | ------------- function or associated item `method` not found for this struct -... -LL | Struct::method; - | ^^^^^^ function or associated item not found in `Struct` - -error[E0599]: no associated item named `Assoc` found for struct `Struct` in the current scope - --> $DIR/issue-23173.rs:12:13 - | -LL | struct Struct { - | ------------- associated item `Assoc` not found for this struct -... -LL | Struct::Assoc; - | ^^^^^ associated item not found in `Struct` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-23189.rs b/tests/ui/issues/issue-23189.rs deleted file mode 100644 index e5526357cb0e..000000000000 --- a/tests/ui/issues/issue-23189.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod module {} - -fn main() { - let _ = module { x: 0 }; //~ERROR expected struct -} diff --git a/tests/ui/issues/issue-23189.stderr b/tests/ui/issues/issue-23189.stderr deleted file mode 100644 index 37d778dc992e..000000000000 --- a/tests/ui/issues/issue-23189.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0574]: expected struct, variant or union type, found module `module` - --> $DIR/issue-23189.rs:4:13 - | -LL | let _ = module { x: 0 }; - | ^^^^^^ not a struct, variant or union type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/issues/issue-23217.rs b/tests/ui/issues/issue-23217.rs deleted file mode 100644 index 09f9ebccf250..000000000000 --- a/tests/ui/issues/issue-23217.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub enum SomeEnum { - B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found -} - -fn main() {} diff --git a/tests/ui/issues/issue-23217.stderr b/tests/ui/issues/issue-23217.stderr deleted file mode 100644 index 830d260f99d7..000000000000 --- a/tests/ui/issues/issue-23217.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0599]: no variant or associated item named `A` found for enum `SomeEnum` in the current scope - --> $DIR/issue-23217.rs:2:19 - | -LL | pub enum SomeEnum { - | ----------------- variant or associated item `A` not found for this enum -LL | B = SomeEnum::A, - | ^ variant or associated item not found in `SomeEnum` - | -help: there is a variant with a similar name - | -LL - B = SomeEnum::A, -LL + B = SomeEnum::B, - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-23253.rs b/tests/ui/issues/issue-23253.rs deleted file mode 100644 index b285cb81ee23..000000000000 --- a/tests/ui/issues/issue-23253.rs +++ /dev/null @@ -1,6 +0,0 @@ -enum Foo { Bar } - -fn main() { - Foo::Bar.a; - //~^ ERROR no field `a` on type `Foo` -} diff --git a/tests/ui/issues/issue-23253.stderr b/tests/ui/issues/issue-23253.stderr deleted file mode 100644 index ec7696909e72..000000000000 --- a/tests/ui/issues/issue-23253.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0609]: no field `a` on type `Foo` - --> $DIR/issue-23253.rs:4:14 - | -LL | Foo::Bar.a; - | ^ unknown field - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/issues/issue-2383.rs b/tests/ui/issues/issue-2383.rs deleted file mode 100644 index 5d60018ae673..000000000000 --- a/tests/ui/issues/issue-2383.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass - -use std::collections::VecDeque; - -pub fn main() { - let mut q = VecDeque::new(); - q.push_front(10); -} diff --git a/tests/ui/issues/issue-24013.rs b/tests/ui/issues/issue-24013.rs deleted file mode 100644 index c6d301671272..000000000000 --- a/tests/ui/issues/issue-24013.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - use std::mem::{transmute, swap}; - let a = 1; - let b = 2; - unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; - //~^ ERROR type annotations needed -} diff --git a/tests/ui/issues/issue-24013.stderr b/tests/ui/issues/issue-24013.stderr deleted file mode 100644 index 37a86ecc5437..000000000000 --- a/tests/ui/issues/issue-24013.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-24013.rs:5:13 - | -LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; - | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-24161.rs b/tests/ui/issues/issue-24161.rs deleted file mode 100644 index 974add438616..000000000000 --- a/tests/ui/issues/issue-24161.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -#[derive(Copy,Clone)] -struct Functions { - a: fn(u32) -> u32, - b: extern "C" fn(u32) -> u32, - c: unsafe fn(u32) -> u32, - d: unsafe extern "C" fn(u32) -> u32 -} - -pub fn main() {} diff --git a/tests/ui/issues/issue-2428.rs b/tests/ui/issues/issue-2428.rs deleted file mode 100644 index 9cb02460f35b..000000000000 --- a/tests/ui/issues/issue-2428.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -#![allow(non_upper_case_globals)] - - -pub fn main() { - let _foo = 100; - const quux: isize = 5; - - enum Stuff { - Bar = quux - } - - assert_eq!(Stuff::Bar as isize, quux); -} diff --git a/tests/ui/issues/issue-24357.rs b/tests/ui/issues/issue-24357.rs deleted file mode 100644 index 63c061594d87..000000000000 --- a/tests/ui/issues/issue-24357.rs +++ /dev/null @@ -1,13 +0,0 @@ -struct NoCopy; //~ NOTE if `NoCopy` implemented `Clone`, you could clone the value -//~^ NOTE consider implementing `Clone` for this type -fn main() { - let x = NoCopy; - //~^ NOTE move occurs because `x` has type `NoCopy` - let f = move || { let y = x; }; - //~^ NOTE value moved into closure here - //~| NOTE variable moved due to use in closure - //~| NOTE you could clone this value - let z = x; - //~^ ERROR use of moved value: `x` - //~| NOTE value used here after move -} diff --git a/tests/ui/issues/issue-24357.stderr b/tests/ui/issues/issue-24357.stderr deleted file mode 100644 index 2d85077fe4c2..000000000000 --- a/tests/ui/issues/issue-24357.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0382]: use of moved value: `x` - --> $DIR/issue-24357.rs:10:12 - | -LL | let x = NoCopy; - | - move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait -LL | -LL | let f = move || { let y = x; }; - | ------- - variable moved due to use in closure - | | - | value moved into closure here -... -LL | let z = x; - | ^ value used here after move - | -note: if `NoCopy` implemented `Clone`, you could clone the value - --> $DIR/issue-24357.rs:1:1 - | -LL | struct NoCopy; - | ^^^^^^^^^^^^^ consider implementing `Clone` for this type -... -LL | let f = move || { let y = x; }; - | - you could clone this value - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/issues/issue-24389.rs b/tests/ui/issues/issue-24389.rs deleted file mode 100644 index 95bb2af9b25c..000000000000 --- a/tests/ui/issues/issue-24389.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ check-pass -#![allow(dead_code)] - -struct Foo; - -impl Foo { - fn new() -> Self { Foo } - fn bar() { Self::new(); } -} - -fn main() {} diff --git a/tests/ui/issues/issue-24434.rs b/tests/ui/issues/issue-24434.rs index 991084c27409..429bcf4a8d87 100644 --- a/tests/ui/issues/issue-24434.rs +++ b/tests/ui/issues/issue-24434.rs @@ -1,6 +1,6 @@ //@ check-pass -#![cfg_attr(all(), feature(rustc_attrs))] +#![cfg_attr(true, feature(rustc_attrs))] #![rustc_dummy] fn main() {} diff --git a/tests/ui/issues/issue-2445-b.rs b/tests/ui/issues/issue-2445-b.rs deleted file mode 100644 index 3a54c62a771b..000000000000 --- a/tests/ui/issues/issue-2445-b.rs +++ /dev/null @@ -1,30 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - -struct c1 { - x: T, -} - -impl c1 { - pub fn f1(&self, _x: isize) { - } -} - -fn c1(x: T) -> c1 { - c1 { - x: x - } -} - -impl c1 { - pub fn f2(&self, _x: isize) { - } -} - - -pub fn main() { - c1::(3).f1(4); - c1::(3).f2(4); -} diff --git a/tests/ui/issues/issue-2445.rs b/tests/ui/issues/issue-2445.rs deleted file mode 100644 index e6c33a8fd016..000000000000 --- a/tests/ui/issues/issue-2445.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - -struct c1 { - x: T, -} - -impl c1 { - pub fn f1(&self, _x: T) {} -} - -fn c1(x: T) -> c1 { - c1 { - x: x - } -} - -impl c1 { - pub fn f2(&self, _x: T) {} -} - - -pub fn main() { - c1::(3).f1(4); - c1::(3).f2(4); -} diff --git a/tests/ui/issues/issue-2463.rs b/tests/ui/issues/issue-2463.rs deleted file mode 100644 index 8fff9763bd9e..000000000000 --- a/tests/ui/issues/issue-2463.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -struct Pair { f: isize, g: isize } - -pub fn main() { - - let x = Pair { - f: 0, - g: 0, - }; - - let _y = Pair { - f: 1, - g: 1, - .. x - }; - - let _z = Pair { - f: 1, - .. x - }; - -} diff --git a/tests/ui/issues/issue-24779.rs b/tests/ui/issues/issue-24779.rs deleted file mode 100644 index f371828606c4..000000000000 --- a/tests/ui/issues/issue-24779.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ run-pass -fn main() { - assert_eq!((||||42)()(), 42); -} diff --git a/tests/ui/issues/issue-24819.rs b/tests/ui/issues/issue-24819.rs deleted file mode 100644 index 97d288e5cb14..000000000000 --- a/tests/ui/issues/issue-24819.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ dont-require-annotations: NOTE - -use std::collections::HashSet; - -fn main() { - let mut v = Vec::new(); - foo(&mut v); - //~^ ERROR mismatched types - //~| NOTE expected `&mut HashSet`, found `&mut Vec<_>` -} - -fn foo(h: &mut HashSet) { -} diff --git a/tests/ui/issues/issue-24819.stderr b/tests/ui/issues/issue-24819.stderr deleted file mode 100644 index e144f37d6e48..000000000000 --- a/tests/ui/issues/issue-24819.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-24819.rs:7:9 - | -LL | foo(&mut v); - | --- ^^^^^^ expected `&mut HashSet`, found `&mut Vec<_>` - | | - | arguments to this function are incorrect - | - = note: expected mutable reference `&mut HashSet` - found mutable reference `&mut Vec<_>` -note: function defined here - --> $DIR/issue-24819.rs:12:4 - | -LL | fn foo(h: &mut HashSet) { - | ^^^ -------------------- - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-2487-a.rs b/tests/ui/issues/issue-2487-a.rs deleted file mode 100644 index d38616929fae..000000000000 --- a/tests/ui/issues/issue-2487-a.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ build-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - -struct socket { - sock: isize, - -} - -impl Drop for socket { - fn drop(&mut self) {} -} - -impl socket { - pub fn set_identity(&self) { - closure(|| setsockopt_bytes(self.sock.clone())) - } -} - -fn socket() -> socket { - socket { - sock: 1 - } -} - -fn closure(f: F) where F: FnOnce() { f() } - -fn setsockopt_bytes(_sock: isize) { } - -pub fn main() {} diff --git a/tests/ui/issues/issue-24945-repeat-dash-opts.rs b/tests/ui/issues/issue-24945-repeat-dash-opts.rs deleted file mode 100644 index 5d8044b0a1a0..000000000000 --- a/tests/ui/issues/issue-24945-repeat-dash-opts.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass -// This test is just checking that we continue to accept `-g -g -O -O` -// as options to the compiler. - -//@ compile-flags:-g -g -O -O - -fn main() { - assert_eq!(1, 1); -} diff --git a/tests/ui/issues/issue-2502.rs b/tests/ui/issues/issue-2502.rs deleted file mode 100644 index 98a52a3b5a7d..000000000000 --- a/tests/ui/issues/issue-2502.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - - - -struct font<'a> { - fontbuf: &'a Vec , -} - -impl<'a> font<'a> { - pub fn buf(&self) -> &'a Vec { - self.fontbuf - } -} - -fn font(fontbuf: &Vec ) -> font<'_> { - font { - fontbuf: fontbuf - } -} - -pub fn main() { } diff --git a/tests/ui/issues/issue-25180.rs b/tests/ui/issues/issue-25180.rs deleted file mode 100644 index 339aca037546..000000000000 --- a/tests/ui/issues/issue-25180.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -#![allow(non_upper_case_globals)] - -const x: &'static dyn Fn() = &|| println!("ICE here"); - -fn main() {} diff --git a/tests/ui/issues/issue-25368.rs b/tests/ui/issues/issue-25368.rs deleted file mode 100644 index 4be83457f7a8..000000000000 --- a/tests/ui/issues/issue-25368.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::sync::mpsc::channel; -use std::thread::spawn; -use std::marker::PhantomData; - -struct Foo {foo: PhantomData} - -fn main() { - let (tx, rx) = - channel(); - spawn(move || { - tx.send(Foo{ foo: PhantomData }); - //~^ ERROR type annotations needed - }); -} diff --git a/tests/ui/issues/issue-25368.stderr b/tests/ui/issues/issue-25368.stderr deleted file mode 100644 index 23f1441e69dc..000000000000 --- a/tests/ui/issues/issue-25368.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-25368.rs:11:27 - | -LL | tx.send(Foo{ foo: PhantomData }); - | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` - | -help: consider specifying the generic argument - | -LL | tx.send(Foo{ foo: PhantomData:: }); - | +++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-25394.rs b/tests/ui/issues/issue-25394.rs deleted file mode 100644 index 689c9f33af02..000000000000 --- a/tests/ui/issues/issue-25394.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -#[derive(Debug)] -struct Row([T]); - -fn main() {} diff --git a/tests/ui/issues/issue-2550.rs b/tests/ui/issues/issue-2550.rs deleted file mode 100644 index 450db9be627e..000000000000 --- a/tests/ui/issues/issue-2550.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_snake_case)] - - -struct C { - x: usize, -} - -fn C(x: usize) -> C { - C { - x: x - } -} - -fn f(_x: T) { -} - -pub fn main() { - f(C(1)); -} diff --git a/tests/ui/issues/issue-2642.rs b/tests/ui/issues/issue-2642.rs deleted file mode 100644 index ad5721495090..000000000000 --- a/tests/ui/issues/issue-2642.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -fn f() { - let _x: usize = loop { loop { break; } }; -} - -pub fn main() { -} diff --git a/tests/ui/issues/issue-26472.rs b/tests/ui/issues/issue-26472.rs deleted file mode 100644 index b100c59ad0bd..000000000000 --- a/tests/ui/issues/issue-26472.rs +++ /dev/null @@ -1,13 +0,0 @@ -mod sub { - pub struct S { len: usize } - impl S { - pub fn new() -> S { S { len: 0 } } - pub fn len(&self) -> usize { self.len } - } -} - -fn main() { - let s = sub::S::new(); - let v = s.len; //~ ERROR field `len` of struct `S` is private - s.len = v; //~ ERROR field `len` of struct `S` is private -} diff --git a/tests/ui/issues/issue-26472.stderr b/tests/ui/issues/issue-26472.stderr deleted file mode 100644 index d7134bff1761..000000000000 --- a/tests/ui/issues/issue-26472.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0616]: field `len` of struct `S` is private - --> $DIR/issue-26472.rs:11:15 - | -LL | let v = s.len; - | ^^^ private field - | -help: a method `len` also exists, call it with parentheses - | -LL | let v = s.len(); - | ++ - -error[E0616]: field `len` of struct `S` is private - --> $DIR/issue-26472.rs:12:7 - | -LL | s.len = v; - | ^^^ private field - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0616`. diff --git a/tests/ui/issues/issue-26614.rs b/tests/ui/issues/issue-26614.rs deleted file mode 100644 index 576c7545924b..000000000000 --- a/tests/ui/issues/issue-26614.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ check-pass - -trait Mirror { - type It; -} - -impl Mirror for T { - type It = Self; -} - -fn main() { - let c: ::It = 5; - const CCCC: ::It = 5; -} diff --git a/tests/ui/issues/issue-26646.rs b/tests/ui/issues/issue-26646.rs deleted file mode 100644 index b1789b1a91fc..000000000000 --- a/tests/ui/issues/issue-26646.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ check-pass -#![deny(unused_attributes)] - -#[repr(C)] -#[repr(packed)] -pub struct Foo; - -#[repr(packed)] -#[repr(C)] -pub struct Bar; - -fn main() { } diff --git a/tests/ui/issues/issue-27008.rs b/tests/ui/issues/issue-27008.rs deleted file mode 100644 index 20aa4f282c7e..000000000000 --- a/tests/ui/issues/issue-27008.rs +++ /dev/null @@ -1,7 +0,0 @@ -struct S; - -fn main() { - let b = [0; S]; - //~^ ERROR mismatched types - //~| NOTE expected `usize`, found `S` -} diff --git a/tests/ui/issues/issue-27008.stderr b/tests/ui/issues/issue-27008.stderr deleted file mode 100644 index b4bfaa278633..000000000000 --- a/tests/ui/issues/issue-27008.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-27008.rs:4:17 - | -LL | let b = [0; S]; - | ^ expected `usize`, found `S` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-27033.rs b/tests/ui/issues/issue-27033.rs deleted file mode 100644 index a23819a20f9a..000000000000 --- a/tests/ui/issues/issue-27033.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn main() { - match Some(1) { - None @ _ => {} //~ ERROR match bindings cannot shadow unit variants - }; - const C: u8 = 1; - match 1 { - C @ 2 => { //~ ERROR match bindings cannot shadow constant - println!("{}", C); - } - _ => {} - }; -} diff --git a/tests/ui/issues/issue-27033.stderr b/tests/ui/issues/issue-27033.stderr deleted file mode 100644 index 129870f8c409..000000000000 --- a/tests/ui/issues/issue-27033.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0530]: match bindings cannot shadow unit variants - --> $DIR/issue-27033.rs:3:9 - | -LL | None @ _ => {} - | ^^^^ cannot be named the same as a unit variant - | - --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL - | - = note: the unit variant `None` is defined here - -error[E0530]: match bindings cannot shadow constants - --> $DIR/issue-27033.rs:7:9 - | -LL | const C: u8 = 1; - | ---------------- the constant `C` is defined here -LL | match 1 { -LL | C @ 2 => { - | ^ cannot be named the same as a constant - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0530`. diff --git a/tests/ui/issues/issue-2708.rs b/tests/ui/issues/issue-2708.rs deleted file mode 100644 index 09d19f87aa64..000000000000 --- a/tests/ui/issues/issue-2708.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_snake_case)] - - - - -struct Font { - fontbuf: usize, - cairo_font: usize, - font_dtor: usize, - -} - -impl Drop for Font { - fn drop(&mut self) {} -} - -fn Font() -> Font { - Font { - fontbuf: 0, - cairo_font: 0, - font_dtor: 0 - } -} - -pub fn main() { - let _f: Box<_> = Box::new(Font()); -} diff --git a/tests/ui/issues/issue-27268.rs b/tests/ui/issues/issue-27268.rs deleted file mode 100644 index e8704d215e88..000000000000 --- a/tests/ui/issues/issue-27268.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ run-pass -fn main() { - const _C: &'static dyn Fn() = &||{}; -} diff --git a/tests/ui/issues/issue-27340.rs b/tests/ui/issues/issue-27340.rs index 53ca2bc973ff..9966c24a7441 100644 --- a/tests/ui/issues/issue-27340.rs +++ b/tests/ui/issues/issue-27340.rs @@ -1,7 +1,7 @@ struct Foo; #[derive(Copy, Clone)] -//~^ ERROR the trait `Copy` cannot be implemented for this type struct Bar(Foo); -//~^ ERROR `Foo: Clone` is not satisfied +//~^ ERROR: the trait `Copy` cannot be implemented for this type +//~| ERROR: `Foo: Clone` is not satisfied fn main() {} diff --git a/tests/ui/issues/issue-27340.stderr b/tests/ui/issues/issue-27340.stderr index d5ff29a618b0..3b4ad58b1f08 100644 --- a/tests/ui/issues/issue-27340.stderr +++ b/tests/ui/issues/issue-27340.stderr @@ -1,22 +1,20 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-27340.rs:2:10 + --> $DIR/issue-27340.rs:3:8 | LL | #[derive(Copy, Clone)] - | ^^^^ -LL | + | ---- in this derive macro expansion LL | struct Bar(Foo); - | --- this field does not implement `Copy` + | ^^^ --- this field does not implement `Copy` error[E0277]: the trait bound `Foo: Clone` is not satisfied - --> $DIR/issue-27340.rs:4:12 + --> $DIR/issue-27340.rs:3:12 | LL | #[derive(Copy, Clone)] | ----- in this derive macro expansion -LL | LL | struct Bar(Foo); | ^^^ the trait `Clone` is not implemented for `Foo` | -note: required by a bound in `AssertParamIsClone` +note: required by a bound in `std::clone::AssertParamIsClone` --> $SRC_DIR/core/src/clone.rs:LL:COL help: consider annotating `Foo` with `#[derive(Clone)]` | diff --git a/tests/ui/issues/issue-27639.rs b/tests/ui/issues/issue-27639.rs deleted file mode 100644 index 95edcb8695e2..000000000000 --- a/tests/ui/issues/issue-27639.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_upper_case_globals)] - -fn main() { - const iter: i32 = 0; - - for i in 1..10 { - println!("{}", i); - } -} diff --git a/tests/ui/issues/issue-28105.rs b/tests/ui/issues/issue-28105.rs deleted file mode 100644 index 1e8d2d6ccf13..000000000000 --- a/tests/ui/issues/issue-28105.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Make sure that a continue span actually contains the keyword. - -fn main() { - continue //~ ERROR `continue` outside of a loop - ; - break //~ ERROR `break` outside of a loop - ; -} diff --git a/tests/ui/issues/issue-28105.stderr b/tests/ui/issues/issue-28105.stderr deleted file mode 100644 index f450256f3ecf..000000000000 --- a/tests/ui/issues/issue-28105.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0268]: `continue` outside of a loop - --> $DIR/issue-28105.rs:4:5 - | -LL | continue - | ^^^^^^^^ cannot `continue` outside of a loop - -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/issue-28105.rs:6:5 - | -LL | break - | ^^^^^ cannot `break` outside of a loop or labeled block - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/issues/issue-28109.rs b/tests/ui/issues/issue-28109.rs deleted file mode 100644 index 755a539b5003..000000000000 --- a/tests/ui/issues/issue-28109.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Make sure that label for continue and break is spanned correctly - -fn main() { - loop { - continue - 'b //~ ERROR use of undeclared label - ; - break - 'c //~ ERROR use of undeclared label - ; - } -} diff --git a/tests/ui/issues/issue-28109.stderr b/tests/ui/issues/issue-28109.stderr deleted file mode 100644 index 0f918d3b6f70..000000000000 --- a/tests/ui/issues/issue-28109.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0426]: use of undeclared label `'b` - --> $DIR/issue-28109.rs:6:9 - | -LL | 'b - | ^^ undeclared label `'b` - -error[E0426]: use of undeclared label `'c` - --> $DIR/issue-28109.rs:9:9 - | -LL | 'c - | ^^ undeclared label `'c` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0426`. diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr index c85424e22794..9940f005b7f8 100644 --- a/tests/ui/issues/issue-28344.stderr +++ b/tests/ui/issues/issue-28344.stderr @@ -16,7 +16,7 @@ error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be s --> $DIR/issue-28344.rs:5:17 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - | ^^^^^^ help: specify the associated type: `BitXor::` + | ^^^^^^ help: specify the associated type: `BitXor::` warning: trait objects without an explicit `dyn` are deprecated --> $DIR/issue-28344.rs:10:13 @@ -35,7 +35,7 @@ error[E0191]: the value of the associated type `Output` in `BitXor<_>` must be s --> $DIR/issue-28344.rs:10:13 | LL | let g = BitXor::bitor; - | ^^^^^^ help: specify the associated type: `BitXor::` + | ^^^^^^ help: specify the associated type: `BitXor::` error: aborting due to 2 previous errors; 2 warnings emitted diff --git a/tests/ui/issues/issue-28433.rs b/tests/ui/issues/issue-28433.rs deleted file mode 100644 index 2298ad240d56..000000000000 --- a/tests/ui/issues/issue-28433.rs +++ /dev/null @@ -1,12 +0,0 @@ -enum Bird { - pub Duck, - //~^ ERROR visibility qualifiers are not permitted here - Goose, - pub(crate) Dove - //~^ ERROR visibility qualifiers are not permitted here -} - - -fn main() { - let y = Bird::Goose; -} diff --git a/tests/ui/issues/issue-28433.stderr b/tests/ui/issues/issue-28433.stderr deleted file mode 100644 index 0fa67e35f1d4..000000000000 --- a/tests/ui/issues/issue-28433.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0449]: visibility qualifiers are not permitted here - --> $DIR/issue-28433.rs:2:5 - | -LL | pub Duck, - | ^^^ help: remove the qualifier - | - = note: enum variants and their fields always share the visibility of the enum they are in - -error[E0449]: visibility qualifiers are not permitted here - --> $DIR/issue-28433.rs:5:5 - | -LL | pub(crate) Dove - | ^^^^^^^^^^ help: remove the qualifier - | - = note: enum variants and their fields always share the visibility of the enum they are in - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0449`. diff --git a/tests/ui/issues/issue-2848.rs b/tests/ui/issues/issue-2848.rs deleted file mode 100644 index 8499459cec26..000000000000 --- a/tests/ui/issues/issue-2848.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[allow(non_camel_case_types)] - -mod bar { - pub enum foo { - alpha, - beta, - charlie - } -} - -fn main() { - use bar::foo::{alpha, charlie}; - match alpha { - alpha | beta => {} //~ ERROR variable `beta` is not bound in all patterns - //~^ ERROR `beta` is named the same as one of the variants - charlie => {} - } -} diff --git a/tests/ui/issues/issue-2848.stderr b/tests/ui/issues/issue-2848.stderr deleted file mode 100644 index 1cef27c34635..000000000000 --- a/tests/ui/issues/issue-2848.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0408]: variable `beta` is not bound in all patterns - --> $DIR/issue-2848.rs:14:7 - | -LL | alpha | beta => {} - | ^^^^^ ---- variable not in all patterns - | | - | pattern doesn't bind `beta` - -error[E0170]: pattern binding `beta` is named the same as one of the variants of the type `bar::foo` - --> $DIR/issue-2848.rs:14:15 - | -LL | alpha | beta => {} - | ^^^^ help: to match on the variant, qualify the path: `bar::foo::beta` - | - = note: `#[deny(bindings_with_variant_name)]` on by default - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0170, E0408. -For more information about an error, try `rustc --explain E0170`. diff --git a/tests/ui/issues/issue-2849.rs b/tests/ui/issues/issue-2849.rs deleted file mode 100644 index 787ab0e28960..000000000000 --- a/tests/ui/issues/issue-2849.rs +++ /dev/null @@ -1,8 +0,0 @@ -enum Foo { Alpha, Beta(isize) } - -fn main() { - match Foo::Alpha { - Foo::Alpha | Foo::Beta(i) => {} - //~^ ERROR variable `i` is not bound in all patterns - } -} diff --git a/tests/ui/issues/issue-2849.stderr b/tests/ui/issues/issue-2849.stderr deleted file mode 100644 index ef5cdb42e610..000000000000 --- a/tests/ui/issues/issue-2849.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0408]: variable `i` is not bound in all patterns - --> $DIR/issue-2849.rs:5:7 - | -LL | Foo::Alpha | Foo::Beta(i) => {} - | ^^^^^^^^^^ - variable not in all patterns - | | - | pattern doesn't bind `i` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0408`. diff --git a/tests/ui/issues/issue-28568.rs b/tests/ui/issues/issue-28568.rs deleted file mode 100644 index ce511158f005..000000000000 --- a/tests/ui/issues/issue-28568.rs +++ /dev/null @@ -1,12 +0,0 @@ -struct MyStruct; - -impl Drop for MyStruct { - fn drop(&mut self) { } -} - -impl Drop for MyStruct { -//~^ ERROR conflicting implementations of trait - fn drop(&mut self) { } -} - -fn main() {} diff --git a/tests/ui/issues/issue-28568.stderr b/tests/ui/issues/issue-28568.stderr deleted file mode 100644 index c8db0403e59a..000000000000 --- a/tests/ui/issues/issue-28568.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0119]: conflicting implementations of trait `Drop` for type `MyStruct` - --> $DIR/issue-28568.rs:7:1 - | -LL | impl Drop for MyStruct { - | ---------------------- first implementation here -... -LL | impl Drop for MyStruct { - | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyStruct` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/issues/issue-2895.rs b/tests/ui/issues/issue-2895.rs deleted file mode 100644 index 6301a8637534..000000000000 --- a/tests/ui/issues/issue-2895.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -use std::mem; - -struct Cat { - x: isize -} - -struct Kitty { - x: isize, -} - -impl Drop for Kitty { - fn drop(&mut self) {} -} - -#[cfg(target_pointer_width = "64")] -pub fn main() { - assert_eq!(mem::size_of::(), 8 as usize); - assert_eq!(mem::size_of::(), 8 as usize); -} - -#[cfg(target_pointer_width = "32")] -pub fn main() { - assert_eq!(mem::size_of::(), 4 as usize); - assert_eq!(mem::size_of::(), 4 as usize); -} diff --git a/tests/ui/issues/issue-29030.rs b/tests/ui/issues/issue-29030.rs deleted file mode 100644 index c92853fb5dc2..000000000000 --- a/tests/ui/issues/issue-29030.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -#[derive(Debug)] -struct Message<'a, P: 'a = &'a [u8]> { - header: &'a [u8], - payload: P, -} - -fn main() {} diff --git a/tests/ui/issues/issue-2904.rs b/tests/ui/issues/issue-2904.rs deleted file mode 100644 index 1ae3a8ad656e..000000000000 --- a/tests/ui/issues/issue-2904.rs +++ /dev/null @@ -1,79 +0,0 @@ -//@ build-pass -#![allow(unused_must_use)] -#![allow(dead_code)] -#![allow(unused_mut)] -#![allow(non_camel_case_types)] - -// Map representation - -use std::fmt; -use std::io::prelude::*; -use square::{bot, wall, rock, lambda, closed_lift, open_lift, earth, empty}; - -enum square { - bot, - wall, - rock, - lambda, - closed_lift, - open_lift, - earth, - empty -} - -impl fmt::Debug for square { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", match *self { - bot => { "R".to_string() } - wall => { "#".to_string() } - rock => { "*".to_string() } - lambda => { "\\".to_string() } - closed_lift => { "L".to_string() } - open_lift => { "O".to_string() } - earth => { ".".to_string() } - empty => { " ".to_string() } - }) - } -} - -fn square_from_char(c: char) -> square { - match c { - 'R' => { bot } - '#' => { wall } - '*' => { rock } - '\\' => { lambda } - 'L' => { closed_lift } - 'O' => { open_lift } - '.' => { earth } - ' ' => { empty } - _ => { - println!("invalid square: {}", c); - panic!() - } - } -} - -fn read_board_grid(mut input: rdr) - -> Vec> { - let mut input: &mut dyn Read = &mut input; - let mut grid = Vec::new(); - let mut line = [0; 10]; - input.read(&mut line); - let mut row = Vec::new(); - for c in &line { - row.push(square_from_char(*c as char)) - } - grid.push(row); - let width = grid[0].len(); - for row in &grid { assert_eq!(row.len(), width) } - grid -} - -mod test { - #[test] - pub fn trivial_to_string() { - assert_eq!(lambda.to_string(), "\\") - } -} - -pub fn main() {} diff --git a/tests/ui/issues/issue-2935.rs b/tests/ui/issues/issue-2935.rs deleted file mode 100644 index bcc25f6187b5..000000000000 --- a/tests/ui/issues/issue-2935.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -//type t = { a: isize }; -// type t = { a: bool }; -type t = bool; - -trait it { - fn f(&self); -} - -impl it for t { - fn f(&self) { } -} - -pub fn main() { - // let x = ({a: 4} as it); - // let y = box ({a: 4}); - // let z = box ({a: 4} as it); - // let z = box ({a: true} as it); - let z: Box<_> = Box::new(Box::new(true) as Box); - // x.f(); - // y.f(); - // (*z).f(); - println!("ok so far..."); - z.f(); //segfault -} diff --git a/tests/ui/issues/issue-2951.rs b/tests/ui/issues/issue-2951.rs deleted file mode 100644 index e28516fa3073..000000000000 --- a/tests/ui/issues/issue-2951.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ dont-require-annotations: NOTE - -fn foo(x: T, y: U) { - let mut xx = x; - xx = y; - //~^ ERROR mismatched types - //~| NOTE expected type parameter `T`, found type parameter `U` - //~| NOTE expected type parameter `T` - //~| NOTE found type parameter `U` -} - -fn main() { -} diff --git a/tests/ui/issues/issue-2951.stderr b/tests/ui/issues/issue-2951.stderr deleted file mode 100644 index d4b45935bf9a..000000000000 --- a/tests/ui/issues/issue-2951.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-2951.rs:5:10 - | -LL | fn foo(x: T, y: U) { - | - - found type parameter - | | - | expected type parameter -LL | let mut xx = x; - | - expected due to this value -LL | xx = y; - | ^ expected type parameter `T`, found type parameter `U` - | - = note: expected type parameter `T` - found type parameter `U` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-29540.rs b/tests/ui/issues/issue-29540.rs deleted file mode 100644 index 6bfeae8559dc..000000000000 --- a/tests/ui/issues/issue-29540.rs +++ /dev/null @@ -1,492 +0,0 @@ -//@ build-pass -#[derive(Debug)] -pub struct Config { - pub name: String, - pub cluster: String, - pub debug_none: String, - pub debug_lockdep: String, - pub debug_context: String, - pub debug_crush: String, - pub debug_mds: String, - pub debug_mds_balancer: String, - pub debug_mds_locker: String, - pub debug_mds_log: String, - pub debug_mds_log_expire: String, - pub debug_mds_migrator: String, - pub debug_buffer: String, - pub debug_timer: String, - pub debug_filer: String, - pub debug_striper: String, - pub debug_objecter: String, - pub debug_rados: String, - pub debug_rbd: String, - pub debug_journaler: String, - pub debug_objectcacher: String, - pub debug_client: String, - pub debug_osd: String, - pub debug_optracker: String, - pub debug_objclass: String, - pub debug_filestore: String, - pub debug_keyvaluestore: String, - pub debug_journal: String, - pub debug_ms: String, - pub debug_mon: String, - pub debug_monc: String, - pub debug_paxos: String, - pub debug_tp: String, - pub debug_auth: String, - pub debug_crypto: String, - pub debug_finisher: String, - pub debug_heartbeatmap: String, - pub debug_perfcounter: String, - pub debug_rgw: String, - pub debug_civetweb: String, - pub debug_javaclient: String, - pub debug_asok: String, - pub debug_throttle: String, - pub host: String, - pub fsid: String, - pub public_addr: String, - pub cluster_addr: String, - pub public_network: String, - pub cluster_network: String, - pub num_client: String, - pub monmap: String, - pub mon_host: String, - pub lockdep: String, - pub run_dir: String, - pub admin_socket: String, - pub daemonize: String, - pub pid_file: String, - pub chdir: String, - pub max_open_files: String, - pub restapi_log_level: String, - pub restapi_base_url: String, - pub fatal_signal_handlers: String, - pub log_file: String, - pub log_max_new: String, - pub log_max_recent: String, - pub log_to_stderr: String, - pub err_to_stderr: String, - pub log_to_syslog: String, - pub err_to_syslog: String, - pub log_flush_on_exit: String, - pub log_stop_at_utilization: String, - pub clog_to_monitors: String, - pub clog_to_syslog: String, - pub clog_to_syslog_level: String, - pub clog_to_syslog_facility: String, - pub mon_cluster_log_to_syslog: String, - pub mon_cluster_log_to_syslog_level: String, - pub mon_cluster_log_to_syslog_facility: String, - pub mon_cluster_log_file: String, - pub mon_cluster_log_file_level: String, - pub key: String, - pub keyfile: String, - pub keyring: String, - pub heartbeat_interval: String, - pub heartbeat_file: String, - pub heartbeat_inject_failure: String, - pub perf: String, - pub ms_tcp_nodelay: String, - pub ms_tcp_rcvbuf: String, - pub ms_initial_backoff: String, - pub ms_max_backoff: String, - pub ms_nocrc: String, - pub ms_die_on_bad_msg: String, - pub ms_die_on_unhandled_msg: String, - pub ms_die_on_old_message: String, - pub ms_dispatch_throttle_bytes: String, - pub ms_bind_ipv6: String, - pub ms_bind_port_min: String, - pub ms_bind_port_max: String, - pub ms_rwthread_stack_bytes: String, - pub ms_tcp_read_timeout: String, - pub ms_pq_max_tokens_per_priority: String, - pub ms_pq_min_cost: String, - pub ms_inject_socket_failures: String, - pub ms_inject_delay_type: String, - pub ms_inject_delay_msg_type: String, - pub ms_inject_delay_max: String, - pub ms_inject_delay_probability: String, - pub ms_inject_internal_delays: String, - pub ms_dump_on_send: String, - pub inject_early_sigterm: String, - pub mon_data: String, - pub mon_initial_members: String, - pub mon_sync_fs_threshold: String, - pub mon_compact_on_start: String, - pub mon_compact_on_bootstrap: String, - pub mon_compact_on_trim: String, - pub mon_tick_interval: String, - pub mon_subscribe_interval: String, - pub mon_delta_reset_interval: String, - pub mon_osd_laggy_halflife: String, - pub mon_osd_laggy_weight: String, - pub mon_osd_adjust_heartbeat_grace: String, - pub mon_osd_adjust_down_out_interval: String, - pub mon_osd_auto_mark_in: String, - pub mon_osd_auto_mark_auto_out_in: String, - pub mon_osd_auto_mark_new_in: String, - pub mon_osd_down_out_interval: String, - pub mon_osd_down_out_subtree_limit: String, - pub mon_osd_min_up_ratio: String, - pub mon_osd_min_in_ratio: String, - pub mon_osd_max_op_age: String, - pub mon_osd_max_split_count: String, - pub mon_osd_allow_primary_temp: String, - pub mon_osd_allow_primary_affinity: String, - pub mon_stat_smooth_intervals: String, - pub mon_lease: String, - pub mon_lease_renew_interval: String, - pub mon_lease_ack_timeout: String, - pub mon_clock_drift_allowed: String, - pub mon_clock_drift_warn_backoff: String, - pub mon_timecheck_interval: String, - pub mon_accept_timeout: String, - pub mon_pg_create_interval: String, - pub mon_pg_stuck_threshold: String, - pub mon_pg_warn_min_per_osd: String, - pub mon_pg_warn_max_object_skew: String, - pub mon_pg_warn_min_objects: String, - pub mon_pg_warn_min_pool_objects: String, - pub mon_cache_target_full_warn_ratio: String, - pub mon_osd_full_ratio: String, - pub mon_osd_nearfull_ratio: String, - pub mon_globalid_prealloc: String, - pub mon_osd_report_timeout: String, - pub mon_force_standby_active: String, - pub mon_warn_on_old_mons: String, - pub mon_warn_on_legacy_crush_tunables: String, - pub mon_warn_on_osd_down_out_interval_zero: String, - pub mon_warn_on_cache_pools_without_hit_sets: String, - pub mon_min_osdmap_epochs: String, - pub mon_max_pgmap_epochs: String, - pub mon_max_log_epochs: String, - pub mon_max_mdsmap_epochs: String, - pub mon_max_osd: String, - pub mon_probe_timeout: String, - pub mon_slurp_timeout: String, - pub mon_slurp_bytes: String, - pub mon_client_bytes: String, - pub mon_daemon_bytes: String, - pub mon_max_log_entries_per_event: String, - pub mon_health_data_update_interval: String, - pub mon_data_avail_crit: String, - pub mon_data_avail_warn: String, - pub mon_config_key_max_entry_size: String, - pub mon_sync_timeout: String, - pub mon_sync_max_payload_size: String, - pub mon_sync_debug: String, - pub mon_sync_debug_leader: String, - pub mon_sync_debug_provider: String, - pub mon_sync_debug_provider_fallback: String, - pub mon_inject_sync_get_chunk_delay: String, - pub mon_osd_min_down_reporters: String, - pub mon_osd_min_down_reports: String, - pub mon_osd_force_trim_to: String, - pub mon_mds_force_trim_to: String, - pub mon_advanced_debug_mode: String, - pub mon_debug_dump_transactions: String, - pub mon_debug_dump_location: String, - pub mon_sync_provider_kill_at: String, - pub mon_sync_requester_kill_at: String, - pub mon_leveldb_write_buffer_size: String, - pub mon_leveldb_cache_size: String, - pub mon_leveldb_block_size: String, - pub mon_leveldb_bloom_size: String, - pub mon_leveldb_max_open_files: String, - pub mon_leveldb_compression: String, - pub mon_leveldb_paranoid: String, - pub mon_leveldb_log: String, - pub mon_leveldb_size_warn: String, - pub mon_force_quorum_join: String, - pub paxos_stash_full_interval: String, - pub paxos_max_join_drift: String, - pub paxos_propose_interval: String, - pub paxos_min_wait: String, - pub paxos_min: String, - pub paxos_trim_min: String, - pub paxos_trim_max: String, - pub paxos_service_trim_min: String, - pub paxos_service_trim_max: String, - pub paxos_kill_at: String, - pub clock_offset: String, - pub auth_cluster_required: String, - pub auth_service_required: String, - pub auth_client_required: String, - pub auth_supported: String, - pub cephx_require_signatures: String, - pub cephx_cluster_require_signatures: String, - pub cephx_service_require_signatures: String, - pub cephx_sign_messages: String, - pub auth_mon_ticket_ttl: String, - pub auth_service_ticket_ttl: String, - pub auth_debug: String, - pub mon_client_hunt_interval: String, - pub mon_client_ping_interval: String, - pub mon_client_ping_timeout: String, - pub mon_client_hunt_interval_backoff: String, - pub mon_client_hunt_interval_max_multiple: String, - pub mon_client_max_log_entries_per_message: String, - pub mon_max_pool_pg_num: String, - pub mon_pool_quota_warn_threshold: String, - pub mon_pool_quota_crit_threshold: String, - pub client_cache_size: String, - pub client_cache_mid: String, - pub client_use_random_mds: String, - pub client_mount_timeout: String, - pub client_tick_interval: String, - pub client_trace: String, - pub client_readahead_min: String, - pub client_readahead_max_bytes: String, - pub client_readahead_max_periods: String, - pub client_snapdir: String, - pub client_mountpoint: String, - pub client_notify_timeout: String, - pub osd_client_watch_timeout: String, - pub client_caps_release_delay: String, - pub client_oc: String, - pub client_oc_size: String, - pub client_oc_max_dirty: String, - pub client_oc_target_dirty: String, - pub client_oc_max_dirty_age: String, - pub client_oc_max_objects: String, - pub client_debug_force_sync_read: String, - pub client_debug_inject_tick_delay: String, - pub client_max_inline_size: String, - pub fuse_use_invalidate_cb: String, - pub fuse_allow_other: String, - pub fuse_default_permissions: String, - pub fuse_big_writes: String, - pub fuse_atomic_o_trunc: String, - pub fuse_debug: String, - pub fuse_multithreaded: String, - pub crush_location: String, - pub objecter_tick_interval: String, - pub objecter_timeout: String, - pub objecter_inflight_op_bytes: String, - pub objecter_inflight_ops: String, - pub journaler_allow_split_entries: String, - pub journaler_write_head_interval: String, - pub journaler_prefetch_periods: String, - pub journaler_prezero_periods: String, - pub journaler_batch_interval: String, - pub journaler_batch_max: String, - pub mds_data: String, - pub mds_max_file_size: String, - pub mds_cache_size: String, - pub mds_cache_mid: String, - pub mds_mem_max: String, - pub mds_dir_max_commit_size: String, - pub mds_decay_halflife: String, - pub mds_beacon_interval: String, - pub mds_beacon_grace: String, - pub mds_enforce_unique_name: String, - pub mds_interval: String, - pub mds_session_timeout: String, - pub mds_freeze_tree_timeout: String, - pub mds_session_autoclose: String, - pub mds_reconnect_timeout: String, - pub mds_tick_interval: String, - pub mds_dirstat_min_interval: String, - pub mds_scatter_nudge_interval: String, - pub mds_client_prealloc_inos: String, - pub mds_early_reply: String, - pub mds_default_dir_hash: String, - pub mds_log: String, - pub mds_log_skip_corrupt_events: String, - pub mds_log_max_events: String, - pub mds_log_segment_size: String, - pub mds_log_max_segments: String, - pub mds_log_max_expiring: String, - pub mds_bal_sample_interval: String, - pub mds_bal_replicate_threshold: String, - pub mds_bal_unreplicate_threshold: String, - pub mds_bal_frag: String, - pub mds_bal_split_size: String, - pub mds_bal_split_rd: String, - pub mds_bal_split_wr: String, - pub mds_bal_split_bits: String, - pub mds_bal_merge_size: String, - pub mds_bal_merge_rd: String, - pub mds_bal_merge_wr: String, - pub mds_bal_interval: String, - pub mds_bal_fragment_interval: String, - pub mds_bal_idle_threshold: String, - pub mds_bal_max: String, - pub mds_bal_max_until: String, - pub mds_bal_mode: String, - pub mds_bal_min_rebalance: String, - pub mds_bal_min_start: String, - pub mds_bal_need_min: String, - pub mds_bal_need_max: String, - pub mds_bal_midchunk: String, - pub mds_bal_minchunk: String, - pub mds_bal_target_removal_min: String, - pub mds_bal_target_removal_max: String, - pub mds_replay_interval: String, - pub mds_shutdown_check: String, - pub mds_thrash_exports: String, - pub mds_thrash_fragments: String, - pub mds_dump_cache_on_map: String, - pub mds_dump_cache_after_rejoin: String, - pub mds_verify_scatter: String, - pub mds_debug_scatterstat: String, - pub mds_debug_frag: String, - pub mds_debug_auth_pins: String, - pub mds_debug_subtrees: String, - pub mds_kill_mdstable_at: String, - pub mds_kill_export_at: String, - pub mds_kill_import_at: String, - pub mds_kill_link_at: String, - pub mds_kill_rename_at: String, - pub mds_kill_openc_at: String, - pub mds_kill_journal_at: String, - pub mds_kill_journal_expire_at: String, - pub mds_kill_journal_replay_at: String, - pub mds_kill_create_at: String, - pub mds_open_remote_link_mode: String, - pub mds_inject_traceless_reply_probability: String, - pub mds_wipe_sessions: String, - pub mds_wipe_ino_prealloc: String, - pub mds_skip_ino: String, - pub max_mds: String, - pub mds_standby_for_name: String, - pub mds_standby_for_rank: String, - pub mds_standby_replay: String, - pub osd_compact_leveldb_on_mount: String, - pub osd_max_backfills: String, - pub osd_backfill_full_ratio: String, - pub osd_backfill_retry_interval: String, - pub osd_agent_max_ops: String, - pub osd_agent_min_evict_effort: String, - pub osd_agent_quantize_effort: String, - pub osd_agent_delay_time: String, - pub osd_agent_hist_halflife: String, - pub osd_agent_slop: String, - pub osd_uuid: String, - pub osd_data: String, - pub osd_journal: String, - pub osd_journal_size: String, - pub osd_max_write_size: String, - pub osd_max_pgls: String, - pub osd_client_message_size_cap: String, - pub osd_client_message_cap: String, - pub osd_pg_bits: String, - pub osd_pgp_bits: String, - pub osd_crush_chooseleaf_type: String, - pub osd_pool_default_crush_rule: String, - pub osd_pool_default_crush_replicated_ruleset: String, - pub osd_pool_erasure_code_stripe_width: String, - pub osd_pool_default_size: String, - pub osd_pool_default_min_size: String, - pub osd_pool_default_pg_num: String, - pub osd_pool_default_pgp_num: String, - pub osd_pool_default_erasure_code_directory: String, - pub osd_pool_default_erasure_code_profile: String, - pub osd_erasure_code_plugins: String, - pub osd_pool_default_flags: String, - pub osd_pool_default_flag_hashpspool: String, - pub osd_pool_default_hit_set_bloom_fpp: String, - pub osd_pool_default_cache_target_dirty_ratio: String, - pub osd_pool_default_cache_target_full_ratio: String, - pub osd_pool_default_cache_min_flush_age: String, - pub osd_pool_default_cache_min_evict_age: String, - pub osd_hit_set_min_size: String, - pub osd_hit_set_max_size: String, - pub osd_hit_set_namespace: String, - pub osd_tier_default_cache_mode: String, - pub osd_tier_default_cache_hit_set_count: String, - pub osd_tier_default_cache_hit_set_period: String, - pub osd_tier_default_cache_hit_set_type: String, - pub osd_map_dedup: String, - pub osd_map_max_advance: String, - pub osd_map_cache_size: String, - pub osd_map_message_max: String, - pub osd_map_share_max_epochs: String, - pub osd_op_threads: String, - pub osd_peering_wq_batch_size: String, - pub osd_op_pq_max_tokens_per_priority: String, - pub osd_op_pq_min_cost: String, - pub osd_disk_threads: String, - pub osd_disk_thread_ioprio_class: String, - pub osd_disk_thread_ioprio_priority: String, - pub osd_recovery_threads: String, - pub osd_recover_clone_overlap: String, - pub osd_recover_clone_overlap_limit: String, - pub osd_backfill_scan_min: String, - pub osd_backfill_scan_max: String, - pub osd_op_thread_timeout: String, - pub osd_recovery_thread_timeout: String, - pub osd_snap_trim_thread_timeout: String, - pub osd_snap_trim_sleep: String, - pub osd_scrub_thread_timeout: String, - pub osd_scrub_finalize_thread_timeout: String, - pub osd_scrub_invalid_stats: String, - pub osd_remove_thread_timeout: String, - pub osd_command_thread_timeout: String, - pub osd_age: String, - pub osd_age_time: String, - pub osd_heartbeat_addr: String, - pub osd_heartbeat_interval: String, - pub osd_heartbeat_grace: String, - pub osd_heartbeat_min_peers: String, - pub osd_pg_max_concurrent_snap_trims: String, - pub osd_heartbeat_min_healthy_ratio: String, - pub osd_mon_heartbeat_interval: String, - pub osd_mon_report_interval_max: String, - pub osd_mon_report_interval_min: String, - pub osd_pg_stat_report_interval_max: String, - pub osd_mon_ack_timeout: String, - pub osd_default_data_pool_replay_window: String, - pub osd_preserve_trimmed_log: String, - pub osd_auto_mark_unfound_lost: String, - pub osd_recovery_delay_start: String, - pub osd_recovery_max_active: String, - pub osd_recovery_max_single_start: String, - pub osd_recovery_max_chunk: String, - pub osd_copyfrom_max_chunk: String, - pub osd_push_per_object_cost: String, - pub osd_max_push_cost: String, - pub osd_max_push_objects: String, - pub osd_recovery_forget_lost_objects: String, - pub osd_max_scrubs: String, - pub osd_scrub_load_threshold: String, - pub osd_scrub_min_interval: String, - pub osd_scrub_max_interval: String, - pub osd_scrub_chunk_min: String, - pub osd_scrub_chunk_max: String, - pub osd_scrub_sleep: String, - pub osd_deep_scrub_interval: String, - pub osd_deep_scrub_stride: String, - pub osd_scan_list_ping_tp_interval: String, - pub osd_auto_weight: String, - pub osd_class_dir: String, - pub osd_open_classes_on_start: String, - pub osd_check_for_log_corruption: String, - pub osd_use_stale_snap: String, - pub osd_rollback_to_cluster_snap: String, - pub osd_default_notify_timeout: String, - pub osd_kill_backfill_at: String, - pub osd_pg_epoch_persisted_max_stale: String, - pub osd_min_pg_log_entries: String, - pub osd_max_pg_log_entries: String, - pub osd_op_complaint_time: String, - pub osd_command_max_records: String, - pub osd_op_log_threshold: String, - pub osd_verify_sparse_read_holes: String, - pub osd_debug_drop_ping_probability: String, - pub osd_debug_drop_ping_duration: String, - pub osd_debug_drop_pg_create_probability: String, - pub osd_debug_drop_pg_create_duration: String, - pub osd_debug_drop_op_probability: String, - pub osd_debug_op_order: String, - pub osd_debug_verify_snaps_on_info: String, - pub osd_debug_verify_stray_on_activate: String, - pub osd_debug_skip_full_check_in_backfill_reservation: String, - pub osd_debug_reject_backfill_probability: String, - pub osd_enable_op_tracker: String, -} - -fn main() {} diff --git a/tests/ui/issues/issue-29663.rs b/tests/ui/issues/issue-29663.rs index ed512f14f4ce..9f7de6b72e11 100644 --- a/tests/ui/issues/issue-29663.rs +++ b/tests/ui/issues/issue-29663.rs @@ -1,8 +1,6 @@ //@ run-pass -#![allow(stable_features)] // write_volatile causes an LLVM assert with composite types -#![feature(volatile)] use std::ptr::{read_volatile, write_volatile}; #[derive(Debug, Eq, PartialEq)] diff --git a/tests/ui/issues/issue-29740.rs b/tests/ui/issues/issue-29740.rs deleted file mode 100644 index e26e2c882dc3..000000000000 --- a/tests/ui/issues/issue-29740.rs +++ /dev/null @@ -1,317 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -// Regression test for #29740. Inefficient MIR matching algorithms -// generated way too much code for this sort of case, leading to OOM. -#![allow(non_snake_case)] - -pub mod KeyboardEventConstants { - pub const DOM_KEY_LOCATION_STANDARD: u32 = 0; - pub const DOM_KEY_LOCATION_LEFT: u32 = 1; - pub const DOM_KEY_LOCATION_RIGHT: u32 = 2; - pub const DOM_KEY_LOCATION_NUMPAD: u32 = 3; -} // mod KeyboardEventConstants - -pub enum Key { - Space, - Apostrophe, - Comma, - Minus, - Period, - Slash, - Num0, - Num1, - Num2, - Num3, - Num4, - Num5, - Num6, - Num7, - Num8, - Num9, - Semicolon, - Equal, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - T, - U, - V, - W, - X, - Y, - Z, - LeftBracket, - Backslash, - RightBracket, - GraveAccent, - World1, - World2, - - Escape, - Enter, - Tab, - Backspace, - Insert, - Delete, - Right, - Left, - Down, - Up, - PageUp, - PageDown, - Home, - End, - CapsLock, - ScrollLock, - NumLock, - PrintScreen, - Pause, - F1, - F2, - F3, - F4, - F5, - F6, - F7, - F8, - F9, - F10, - F11, - F12, - F13, - F14, - F15, - F16, - F17, - F18, - F19, - F20, - F21, - F22, - F23, - F24, - F25, - Kp0, - Kp1, - Kp2, - Kp3, - Kp4, - Kp5, - Kp6, - Kp7, - Kp8, - Kp9, - KpDecimal, - KpDivide, - KpMultiply, - KpSubtract, - KpAdd, - KpEnter, - KpEqual, - LeftShift, - LeftControl, - LeftAlt, - LeftSuper, - RightShift, - RightControl, - RightAlt, - RightSuper, - Menu, -} - -fn key_from_string(key_string: &str, location: u32) -> Option { - match key_string { - " " => Some(Key::Space), - "\"" => Some(Key::Apostrophe), - "'" => Some(Key::Apostrophe), - "<" => Some(Key::Comma), - "," => Some(Key::Comma), - "_" => Some(Key::Minus), - "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Minus), - ">" => Some(Key::Period), - "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Period), - "?" => Some(Key::Slash), - "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Slash), - "~" => Some(Key::GraveAccent), - "`" => Some(Key::GraveAccent), - ")" => Some(Key::Num0), - "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num0), - "!" => Some(Key::Num1), - "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num1), - "@" => Some(Key::Num2), - "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num2), - "#" => Some(Key::Num3), - "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num3), - "$" => Some(Key::Num4), - "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num4), - "%" => Some(Key::Num5), - "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num5), - "^" => Some(Key::Num6), - "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num6), - "&" => Some(Key::Num7), - "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num7), - "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8), - "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8), - "(" => Some(Key::Num9), - "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num9), - ":" => Some(Key::Semicolon), - ";" => Some(Key::Semicolon), - "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal), - "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal), - "A" => Some(Key::A), - "a" => Some(Key::A), - "B" => Some(Key::B), - "b" => Some(Key::B), - "C" => Some(Key::C), - "c" => Some(Key::C), - "D" => Some(Key::D), - "d" => Some(Key::D), - "E" => Some(Key::E), - "e" => Some(Key::E), - "F" => Some(Key::F), - "f" => Some(Key::F), - "G" => Some(Key::G), - "g" => Some(Key::G), - "H" => Some(Key::H), - "h" => Some(Key::H), - "I" => Some(Key::I), - "i" => Some(Key::I), - "J" => Some(Key::J), - "j" => Some(Key::J), - "K" => Some(Key::K), - "k" => Some(Key::K), - "L" => Some(Key::L), - "l" => Some(Key::L), - "M" => Some(Key::M), - "m" => Some(Key::M), - "N" => Some(Key::N), - "n" => Some(Key::N), - "O" => Some(Key::O), - "o" => Some(Key::O), - "P" => Some(Key::P), - "p" => Some(Key::P), - "Q" => Some(Key::Q), - "q" => Some(Key::Q), - "R" => Some(Key::R), - "r" => Some(Key::R), - "S" => Some(Key::S), - "s" => Some(Key::S), - "T" => Some(Key::T), - "t" => Some(Key::T), - "U" => Some(Key::U), - "u" => Some(Key::U), - "V" => Some(Key::V), - "v" => Some(Key::V), - "W" => Some(Key::W), - "w" => Some(Key::W), - "X" => Some(Key::X), - "x" => Some(Key::X), - "Y" => Some(Key::Y), - "y" => Some(Key::Y), - "Z" => Some(Key::Z), - "z" => Some(Key::Z), - "{" => Some(Key::LeftBracket), - "[" => Some(Key::LeftBracket), - "|" => Some(Key::Backslash), - "\\" => Some(Key::Backslash), - "}" => Some(Key::RightBracket), - "]" => Some(Key::RightBracket), - "Escape" => Some(Key::Escape), - "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD - => Some(Key::Enter), - "Tab" => Some(Key::Tab), - "Backspace" => Some(Key::Backspace), - "Insert" => Some(Key::Insert), - "Delete" => Some(Key::Delete), - "ArrowRight" => Some(Key::Right), - "ArrowLeft" => Some(Key::Left), - "ArrowDown" => Some(Key::Down), - "ArrowUp" => Some(Key::Up), - "PageUp" => Some(Key::PageUp), - "PageDown" => Some(Key::PageDown), - "Home" => Some(Key::Home), - "End" => Some(Key::End), - "CapsLock" => Some(Key::CapsLock), - "ScrollLock" => Some(Key::ScrollLock), - "NumLock" => Some(Key::NumLock), - "PrintScreen" => Some(Key::PrintScreen), - "Pause" => Some(Key::Pause), - "F1" => Some(Key::F1), - "F2" => Some(Key::F2), - "F3" => Some(Key::F3), - "F4" => Some(Key::F4), - "F5" => Some(Key::F5), - "F6" => Some(Key::F6), - "F7" => Some(Key::F7), - "F8" => Some(Key::F8), - "F9" => Some(Key::F9), - "F10" => Some(Key::F10), - "F11" => Some(Key::F11), - "F12" => Some(Key::F12), - "F13" => Some(Key::F13), - "F14" => Some(Key::F14), - "F15" => Some(Key::F15), - "F16" => Some(Key::F16), - "F17" => Some(Key::F17), - "F18" => Some(Key::F18), - "F19" => Some(Key::F19), - "F20" => Some(Key::F20), - "F21" => Some(Key::F21), - "F22" => Some(Key::F22), - "F23" => Some(Key::F23), - "F24" => Some(Key::F24), - "F25" => Some(Key::F25), - "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp0), - "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp1), - "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp2), - "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp3), - "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp4), - "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp5), - "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp6), - "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp7), - "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp8), - "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp9), - "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDecimal), - "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDivide), - "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpMultiply), - "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpSubtract), - "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpAdd), - "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD - => Some(Key::KpEnter), - "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpEqual), - "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT - => Some(Key::LeftShift), - "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT - => Some(Key::LeftControl), - "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftAlt), - "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT - => Some(Key::LeftSuper), - "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT - => Some(Key::RightShift), - "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT - => Some(Key::RightControl), - "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightAlt), - "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT - => Some(Key::RightSuper), - "ContextMenu" => Some(Key::Menu), - _ => None - } -} - -fn main() { } diff --git a/tests/ui/issues/issue-2995.rs b/tests/ui/issues/issue-2995.rs deleted file mode 100644 index 0da7909480d2..000000000000 --- a/tests/ui/issues/issue-2995.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn bad (p: *const isize) { - let _q: &isize = p as &isize; //~ ERROR non-primitive cast -} - -fn main() { } diff --git a/tests/ui/issues/issue-2995.stderr b/tests/ui/issues/issue-2995.stderr deleted file mode 100644 index f4a08e1751fc..000000000000 --- a/tests/ui/issues/issue-2995.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0605]: non-primitive cast: `*const isize` as `&isize` - --> $DIR/issue-2995.rs:2:22 - | -LL | let _q: &isize = p as &isize; - | ^^^^^^^^^^^ invalid cast - | -help: consider borrowing the value - | -LL - let _q: &isize = p as &isize; -LL + let _q: &isize = &*p; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/issues/issue-3026.rs b/tests/ui/issues/issue-3026.rs deleted file mode 100644 index 05dc46c3cc09..000000000000 --- a/tests/ui/issues/issue-3026.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass - -use std::collections::HashMap; - -pub fn main() { - let x: Box<_>; - let mut buggy_map: HashMap = HashMap::new(); - x = Box::new(1); - buggy_map.insert(42, &*x); -} diff --git a/tests/ui/issues/issue-3029.rs b/tests/ui/issues/issue-3029.rs deleted file mode 100644 index 22d0906ccf70..000000000000 --- a/tests/ui/issues/issue-3029.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-fail -//@ error-pattern:so long -//@ needs-subprocess - -#![allow(unreachable_code)] - -fn main() { - let mut x = Vec::new(); - let y = vec![3]; - panic!("so long"); - x.extend(y.into_iter()); -} diff --git a/tests/ui/issues/issue-3038.rs b/tests/ui/issues/issue-3038.rs deleted file mode 100644 index cf3ba009f00c..000000000000 --- a/tests/ui/issues/issue-3038.rs +++ /dev/null @@ -1,26 +0,0 @@ -enum F { G(isize, isize) } - -enum H { I(J, K) } - -enum J { L(isize, isize) } -enum K { M(isize, isize) } - -fn main() -{ - - let _z = match F::G(1, 2) { - F::G(x, x) => { println!("{}", x + x); } - //~^ ERROR identifier `x` is bound more than once in the same pattern - }; - - let _z = match H::I(J::L(1, 2), K::M(3, 4)) { - H::I(J::L(x, _), K::M(_, x)) - //~^ ERROR identifier `x` is bound more than once in the same pattern - => { println!("{}", x + x); } - }; - - let _z = match (1, 2) { - (x, x) => { x } //~ ERROR identifier `x` is bound more than once in the same pattern - }; - -} diff --git a/tests/ui/issues/issue-3038.stderr b/tests/ui/issues/issue-3038.stderr deleted file mode 100644 index 210da2ceff9b..000000000000 --- a/tests/ui/issues/issue-3038.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0416]: identifier `x` is bound more than once in the same pattern - --> $DIR/issue-3038.rs:12:15 - | -LL | F::G(x, x) => { println!("{}", x + x); } - | ^ used in a pattern more than once - -error[E0416]: identifier `x` is bound more than once in the same pattern - --> $DIR/issue-3038.rs:17:32 - | -LL | H::I(J::L(x, _), K::M(_, x)) - | ^ used in a pattern more than once - -error[E0416]: identifier `x` is bound more than once in the same pattern - --> $DIR/issue-3038.rs:23:13 - | -LL | (x, x) => { x } - | ^ used in a pattern more than once - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0416`. diff --git a/tests/ui/issues/issue-3052.rs b/tests/ui/issues/issue-3052.rs deleted file mode 100644 index ab3519fe7147..000000000000 --- a/tests/ui/issues/issue-3052.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -type Connection = Box) + 'static>; - -fn f() -> Option { - let mock_connection: Connection = Box::new(|_| {}); - Some(mock_connection) -} - -pub fn main() { -} diff --git a/tests/ui/issues/issue-3091.rs b/tests/ui/issues/issue-3091.rs deleted file mode 100644 index a4f9b3718446..000000000000 --- a/tests/ui/issues/issue-3091.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -pub fn main() { - let x = 1; - let y = 1; - assert_eq!(&x, &y); -} diff --git a/tests/ui/issues/issue-3121.rs b/tests/ui/issues/issue-3121.rs deleted file mode 100644 index aa150f11cf40..000000000000 --- a/tests/ui/issues/issue-3121.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -#[derive(Copy, Clone)] -enum side { mayo, catsup, vinegar } -#[derive(Copy, Clone)] -enum order { hamburger, fries(side), shake } -#[derive(Copy, Clone)] -enum meal { to_go(order), for_here(order) } - -fn foo(m: Box, cond: bool) { - match *m { - meal::to_go(_) => { } - meal::for_here(_) if cond => {} - meal::for_here(order::hamburger) => {} - meal::for_here(order::fries(_s)) => {} - meal::for_here(order::shake) => {} - } -} - -pub fn main() { - foo(Box::new(meal::for_here(order::hamburger)), true) -} diff --git a/tests/ui/issues/issue-31267.rs b/tests/ui/issues/issue-31267.rs deleted file mode 100644 index d6081bb87439..000000000000 --- a/tests/ui/issues/issue-31267.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -// Regression test for issue #31267 - - -struct Foo; - -impl Foo { - const FOO: [i32; 3] = [0; 3]; -} - -pub fn main() { - let foo = Foo::FOO; - assert_eq!(foo, [0i32, 0, 0]); -} diff --git a/tests/ui/issues/issue-32004.rs b/tests/ui/issues/issue-32004.rs deleted file mode 100644 index b3493508c5a9..000000000000 --- a/tests/ui/issues/issue-32004.rs +++ /dev/null @@ -1,19 +0,0 @@ -enum Foo { - Bar(i32), - Baz -} - -struct S; - -fn main() { - match Foo::Baz { - Foo::Bar => {} - //~^ ERROR expected unit struct, unit variant or constant, found tuple variant `Foo::Bar` - _ => {} - } - - match S { - S(()) => {} - //~^ ERROR expected tuple struct or tuple variant, found unit struct `S` - } -} diff --git a/tests/ui/issues/issue-32004.stderr b/tests/ui/issues/issue-32004.stderr deleted file mode 100644 index fcbec97661b4..000000000000 --- a/tests/ui/issues/issue-32004.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0532]: expected unit struct, unit variant or constant, found tuple variant `Foo::Bar` - --> $DIR/issue-32004.rs:10:9 - | -LL | Bar(i32), - | -------- `Foo::Bar` defined here -LL | Baz - | --- similarly named unit variant `Baz` defined here -... -LL | Foo::Bar => {} - | ^^^^^^^^ - | -help: use the tuple variant pattern syntax instead - | -LL | Foo::Bar(_) => {} - | +++ -help: a unit variant with a similar name exists - | -LL - Foo::Bar => {} -LL + Foo::Baz => {} - | - -error[E0532]: expected tuple struct or tuple variant, found unit struct `S` - --> $DIR/issue-32004.rs:16:9 - | -LL | struct S; - | --------- `S` defined here -... -LL | S(()) => {} - | ^^^^^ help: use this syntax instead: `S` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0532`. diff --git a/tests/ui/issues/issue-3290.rs b/tests/ui/issues/issue-3290.rs deleted file mode 100644 index 50c432288ce1..000000000000 --- a/tests/ui/issues/issue-3290.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -pub fn main() { - let mut x: Box<_> = Box::new(3); - x = x; - assert_eq!(*x, 3); -} diff --git a/tests/ui/issues/issue-33687.rs b/tests/ui/issues/issue-33687.rs deleted file mode 100644 index a5693b3aca8e..000000000000 --- a/tests/ui/issues/issue-33687.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -#![feature(unboxed_closures)] -#![feature(fn_traits)] - -struct Test; - -impl FnOnce<(u32, u32)> for Test { - type Output = u32; - - extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { - a + b - } -} - -fn main() { - assert_eq!(Test(1u32, 2u32), 3u32); -} diff --git a/tests/ui/issues/issue-34047.rs b/tests/ui/issues/issue-34047.rs deleted file mode 100644 index 55196177f693..000000000000 --- a/tests/ui/issues/issue-34047.rs +++ /dev/null @@ -1,8 +0,0 @@ -const C: u8 = 0; - -fn main() { - match 1u8 { - mut C => {} //~ ERROR match bindings cannot shadow constants - _ => {} - } -} diff --git a/tests/ui/issues/issue-34047.stderr b/tests/ui/issues/issue-34047.stderr deleted file mode 100644 index 97b1230ce350..000000000000 --- a/tests/ui/issues/issue-34047.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0530]: match bindings cannot shadow constants - --> $DIR/issue-34047.rs:5:13 - | -LL | const C: u8 = 0; - | ---------------- the constant `C` is defined here -... -LL | mut C => {} - | ^ cannot be named the same as a constant - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0530`. diff --git a/tests/ui/issues/issue-34074.rs b/tests/ui/issues/issue-34074.rs deleted file mode 100644 index d642c74d412a..000000000000 --- a/tests/ui/issues/issue-34074.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ edition: 2015 -//@ check-pass -// Make sure several unnamed function parameters don't conflict with each other - -trait Tr { - #[allow(anonymous_parameters)] - fn f(u8, u8) {} -} - -fn main() { -} diff --git a/tests/ui/issues/issue-34209.rs b/tests/ui/issues/issue-34209.rs deleted file mode 100644 index 632ddb91b36f..000000000000 --- a/tests/ui/issues/issue-34209.rs +++ /dev/null @@ -1,11 +0,0 @@ -enum S { - A, -} - -fn bug(l: S) { - match l { - S::B {} => {}, //~ ERROR no variant named `B` found for enum `S` - } -} - -fn main () {} diff --git a/tests/ui/issues/issue-34209.stderr b/tests/ui/issues/issue-34209.stderr deleted file mode 100644 index 83b40d0c0816..000000000000 --- a/tests/ui/issues/issue-34209.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0599]: no variant named `B` found for enum `S` - --> $DIR/issue-34209.rs:7:12 - | -LL | enum S { - | ------ variant `B` not found here -... -LL | S::B {} => {}, - | ^ - | -help: there is a variant with a similar name - | -LL - S::B {} => {}, -LL + S::A {} => {}, - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-3429.rs b/tests/ui/issues/issue-3429.rs deleted file mode 100644 index 39d657573db7..000000000000 --- a/tests/ui/issues/issue-3429.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -pub fn main() { - let x = 1_usize; - let y = || x; - let _z = y(); -} diff --git a/tests/ui/issues/issue-34373.rs b/tests/ui/issues/issue-34373.rs index 5b05811a4eb3..765bfc20a451 100644 --- a/tests/ui/issues/issue-34373.rs +++ b/tests/ui/issues/issue-34373.rs @@ -4,8 +4,9 @@ trait Trait { fn foo(_: T) {} } -pub struct Foo>>; //~ ERROR cycle detected -//~^ ERROR `T` is never used +pub struct Foo>>; +//~^ ERROR cycle detected when computing type of `Foo::T` +//~| ERROR type parameter `T` is never used type DefaultFoo = Foo; fn main() { diff --git a/tests/ui/issues/issue-34373.stderr b/tests/ui/issues/issue-34373.stderr index 03d771931341..6d68de8fb3b8 100644 --- a/tests/ui/issues/issue-34373.stderr +++ b/tests/ui/issues/issue-34373.stderr @@ -5,7 +5,7 @@ LL | pub struct Foo>>; | ^^^^^^^^^^ | note: ...which requires expanding type alias `DefaultFoo`... - --> $DIR/issue-34373.rs:9:19 + --> $DIR/issue-34373.rs:10:19 | LL | type DefaultFoo = Foo; | ^^^ diff --git a/tests/ui/issues/issue-34569.rs b/tests/ui/issues/issue-34569.rs deleted file mode 100644 index 25b2e7fbe160..000000000000 --- a/tests/ui/issues/issue-34569.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -//@ compile-flags:-g - -// In this test we just want to make sure that the code below does not lead to -// a debuginfo verification assertion during compilation. This was caused by the -// closure in the guard being codegened twice due to how match expressions are -// handled. -// -// See https://github.com/rust-lang/rust/issues/34569 for details. - -fn main() { - match 0 { - e if (|| { e == 0 })() => {}, - 1 => {}, - _ => {} - } -} diff --git a/tests/ui/issues/issue-34780.rs b/tests/ui/issues/issue-34780.rs index ee5cc0750dce..4470e3af682b 100644 --- a/tests/ui/issues/issue-34780.rs +++ b/tests/ui/issues/issue-34780.rs @@ -1,6 +1,4 @@ //@ check-pass -#![allow(stable_features)] -#![feature(associated_consts)] use std::marker::PhantomData; diff --git a/tests/ui/issues/issue-3500.rs b/tests/ui/issues/issue-3500.rs deleted file mode 100644 index 0860d0f59260..000000000000 --- a/tests/ui/issues/issue-3500.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass - -pub fn main() { - let x = &Some(1); - match x { - &Some(_) => (), - &None => (), - } -} diff --git a/tests/ui/issues/issue-35241.rs b/tests/ui/issues/issue-35241.rs deleted file mode 100644 index 2fa762475da9..000000000000 --- a/tests/ui/issues/issue-35241.rs +++ /dev/null @@ -1,5 +0,0 @@ -struct Foo(u32); - -fn test() -> Foo { Foo } //~ ERROR mismatched types - -fn main() {} diff --git a/tests/ui/issues/issue-35241.stderr b/tests/ui/issues/issue-35241.stderr deleted file mode 100644 index 6f6602793fdb..000000000000 --- a/tests/ui/issues/issue-35241.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-35241.rs:3:20 - | -LL | struct Foo(u32); - | ---------- `Foo` defines a struct constructor here, which should be called -LL | -LL | fn test() -> Foo { Foo } - | --- ^^^ expected `Foo`, found struct constructor - | | - | expected `Foo` because of return type - | - = note: expected struct `Foo` - found struct constructor `fn(u32) -> Foo {Foo}` -help: use parentheses to construct this tuple struct - | -LL | fn test() -> Foo { Foo(/* u32 */) } - | +++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-36400.rs b/tests/ui/issues/issue-36400.rs deleted file mode 100644 index a405f9b11352..000000000000 --- a/tests/ui/issues/issue-36400.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn f(x: &mut u32) {} - -fn main() { - let x = Box::new(3); - f(&mut *x); //~ ERROR cannot borrow `*x` as mutable, as `x` is not declared as mutable -} diff --git a/tests/ui/issues/issue-36400.stderr b/tests/ui/issues/issue-36400.stderr deleted file mode 100644 index 522fb36e1434..000000000000 --- a/tests/ui/issues/issue-36400.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable - --> $DIR/issue-36400.rs:5:7 - | -LL | f(&mut *x); - | ^^^^^^^ cannot borrow as mutable - | -help: consider changing this to be mutable - | -LL | let mut x = Box::new(3); - | +++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/issues/issue-3680.rs b/tests/ui/issues/issue-3680.rs deleted file mode 100644 index 7fdc6e179e47..000000000000 --- a/tests/ui/issues/issue-3680.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - match None { //~ NOTE this expression has type `Option<_>` - Err(_) => () - //~^ ERROR mismatched types - //~| NOTE expected enum `Option<_>` - //~| NOTE found enum `Result<_, _>` - //~| NOTE expected `Option<_>`, found `Result<_, _>` - } -} diff --git a/tests/ui/issues/issue-3680.stderr b/tests/ui/issues/issue-3680.stderr deleted file mode 100644 index 2a757b44dc83..000000000000 --- a/tests/ui/issues/issue-3680.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-3680.rs:3:9 - | -LL | match None { - | ---- this expression has type `Option<_>` -LL | Err(_) => () - | ^^^^^^ expected `Option<_>`, found `Result<_, _>` - | - = note: expected enum `Option<_>` - found enum `Result<_, _>` -help: try wrapping the pattern in `Some` - | -LL | Some(Err(_)) => () - | +++++ + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-37131.rs b/tests/ui/issues/issue-37131.rs index e91c76e1390e..875495d08ed7 100644 --- a/tests/ui/issues/issue-37131.rs +++ b/tests/ui/issues/issue-37131.rs @@ -7,5 +7,6 @@ //@ compile-flags: --target=thumbv6m-none-eabi //@ ignore-arm //@ needs-llvm-components: arm +//@ ignore-backends: gcc fn main() { } diff --git a/tests/ui/issues/issue-37576.rs b/tests/ui/issues/issue-37576.rs deleted file mode 100644 index e7f933ab22ea..000000000000 --- a/tests/ui/issues/issue-37576.rs +++ /dev/null @@ -1,45 +0,0 @@ -fn main() { - 'test_1: while break 'test_1 {} - while break {} - //~^ ERROR `break` or `continue` with no label - - 'test_2: while let true = break 'test_2 {} - while let true = break {} - //~^ ERROR `break` or `continue` with no label - - loop { 'test_3: while break 'test_3 {} } - loop { while break {} } - //~^ ERROR `break` or `continue` with no label - - loop { - 'test_4: while break 'test_4 {} - break; - } - loop { - while break {} - //~^ ERROR `break` or `continue` with no label - break; - } - - 'test_5: while continue 'test_5 {} - while continue {} - //~^ ERROR `break` or `continue` with no label - - 'test_6: while let true = continue 'test_6 {} - while let true = continue {} - //~^ ERROR `break` or `continue` with no label - - loop { 'test_7: while continue 'test_7 {} } - loop { while continue {} } - //~^ ERROR `break` or `continue` with no label - - loop { - 'test_8: while continue 'test_8 {} - continue; - } - loop { - while continue {} - //~^ ERROR `break` or `continue` with no label - continue; - } -} diff --git a/tests/ui/issues/issue-37576.stderr b/tests/ui/issues/issue-37576.stderr deleted file mode 100644 index d19e1f45393a..000000000000 --- a/tests/ui/issues/issue-37576.stderr +++ /dev/null @@ -1,51 +0,0 @@ -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:3:11 - | -LL | while break {} - | ^^^^^ unlabeled `break` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:7:22 - | -LL | while let true = break {} - | ^^^^^ unlabeled `break` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:11:18 - | -LL | loop { while break {} } - | ^^^^^ unlabeled `break` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:19:15 - | -LL | while break {} - | ^^^^^ unlabeled `break` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:25:11 - | -LL | while continue {} - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:29:22 - | -LL | while let true = continue {} - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:33:18 - | -LL | loop { while continue {} } - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop - -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-37576.rs:41:15 - | -LL | while continue {} - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0590`. diff --git a/tests/ui/issues/issue-37686.rs b/tests/ui/issues/issue-37686.rs deleted file mode 100644 index 5a72f2fc74c2..000000000000 --- a/tests/ui/issues/issue-37686.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass -fn main() { - match (0, 0) { - (usize::MIN, usize::MAX) => {} - _ => {} - } -} diff --git a/tests/ui/issues/issue-38458.rs b/tests/ui/issues/issue-38458.rs deleted file mode 100644 index 665a8fdf8e26..000000000000 --- a/tests/ui/issues/issue-38458.rs +++ /dev/null @@ -1,5 +0,0 @@ -const x: () = { - return; //~ ERROR return statement outside of function body -}; - -fn main() {} diff --git a/tests/ui/issues/issue-38458.stderr b/tests/ui/issues/issue-38458.stderr deleted file mode 100644 index fbf88d503397..000000000000 --- a/tests/ui/issues/issue-38458.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0572]: return statement outside of function body - --> $DIR/issue-38458.rs:2:5 - | -LL | return; - | ^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0572`. diff --git a/tests/ui/issues/issue-38857.rs b/tests/ui/issues/issue-38857.rs index 81d881c100bb..63a0af759a3d 100644 --- a/tests/ui/issues/issue-38857.rs +++ b/tests/ui/issues/issue-38857.rs @@ -1,5 +1,5 @@ fn main() { let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; - //~^ ERROR failed to resolve: could not find `imp` in `sys` [E0433] - //~^^ ERROR module `sys` is private [E0603] + //~^ ERROR: cannot find `imp` in `sys` [E0433] + //~| ERROR: module `sys` is private [E0603] } diff --git a/tests/ui/issues/issue-38857.stderr b/tests/ui/issues/issue-38857.stderr index 4d505784b865..85a0c266ac65 100644 --- a/tests/ui/issues/issue-38857.stderr +++ b/tests/ui/issues/issue-38857.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `imp` in `sys` +error[E0433]: cannot find `imp` in `sys` --> $DIR/issue-38857.rs:2:23 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; diff --git a/tests/ui/issues/issue-38919.rs b/tests/ui/issues/issue-38919.rs deleted file mode 100644 index 3d28f1936b47..000000000000 --- a/tests/ui/issues/issue-38919.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn foo() { - T::Item; //~ ERROR no associated item named `Item` found -} - -fn main() { } diff --git a/tests/ui/issues/issue-38919.stderr b/tests/ui/issues/issue-38919.stderr deleted file mode 100644 index 4a4bd2ee43d8..000000000000 --- a/tests/ui/issues/issue-38919.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0599]: no associated item named `Item` found for type parameter `T` in the current scope - --> $DIR/issue-38919.rs:2:8 - | -LL | fn foo() { - | - associated item `Item` not found for this type parameter -LL | T::Item; - | ^^^^ associated item not found in `T` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-38987.rs b/tests/ui/issues/issue-38987.rs deleted file mode 100644 index 713fd5027918..000000000000 --- a/tests/ui/issues/issue-38987.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ run-pass -fn main() { - let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; -} diff --git a/tests/ui/issues/issue-3993.rs b/tests/ui/issues/issue-3993.rs deleted file mode 100644 index 9dea54ea779e..000000000000 --- a/tests/ui/issues/issue-3993.rs +++ /dev/null @@ -1,10 +0,0 @@ -use zoo::fly; //~ ERROR: function `fly` is private - -mod zoo { - fn fly() {} -} - - -fn main() { - fly(); -} diff --git a/tests/ui/issues/issue-3993.stderr b/tests/ui/issues/issue-3993.stderr deleted file mode 100644 index cf839a131406..000000000000 --- a/tests/ui/issues/issue-3993.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0603]: function `fly` is private - --> $DIR/issue-3993.rs:1:10 - | -LL | use zoo::fly; - | ^^^ private function - | -note: the function `fly` is defined here - --> $DIR/issue-3993.rs:4:5 - | -LL | fn fly() {} - | ^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/issues/issue-41998.rs b/tests/ui/issues/issue-41998.rs deleted file mode 100644 index 303bf7a57513..000000000000 --- a/tests/ui/issues/issue-41998.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ check-pass - - -fn main() { - if ('x' as char) < ('y' as char) { - print!("x"); - } else { - print!("y"); - } -} diff --git a/tests/ui/issues/issue-42453.rs b/tests/ui/issues/issue-42453.rs deleted file mode 100644 index 9ed9080e8a92..000000000000 --- a/tests/ui/issues/issue-42453.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -#![allow(non_camel_case_types)] - -#[derive(Debug)] -struct builder; - -fn main() { - -} diff --git a/tests/ui/issues/issue-4265.stderr b/tests/ui/issues/issue-4265.stderr index 23d00aaa44b5..d4a44c129a89 100644 --- a/tests/ui/issues/issue-4265.stderr +++ b/tests/ui/issues/issue-4265.stderr @@ -14,10 +14,7 @@ LL | struct Foo { | ---------- method `bar` not found for this struct ... LL | Foo { baz: 0 }.bar(); - | ---------------^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `Foo::bar()` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Foo` @@ -25,6 +22,11 @@ note: the candidate is defined in an impl for the type `Foo` | LL | fn bar() { | ^^^^^^^^ +help: use associated function syntax instead + | +LL - Foo { baz: 0 }.bar(); +LL + Foo::bar(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-42796.stderr b/tests/ui/issues/issue-42796.stderr index 670b98c77089..0e7ce9e98c4d 100644 --- a/tests/ui/issues/issue-42796.stderr +++ b/tests/ui/issues/issue-42796.stderr @@ -9,7 +9,6 @@ LL | let mut s_copy = s; LL | println!("{}", s); | ^ value borrowed here after move | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value if the performance cost is acceptable | LL | let mut s_copy = s.clone(); diff --git a/tests/ui/issues/issue-42956.rs b/tests/ui/issues/issue-42956.rs index a124ca84f3c3..5d6d4249a7d8 100644 --- a/tests/ui/issues/issue-42956.rs +++ b/tests/ui/issues/issue-42956.rs @@ -1,7 +1,5 @@ //@ check-pass #![allow(dead_code)] -#![allow(stable_features)] -#![feature(associated_consts)] impl A for i32 { type Foo = u32; diff --git a/tests/ui/issues/issue-43057.rs b/tests/ui/issues/issue-43057.rs deleted file mode 100644 index 4dd1fe461f1b..000000000000 --- a/tests/ui/issues/issue-43057.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ check-pass -#![allow(unused)] - -macro_rules! column { - ($i:ident) => { - $i - }; -} - -fn foo() -> ! { - panic!(); -} - -fn main() {} diff --git a/tests/ui/issues/issue-43205.rs b/tests/ui/issues/issue-43205.rs deleted file mode 100644 index 9f54d4258bf1..000000000000 --- a/tests/ui/issues/issue-43205.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ run-pass -fn main() { - let _ = &&[()][0]; - println!("{:?}", &[(),()][1]); -} diff --git a/tests/ui/issues/issue-43988.stderr b/tests/ui/issues/issue-43988.stderr index 0219eeb693e7..d393255e0ee1 100644 --- a/tests/ui/issues/issue-43988.stderr +++ b/tests/ui/issues/issue-43988.stderr @@ -60,17 +60,6 @@ LL | #[repr] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[repr()] - | ++++++++++++++++ -LL | #[repr(C)] - | +++ -LL | #[repr(Rust)] - | ++++++ -LL | #[repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0539]: malformed `inline` attribute input --> $DIR/issue-43988.rs:31:5 @@ -108,17 +97,6 @@ LL | let _z = #[repr] 1; | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | let _z = #[repr()] 1; - | ++++++++++++++++ -LL | let _z = #[repr(C)] 1; - | +++ -LL | let _z = #[repr(Rust)] 1; - | ++++++ -LL | let _z = #[repr(align(...))] 1; - | ++++++++++++ - = and 2 other candidates error: aborting due to 9 previous errors diff --git a/tests/ui/issues/issue-44078.rs b/tests/ui/issues/issue-44078.rs deleted file mode 100644 index b8c0e285ffca..000000000000 --- a/tests/ui/issues/issue-44078.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - "😊""; //~ ERROR unterminated double quote -} diff --git a/tests/ui/issues/issue-44078.stderr b/tests/ui/issues/issue-44078.stderr deleted file mode 100644 index 3e12de34e11e..000000000000 --- a/tests/ui/issues/issue-44078.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0765]: unterminated double quote string - --> $DIR/issue-44078.rs:2:8 - | -LL | "😊""; - | _________^ -LL | | } - | |__^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0765`. diff --git a/tests/ui/issues/issue-45965.rs b/tests/ui/issues/issue-45965.rs deleted file mode 100644 index 15649f777e09..000000000000 --- a/tests/ui/issues/issue-45965.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 }; - //~^ ERROR expected function, found `{float}` -} diff --git a/tests/ui/issues/issue-45965.stderr b/tests/ui/issues/issue-45965.stderr deleted file mode 100644 index 95a39b1d1980..000000000000 --- a/tests/ui/issues/issue-45965.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0618]: expected function, found `{float}` - --> $DIR/issue-45965.rs:2:30 - | -LL | let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 }; - | ^^^---------- - | | - | call expression requires function - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/issues/issue-46101.rs b/tests/ui/issues/issue-46101.rs index ab3d30d401f0..86b06f7c61d0 100644 --- a/tests/ui/issues/issue-46101.rs +++ b/tests/ui/issues/issue-46101.rs @@ -1,6 +1,6 @@ trait Foo {} -#[derive(Foo::Anything)] //~ ERROR failed to resolve: partially resolved path in a derive macro - //~| ERROR failed to resolve: partially resolved path in a derive macro +#[derive(Foo::Anything)] //~ ERROR cannot find + //~| ERROR cannot find struct S; fn main() {} diff --git a/tests/ui/issues/issue-46101.stderr b/tests/ui/issues/issue-46101.stderr index a0cdd5d5f053..1dada87d72d6 100644 --- a/tests/ui/issues/issue-46101.stderr +++ b/tests/ui/issues/issue-46101.stderr @@ -1,14 +1,14 @@ -error[E0433]: failed to resolve: partially resolved path in a derive macro +error[E0433]: cannot find derive macro `Anything` in trait `Foo` --> $DIR/issue-46101.rs:2:10 | LL | #[derive(Foo::Anything)] - | ^^^^^^^^^^^^^ partially resolved path in a derive macro + | ^^^^^^^^^^^^^ a derive macro can't exist within a trait -error[E0433]: failed to resolve: partially resolved path in a derive macro +error[E0433]: cannot find derive macro `Anything` in trait `Foo` --> $DIR/issue-46101.rs:2:10 | LL | #[derive(Foo::Anything)] - | ^^^^^^^^^^^^^ partially resolved path in a derive macro + | ^^^^^^^^^^^^^ a derive macro can't exist within a trait | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/issues/issue-46472.rs b/tests/ui/issues/issue-46472.rs deleted file mode 100644 index b9e20e8dbcb5..000000000000 --- a/tests/ui/issues/issue-46472.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn bar<'a>() -> &'a mut u32 { - &mut 4 - //~^ ERROR cannot return reference to temporary value [E0515] -} - -fn main() { } diff --git a/tests/ui/issues/issue-46472.stderr b/tests/ui/issues/issue-46472.stderr deleted file mode 100644 index 6115da28cc91..000000000000 --- a/tests/ui/issues/issue-46472.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0515]: cannot return reference to temporary value - --> $DIR/issue-46472.rs:2:5 - | -LL | &mut 4 - | ^^^^^- - | | | - | | temporary value created here - | returns a reference to data owned by the current function - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/issues/issue-46604.stderr b/tests/ui/issues/issue-46604.stderr index abe3ad476c60..21abc498de12 100644 --- a/tests/ui/issues/issue-46604.stderr +++ b/tests/ui/issues/issue-46604.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; | ^^^^^^^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item --> $DIR/issue-46604.rs:6:5 diff --git a/tests/ui/issues/issue-46983.rs b/tests/ui/issues/issue-46983.rs deleted file mode 100644 index 4bd49a8796b3..000000000000 --- a/tests/ui/issues/issue-46983.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn foo(x: &u32) -> &'static u32 { - &*x - //~^ ERROR lifetime may not live long enough -} - -fn main() {} diff --git a/tests/ui/issues/issue-46983.stderr b/tests/ui/issues/issue-46983.stderr deleted file mode 100644 index f47df306ab84..000000000000 --- a/tests/ui/issues/issue-46983.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/issue-46983.rs:2:5 - | -LL | fn foo(x: &u32) -> &'static u32 { - | - let's call the lifetime of this reference `'1` -LL | &*x - | ^^^ returning this value requires that `'1` must outlive `'static` - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-47184.rs b/tests/ui/issues/issue-47184.rs deleted file mode 100644 index 2f78ce0002ba..000000000000 --- a/tests/ui/issues/issue-47184.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let _vec: Vec<&'static String> = vec![&String::new()]; - //~^ ERROR temporary value dropped while borrowed [E0716] -} diff --git a/tests/ui/issues/issue-47184.stderr b/tests/ui/issues/issue-47184.stderr deleted file mode 100644 index d25c6eda9c34..000000000000 --- a/tests/ui/issues/issue-47184.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-47184.rs:2:44 - | -LL | let _vec: Vec<&'static String> = vec![&String::new()]; - | -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement - | | | - | | creates a temporary value which is freed while still in use - | type annotation requires that borrow lasts for `'static` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/issues/issue-47377.rs b/tests/ui/issues/issue-47377.rs deleted file mode 100644 index 7a2e0fe6d21d..000000000000 --- a/tests/ui/issues/issue-47377.rs +++ /dev/null @@ -1,6 +0,0 @@ -// ignore-tidy-tab -fn main() { - let b = "hello"; - let _a = b + ", World!"; - //~^ ERROR E0369 -} diff --git a/tests/ui/issues/issue-47377.stderr b/tests/ui/issues/issue-47377.stderr deleted file mode 100644 index 12e5c15d77fc..000000000000 --- a/tests/ui/issues/issue-47377.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0369]: cannot add `&str` to `&str` - --> $DIR/issue-47377.rs:4:14 - | -LL | let _a = b + ", World!"; - | - ^ ---------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str - | - = note: string concatenation requires an owned `String` on the left -help: create an owned `String` from a string reference - | -LL | let _a = b.to_owned() + ", World!"; - | +++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/issues/issue-47380.rs b/tests/ui/issues/issue-47380.rs deleted file mode 100644 index 61e096622252..000000000000 --- a/tests/ui/issues/issue-47380.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let b = "hello"; - println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; - //~^ ERROR E0369 -} diff --git a/tests/ui/issues/issue-47380.stderr b/tests/ui/issues/issue-47380.stderr deleted file mode 100644 index 4fca0296e437..000000000000 --- a/tests/ui/issues/issue-47380.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0369]: cannot add `&str` to `&str` - --> $DIR/issue-47380.rs:3:35 - | -LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; - | - ^ ---------- &str - | | | - | | `+` cannot be used to concatenate two `&str` strings - | &str - | - = note: string concatenation requires an owned `String` on the left -help: create an owned `String` from a string reference - | -LL | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; - | +++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/issues/issue-47673.rs b/tests/ui/issues/issue-47673.rs deleted file mode 100644 index d395ac677e75..000000000000 --- a/tests/ui/issues/issue-47673.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ check-pass -#![allow(unused_imports)] - -use {{}, {}}; - -fn main() {} diff --git a/tests/ui/issues/issue-47715.rs b/tests/ui/issues/issue-47715.rs deleted file mode 100644 index bf2b03351b29..000000000000 --- a/tests/ui/issues/issue-47715.rs +++ /dev/null @@ -1,28 +0,0 @@ -trait Foo {} - -trait Bar {} - -trait Iterable { - type Item; -} - -struct Container> { - //~^ ERROR `impl Trait` is not allowed in generics - field: T -} - -enum Enum> { - //~^ ERROR `impl Trait` is not allowed in generics - A(T), -} - -union Union + Copy> { - //~^ ERROR `impl Trait` is not allowed in generics - x: T, -} - -type Type> = T; -//~^ ERROR `impl Trait` is not allowed in generics - -fn main() { -} diff --git a/tests/ui/issues/issue-47715.stderr b/tests/ui/issues/issue-47715.stderr deleted file mode 100644 index 8ed9ff439521..000000000000 --- a/tests/ui/issues/issue-47715.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0562]: `impl Trait` is not allowed in generics - --> $DIR/issue-47715.rs:9:37 - | -LL | struct Container> { - | ^^^^^^^^ - | - = note: `impl Trait` is only allowed in arguments and return types of functions and methods - -error[E0562]: `impl Trait` is not allowed in generics - --> $DIR/issue-47715.rs:14:30 - | -LL | enum Enum> { - | ^^^^^^^^ - | - = note: `impl Trait` is only allowed in arguments and return types of functions and methods - -error[E0562]: `impl Trait` is not allowed in generics - --> $DIR/issue-47715.rs:19:32 - | -LL | union Union + Copy> { - | ^^^^^^^^ - | - = note: `impl Trait` is only allowed in arguments and return types of functions and methods - -error[E0562]: `impl Trait` is not allowed in generics - --> $DIR/issue-47715.rs:24:30 - | -LL | type Type> = T; - | ^^^^^^^^ - | - = note: `impl Trait` is only allowed in arguments and return types of functions and methods - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/issues/issue-4968.rs b/tests/ui/issues/issue-4968.rs deleted file mode 100644 index 08539d6debd8..000000000000 --- a/tests/ui/issues/issue-4968.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Regression test for issue #4968 - -//@ dont-require-annotations: NOTE - -const A: (isize,isize) = (4,2); -fn main() { - match 42 { A => () } - //~^ ERROR mismatched types - //~| NOTE expected type `{integer}` - //~| NOTE found tuple `(isize, isize)` - //~| NOTE expected integer, found `(isize, isize)` -} diff --git a/tests/ui/issues/issue-4968.stderr b/tests/ui/issues/issue-4968.stderr deleted file mode 100644 index 2c1e1d7bfe5a..000000000000 --- a/tests/ui/issues/issue-4968.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-4968.rs:7:16 - | -LL | const A: (isize,isize) = (4,2); - | ---------------------- constant defined here -LL | fn main() { -LL | match 42 { A => () } - | -- ^ - | | | - | | expected integer, found `(isize, isize)` - | | `A` is interpreted as a constant, not a new binding - | | help: introduce a new binding instead: `other_a` - | this expression has type `{integer}` - | - = note: expected type `{integer}` - found tuple `(isize, isize)` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-49824.rs b/tests/ui/issues/issue-49824.rs deleted file mode 100644 index bc1cd6856bc9..000000000000 --- a/tests/ui/issues/issue-49824.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let mut x = 0; - || { - || { - //~^ ERROR captured variable cannot escape `FnMut` closure body - let _y = &mut x; - } - }; -} diff --git a/tests/ui/issues/issue-49824.stderr b/tests/ui/issues/issue-49824.stderr deleted file mode 100644 index 1c77090de27b..000000000000 --- a/tests/ui/issues/issue-49824.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error: captured variable cannot escape `FnMut` closure body - --> $DIR/issue-49824.rs:4:9 - | -LL | let mut x = 0; - | ----- variable defined here -LL | || { - | - inferred to be a `FnMut` closure -LL | / || { -LL | | -LL | | let _y = &mut x; - | | - variable captured here -LL | | } - | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body - | - = note: `FnMut` closures only have access to their captured variables while they are executing... - = note: ...therefore, they cannot allow references to captured variables to escape -help: consider adding 'move' keyword before the nested closure - | -LL | move || { - | ++++ - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-49854.rs b/tests/ui/issues/issue-49854.rs deleted file mode 100644 index b5a3f07dd4b8..000000000000 --- a/tests/ui/issues/issue-49854.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass -use std::ffi::OsString; - -fn main() { - let os_str = OsString::from("Hello Rust!"); - - assert_eq!(os_str, "Hello Rust!"); - assert_eq!("Hello Rust!", os_str); -} diff --git a/tests/ui/issues/issue-49934-errors.rs b/tests/ui/issues/issue-49934-errors.rs deleted file mode 100644 index dd14bac5e3a9..000000000000 --- a/tests/ui/issues/issue-49934-errors.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn foo<#[derive(Debug)] T>() { //~ ERROR expected non-macro attribute, found attribute macro - match 0 { - #[derive(Debug)] //~ ERROR expected non-macro attribute, found attribute macro - _ => (), - } -} - -fn main() {} diff --git a/tests/ui/issues/issue-49934-errors.stderr b/tests/ui/issues/issue-49934-errors.stderr deleted file mode 100644 index 8c4c54170a10..000000000000 --- a/tests/ui/issues/issue-49934-errors.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: expected non-macro attribute, found attribute macro `derive` - --> $DIR/issue-49934-errors.rs:1:10 - | -LL | fn foo<#[derive(Debug)] T>() { - | ^^^^^^ not a non-macro attribute - -error: expected non-macro attribute, found attribute macro `derive` - --> $DIR/issue-49934-errors.rs:3:11 - | -LL | #[derive(Debug)] - | ^^^^^^ not a non-macro attribute - -error: aborting due to 2 previous errors - diff --git a/tests/ui/issues/issue-49934.rs b/tests/ui/issues/issue-49934.rs deleted file mode 100644 index 119d84a06885..000000000000 --- a/tests/ui/issues/issue-49934.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![feature(stmt_expr_attributes)] - -fn main() { - // fold_stmt (Item) - #[allow(dead_code)] - #[derive(Debug)] // should not warn - struct Foo; - - // fold_stmt (Mac) - #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s - println!("Hello, world!"); - - // fold_stmt (Semi) - #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s - "Hello, world!"; - - // fold_stmt (Local) - #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s - let _ = "Hello, world!"; - - // visit_expr - let _ = #[derive(Debug)] "Hello, world!"; - //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s - - let _ = [ - // filter_map_expr - #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s - "Hello, world!", - ]; -} diff --git a/tests/ui/issues/issue-49934.stderr b/tests/ui/issues/issue-49934.stderr deleted file mode 100644 index f2ff541bb992..000000000000 --- a/tests/ui/issues/issue-49934.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s - --> $DIR/issue-49934.rs:10:5 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ not applicable here -LL | println!("Hello, world!"); - | -------------------------- not a `struct`, `enum` or `union` - -error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s - --> $DIR/issue-49934.rs:14:5 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ not applicable here -LL | "Hello, world!"; - | ---------------- not a `struct`, `enum` or `union` - -error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s - --> $DIR/issue-49934.rs:18:5 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ not applicable here -LL | let _ = "Hello, world!"; - | ------------------------ not a `struct`, `enum` or `union` - -error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s - --> $DIR/issue-49934.rs:22:13 - | -LL | let _ = #[derive(Debug)] "Hello, world!"; - | ^^^^^^^^^^^^^^^^ --------------- not a `struct`, `enum` or `union` - | | - | not applicable here - -error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s - --> $DIR/issue-49934.rs:27:9 - | -LL | #[derive(Debug)] - | ^^^^^^^^^^^^^^^^ not applicable here -LL | "Hello, world!", - | --------------- not a `struct`, `enum` or `union` - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0774`. diff --git a/tests/ui/issues/issue-50442.rs b/tests/ui/issues/issue-50442.rs deleted file mode 100644 index 70c764f33ddf..000000000000 --- a/tests/ui/issues/issue-50442.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -enum Void {} - -enum Foo { - A(i32), - B(Void), - C(i32) -} - -fn main() { - let _foo = Foo::A(0); -} diff --git a/tests/ui/issues/issue-50471.rs b/tests/ui/issues/issue-50471.rs deleted file mode 100644 index 1d8bad20377c..000000000000 --- a/tests/ui/issues/issue-50471.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ check-pass - -fn main() { - assert!({false}); - - assert!(r"\u{41}" == "A"); - - assert!(r"\u{".is_empty()); -} diff --git a/tests/ui/issues/issue-50581.rs b/tests/ui/issues/issue-50581.rs deleted file mode 100644 index 12bb9930eca4..000000000000 --- a/tests/ui/issues/issue-50581.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - |_: [u8; break]| (); //~ ERROR [E0268] -} diff --git a/tests/ui/issues/issue-50581.stderr b/tests/ui/issues/issue-50581.stderr deleted file mode 100644 index bac1ade3b0c8..000000000000 --- a/tests/ui/issues/issue-50581.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0268]: `break` outside of a loop or labeled block - --> $DIR/issue-50581.rs:2:14 - | -LL | |_: [u8; break]| (); - | ^^^^^ cannot `break` outside of a loop or labeled block - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/issues/issue-50582.rs b/tests/ui/issues/issue-50582.rs deleted file mode 100644 index 1358e0bde4c8..000000000000 --- a/tests/ui/issues/issue-50582.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - Vec::<[(); 1 + for x in 0..1 {}]>::new(); - //~^ ERROR cannot add -} diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr deleted file mode 100644 index 168f5894fb03..000000000000 --- a/tests/ui/issues/issue-50582.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0277]: cannot add `()` to `{integer}` - --> $DIR/issue-50582.rs:2:18 - | -LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); - | ^ no implementation for `{integer} + ()` - | - = help: the trait `Add<()>` is not implemented for `{integer}` - = help: the following other types implement trait `Add`: - `&f128` implements `Add` - `&f128` implements `Add` - `&f16` implements `Add` - `&f16` implements `Add` - `&f32` implements `Add` - `&f32` implements `Add` - `&f64` implements `Add` - `&f64` implements `Add` - and 56 others - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-50600.rs b/tests/ui/issues/issue-50600.rs deleted file mode 100644 index 963e607afcfd..000000000000 --- a/tests/ui/issues/issue-50600.rs +++ /dev/null @@ -1,5 +0,0 @@ -struct Foo ( - fn([u8; |x: u8| {}]), //~ ERROR mismatched types -); - -fn main() {} diff --git a/tests/ui/issues/issue-50600.stderr b/tests/ui/issues/issue-50600.stderr deleted file mode 100644 index e3ae7f144c35..000000000000 --- a/tests/ui/issues/issue-50600.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-50600.rs:2:13 - | -LL | fn([u8; |x: u8| {}]), - | ^^^^^^^^^^ expected `usize`, found closure - | - = note: expected type `usize` - found closure `{closure@$DIR/issue-50600.rs:2:13: 2:20}` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-50802.rs b/tests/ui/issues/issue-50802.rs deleted file mode 100644 index dece55968b6a..000000000000 --- a/tests/ui/issues/issue-50802.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[allow(unreachable_code)] - -fn main() { - loop { - break while continue { //~ ERROR E0590 - } - } -} diff --git a/tests/ui/issues/issue-50802.stderr b/tests/ui/issues/issue-50802.stderr deleted file mode 100644 index e1b5ae325120..000000000000 --- a/tests/ui/issues/issue-50802.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop - --> $DIR/issue-50802.rs:5:21 - | -LL | break while continue { - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0590`. diff --git a/tests/ui/issues/issue-51044.rs b/tests/ui/issues/issue-51044.rs deleted file mode 100644 index d7761b50b4c4..000000000000 --- a/tests/ui/issues/issue-51044.rs +++ /dev/null @@ -1,30 +0,0 @@ -//@ run-pass -// regression test for issue #50825 -// Check that the feature gate normalizes associated types. - -#![allow(dead_code)] -struct Foo(T); -struct Duck; -struct Quack; - -trait Hello where A: Animal { -} - -trait Animal { - type Noise; -} - -trait Loud { -} - -impl Loud for f32 { -} - -impl Animal for Duck { - type Noise = Quack; -} - -impl Hello for Foo where f32: Loud<::Noise> { -} - -fn main() {} diff --git a/tests/ui/issues/issue-51714.rs b/tests/ui/issues/issue-51714.rs deleted file mode 100644 index 03b50b7963ea..000000000000 --- a/tests/ui/issues/issue-51714.rs +++ /dev/null @@ -1,21 +0,0 @@ -fn main() { - //~^ NOTE: not the enclosing function body - //~| NOTE: not the enclosing function body - //~| NOTE: not the enclosing function body - //~| NOTE: not the enclosing function body - |_: [_; return || {}]| {}; - //~^ ERROR: return statement outside of function body [E0572] - //~| NOTE: the return is part of this body... - - [(); return || {}]; - //~^ ERROR: return statement outside of function body [E0572] - //~| NOTE: the return is part of this body... - - [(); return |ice| {}]; - //~^ ERROR: return statement outside of function body [E0572] - //~| NOTE: the return is part of this body... - - [(); return while let Some(n) = Some(0) {}]; - //~^ ERROR: return statement outside of function body [E0572] - //~| NOTE: the return is part of this body... -} diff --git a/tests/ui/issues/issue-51714.stderr b/tests/ui/issues/issue-51714.stderr deleted file mode 100644 index da3e3caea29a..000000000000 --- a/tests/ui/issues/issue-51714.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:6:13 - | -LL | / fn main() { -... | -LL | | |_: [_; return || {}]| {}; - | | ^^^^^^^^^^^^ the return is part of this body... -... | -LL | | } - | |_- ...not the enclosing function body - -error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:10:10 - | -LL | / fn main() { -... | -LL | | [(); return || {}]; - | | ^^^^^^^^^^^^ the return is part of this body... -... | -LL | | } - | |_- ...not the enclosing function body - -error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:14:10 - | -LL | / fn main() { -... | -LL | | [(); return |ice| {}]; - | | ^^^^^^^^^^^^^^^ the return is part of this body... -... | -LL | | } - | |_- ...not the enclosing function body - -error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:18:10 - | -LL | / fn main() { -... | -LL | | [(); return while let Some(n) = Some(0) {}]; - | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the return is part of this body... -... | -LL | | } - | |_- ...not the enclosing function body - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0572`. diff --git a/tests/ui/issues/issue-72933-match-stack-overflow.rs b/tests/ui/issues/issue-72933-match-stack-overflow.rs deleted file mode 100644 index 6d091a910819..000000000000 --- a/tests/ui/issues/issue-72933-match-stack-overflow.rs +++ /dev/null @@ -1,5208 +0,0 @@ -//@ build-pass -// ignore-tidy-filelength -#![crate_type="rlib"] - -fn banana(v: &str) -> u32 { - match v { - "0" => 0, - "1" => 1, - "2" => 2, - "3" => 3, - "4" => 4, - "5" => 5, - "6" => 6, - "7" => 7, - "8" => 8, - "9" => 9, - "10" => 10, - "11" => 11, - "12" => 12, - "13" => 13, - "14" => 14, - "15" => 15, - "16" => 16, - "17" => 17, - "18" => 18, - "19" => 19, - "20" => 20, - "21" => 21, - "22" => 22, - "23" => 23, - "24" => 24, - "25" => 25, - "26" => 26, - "27" => 27, - "28" => 28, - "29" => 29, - "30" => 30, - "31" => 31, - "32" => 32, - "33" => 33, - "34" => 34, - "35" => 35, - "36" => 36, - "37" => 37, - "38" => 38, - "39" => 39, - "40" => 40, - "41" => 41, - "42" => 42, - "43" => 43, - "44" => 44, - "45" => 45, - "46" => 46, - "47" => 47, - "48" => 48, - "49" => 49, - "50" => 50, - "51" => 51, - "52" => 52, - "53" => 53, - "54" => 54, - "55" => 55, - "56" => 56, - "57" => 57, - "58" => 58, - "59" => 59, - "60" => 60, - "61" => 61, - "62" => 62, - "63" => 63, - "64" => 64, - "65" => 65, - "66" => 66, - "67" => 67, - "68" => 68, - "69" => 69, - "70" => 70, - "71" => 71, - "72" => 72, - "73" => 73, - "74" => 74, - "75" => 75, - "76" => 76, - "77" => 77, - "78" => 78, - "79" => 79, - "80" => 80, - "81" => 81, - "82" => 82, - "83" => 83, - "84" => 84, - "85" => 85, - "86" => 86, - "87" => 87, - "88" => 88, - "89" => 89, - "90" => 90, - "91" => 91, - "92" => 92, - "93" => 93, - "94" => 94, - "95" => 95, - "96" => 96, - "97" => 97, - "98" => 98, - "99" => 99, - "100" => 100, - "101" => 101, - "102" => 102, - "103" => 103, - "104" => 104, - "105" => 105, - "106" => 106, - "107" => 107, - "108" => 108, - "109" => 109, - "110" => 110, - "111" => 111, - "112" => 112, - "113" => 113, - "114" => 114, - "115" => 115, - "116" => 116, - "117" => 117, - "118" => 118, - "119" => 119, - "120" => 120, - "121" => 121, - "122" => 122, - "123" => 123, - "124" => 124, - "125" => 125, - "126" => 126, - "127" => 127, - "128" => 128, - "129" => 129, - "130" => 130, - "131" => 131, - "132" => 132, - "133" => 133, - "134" => 134, - "135" => 135, - "136" => 136, - "137" => 137, - "138" => 138, - "139" => 139, - "140" => 140, - "141" => 141, - "142" => 142, - "143" => 143, - "144" => 144, - "145" => 145, - "146" => 146, - "147" => 147, - "148" => 148, - "149" => 149, - "150" => 150, - "151" => 151, - "152" => 152, - "153" => 153, - "154" => 154, - "155" => 155, - "156" => 156, - "157" => 157, - "158" => 158, - "159" => 159, - "160" => 160, - "161" => 161, - "162" => 162, - "163" => 163, - "164" => 164, - "165" => 165, - "166" => 166, - "167" => 167, - "168" => 168, - "169" => 169, - "170" => 170, - "171" => 171, - "172" => 172, - "173" => 173, - "174" => 174, - "175" => 175, - "176" => 176, - "177" => 177, - "178" => 178, - "179" => 179, - "180" => 180, - "181" => 181, - "182" => 182, - "183" => 183, - "184" => 184, - "185" => 185, - "186" => 186, - "187" => 187, - "188" => 188, - "189" => 189, - "190" => 190, - "191" => 191, - "192" => 192, - "193" => 193, - "194" => 194, - "195" => 195, - "196" => 196, - "197" => 197, - "198" => 198, - "199" => 199, - "200" => 200, - "201" => 201, - "202" => 202, - "203" => 203, - "204" => 204, - "205" => 205, - "206" => 206, - "207" => 207, - "208" => 208, - "209" => 209, - "210" => 210, - "211" => 211, - "212" => 212, - "213" => 213, - "214" => 214, - "215" => 215, - "216" => 216, - "217" => 217, - "218" => 218, - "219" => 219, - "220" => 220, - "221" => 221, - "222" => 222, - "223" => 223, - "224" => 224, - "225" => 225, - "226" => 226, - "227" => 227, - "228" => 228, - "229" => 229, - "230" => 230, - "231" => 231, - "232" => 232, - "233" => 233, - "234" => 234, - "235" => 235, - "236" => 236, - "237" => 237, - "238" => 238, - "239" => 239, - "240" => 240, - "241" => 241, - "242" => 242, - "243" => 243, - "244" => 244, - "245" => 245, - "246" => 246, - "247" => 247, - "248" => 248, - "249" => 249, - "250" => 250, - "251" => 251, - "252" => 252, - "253" => 253, - "254" => 254, - "255" => 255, - "256" => 256, - "257" => 257, - "258" => 258, - "259" => 259, - "260" => 260, - "261" => 261, - "262" => 262, - "263" => 263, - "264" => 264, - "265" => 265, - "266" => 266, - "267" => 267, - "268" => 268, - "269" => 269, - "270" => 270, - "271" => 271, - "272" => 272, - "273" => 273, - "274" => 274, - "275" => 275, - "276" => 276, - "277" => 277, - "278" => 278, - "279" => 279, - "280" => 280, - "281" => 281, - "282" => 282, - "283" => 283, - "284" => 284, - "285" => 285, - "286" => 286, - "287" => 287, - "288" => 288, - "289" => 289, - "290" => 290, - "291" => 291, - "292" => 292, - "293" => 293, - "294" => 294, - "295" => 295, - "296" => 296, - "297" => 297, - "298" => 298, - "299" => 299, - "300" => 300, - "301" => 301, - "302" => 302, - "303" => 303, - "304" => 304, - "305" => 305, - "306" => 306, - "307" => 307, - "308" => 308, - "309" => 309, - "310" => 310, - "311" => 311, - "312" => 312, - "313" => 313, - "314" => 314, - "315" => 315, - "316" => 316, - "317" => 317, - "318" => 318, - "319" => 319, - "320" => 320, - "321" => 321, - "322" => 322, - "323" => 323, - "324" => 324, - "325" => 325, - "326" => 326, - "327" => 327, - "328" => 328, - "329" => 329, - "330" => 330, - "331" => 331, - "332" => 332, - "333" => 333, - "334" => 334, - "335" => 335, - "336" => 336, - "337" => 337, - "338" => 338, - "339" => 339, - "340" => 340, - "341" => 341, - "342" => 342, - "343" => 343, - "344" => 344, - "345" => 345, - "346" => 346, - "347" => 347, - "348" => 348, - "349" => 349, - "350" => 350, - "351" => 351, - "352" => 352, - "353" => 353, - "354" => 354, - "355" => 355, - "356" => 356, - "357" => 357, - "358" => 358, - "359" => 359, - "360" => 360, - "361" => 361, - "362" => 362, - "363" => 363, - "364" => 364, - "365" => 365, - "366" => 366, - "367" => 367, - "368" => 368, - "369" => 369, - "370" => 370, - "371" => 371, - "372" => 372, - "373" => 373, - "374" => 374, - "375" => 375, - "376" => 376, - "377" => 377, - "378" => 378, - "379" => 379, - "380" => 380, - "381" => 381, - "382" => 382, - "383" => 383, - "384" => 384, - "385" => 385, - "386" => 386, - "387" => 387, - "388" => 388, - "389" => 389, - "390" => 390, - "391" => 391, - "392" => 392, - "393" => 393, - "394" => 394, - "395" => 395, - "396" => 396, - "397" => 397, - "398" => 398, - "399" => 399, - "400" => 400, - "401" => 401, - "402" => 402, - "403" => 403, - "404" => 404, - "405" => 405, - "406" => 406, - "407" => 407, - "408" => 408, - "409" => 409, - "410" => 410, - "411" => 411, - "412" => 412, - "413" => 413, - "414" => 414, - "415" => 415, - "416" => 416, - "417" => 417, - "418" => 418, - "419" => 419, - "420" => 420, - "421" => 421, - "422" => 422, - "423" => 423, - "424" => 424, - "425" => 425, - "426" => 426, - "427" => 427, - "428" => 428, - "429" => 429, - "430" => 430, - "431" => 431, - "432" => 432, - "433" => 433, - "434" => 434, - "435" => 435, - "436" => 436, - "437" => 437, - "438" => 438, - "439" => 439, - "440" => 440, - "441" => 441, - "442" => 442, - "443" => 443, - "444" => 444, - "445" => 445, - "446" => 446, - "447" => 447, - "448" => 448, - "449" => 449, - "450" => 450, - "451" => 451, - "452" => 452, - "453" => 453, - "454" => 454, - "455" => 455, - "456" => 456, - "457" => 457, - "458" => 458, - "459" => 459, - "460" => 460, - "461" => 461, - "462" => 462, - "463" => 463, - "464" => 464, - "465" => 465, - "466" => 466, - "467" => 467, - "468" => 468, - "469" => 469, - "470" => 470, - "471" => 471, - "472" => 472, - "473" => 473, - "474" => 474, - "475" => 475, - "476" => 476, - "477" => 477, - "478" => 478, - "479" => 479, - "480" => 480, - "481" => 481, - "482" => 482, - "483" => 483, - "484" => 484, - "485" => 485, - "486" => 486, - "487" => 487, - "488" => 488, - "489" => 489, - "490" => 490, - "491" => 491, - "492" => 492, - "493" => 493, - "494" => 494, - "495" => 495, - "496" => 496, - "497" => 497, - "498" => 498, - "499" => 499, - "500" => 500, - "501" => 501, - "502" => 502, - "503" => 503, - "504" => 504, - "505" => 505, - "506" => 506, - "507" => 507, - "508" => 508, - "509" => 509, - "510" => 510, - "511" => 511, - "512" => 512, - "513" => 513, - "514" => 514, - "515" => 515, - "516" => 516, - "517" => 517, - "518" => 518, - "519" => 519, - "520" => 520, - "521" => 521, - "522" => 522, - "523" => 523, - "524" => 524, - "525" => 525, - "526" => 526, - "527" => 527, - "528" => 528, - "529" => 529, - "530" => 530, - "531" => 531, - "532" => 532, - "533" => 533, - "534" => 534, - "535" => 535, - "536" => 536, - "537" => 537, - "538" => 538, - "539" => 539, - "540" => 540, - "541" => 541, - "542" => 542, - "543" => 543, - "544" => 544, - "545" => 545, - "546" => 546, - "547" => 547, - "548" => 548, - "549" => 549, - "550" => 550, - "551" => 551, - "552" => 552, - "553" => 553, - "554" => 554, - "555" => 555, - "556" => 556, - "557" => 557, - "558" => 558, - "559" => 559, - "560" => 560, - "561" => 561, - "562" => 562, - "563" => 563, - "564" => 564, - "565" => 565, - "566" => 566, - "567" => 567, - "568" => 568, - "569" => 569, - "570" => 570, - "571" => 571, - "572" => 572, - "573" => 573, - "574" => 574, - "575" => 575, - "576" => 576, - "577" => 577, - "578" => 578, - "579" => 579, - "580" => 580, - "581" => 581, - "582" => 582, - "583" => 583, - "584" => 584, - "585" => 585, - "586" => 586, - "587" => 587, - "588" => 588, - "589" => 589, - "590" => 590, - "591" => 591, - "592" => 592, - "593" => 593, - "594" => 594, - "595" => 595, - "596" => 596, - "597" => 597, - "598" => 598, - "599" => 599, - "600" => 600, - "601" => 601, - "602" => 602, - "603" => 603, - "604" => 604, - "605" => 605, - "606" => 606, - "607" => 607, - "608" => 608, - "609" => 609, - "610" => 610, - "611" => 611, - "612" => 612, - "613" => 613, - "614" => 614, - "615" => 615, - "616" => 616, - "617" => 617, - "618" => 618, - "619" => 619, - "620" => 620, - "621" => 621, - "622" => 622, - "623" => 623, - "624" => 624, - "625" => 625, - "626" => 626, - "627" => 627, - "628" => 628, - "629" => 629, - "630" => 630, - "631" => 631, - "632" => 632, - "633" => 633, - "634" => 634, - "635" => 635, - "636" => 636, - "637" => 637, - "638" => 638, - "639" => 639, - "640" => 640, - "641" => 641, - "642" => 642, - "643" => 643, - "644" => 644, - "645" => 645, - "646" => 646, - "647" => 647, - "648" => 648, - "649" => 649, - "650" => 650, - "651" => 651, - "652" => 652, - "653" => 653, - "654" => 654, - "655" => 655, - "656" => 656, - "657" => 657, - "658" => 658, - "659" => 659, - "660" => 660, - "661" => 661, - "662" => 662, - "663" => 663, - "664" => 664, - "665" => 665, - "666" => 666, - "667" => 667, - "668" => 668, - "669" => 669, - "670" => 670, - "671" => 671, - "672" => 672, - "673" => 673, - "674" => 674, - "675" => 675, - "676" => 676, - "677" => 677, - "678" => 678, - "679" => 679, - "680" => 680, - "681" => 681, - "682" => 682, - "683" => 683, - "684" => 684, - "685" => 685, - "686" => 686, - "687" => 687, - "688" => 688, - "689" => 689, - "690" => 690, - "691" => 691, - "692" => 692, - "693" => 693, - "694" => 694, - "695" => 695, - "696" => 696, - "697" => 697, - "698" => 698, - "699" => 699, - "700" => 700, - "701" => 701, - "702" => 702, - "703" => 703, - "704" => 704, - "705" => 705, - "706" => 706, - "707" => 707, - "708" => 708, - "709" => 709, - "710" => 710, - "711" => 711, - "712" => 712, - "713" => 713, - "714" => 714, - "715" => 715, - "716" => 716, - "717" => 717, - "718" => 718, - "719" => 719, - "720" => 720, - "721" => 721, - "722" => 722, - "723" => 723, - "724" => 724, - "725" => 725, - "726" => 726, - "727" => 727, - "728" => 728, - "729" => 729, - "730" => 730, - "731" => 731, - "732" => 732, - "733" => 733, - "734" => 734, - "735" => 735, - "736" => 736, - "737" => 737, - "738" => 738, - "739" => 739, - "740" => 740, - "741" => 741, - "742" => 742, - "743" => 743, - "744" => 744, - "745" => 745, - "746" => 746, - "747" => 747, - "748" => 748, - "749" => 749, - "750" => 750, - "751" => 751, - "752" => 752, - "753" => 753, - "754" => 754, - "755" => 755, - "756" => 756, - "757" => 757, - "758" => 758, - "759" => 759, - "760" => 760, - "761" => 761, - "762" => 762, - "763" => 763, - "764" => 764, - "765" => 765, - "766" => 766, - "767" => 767, - "768" => 768, - "769" => 769, - "770" => 770, - "771" => 771, - "772" => 772, - "773" => 773, - "774" => 774, - "775" => 775, - "776" => 776, - "777" => 777, - "778" => 778, - "779" => 779, - "780" => 780, - "781" => 781, - "782" => 782, - "783" => 783, - "784" => 784, - "785" => 785, - "786" => 786, - "787" => 787, - "788" => 788, - "789" => 789, - "790" => 790, - "791" => 791, - "792" => 792, - "793" => 793, - "794" => 794, - "795" => 795, - "796" => 796, - "797" => 797, - "798" => 798, - "799" => 799, - "800" => 800, - "801" => 801, - "802" => 802, - "803" => 803, - "804" => 804, - "805" => 805, - "806" => 806, - "807" => 807, - "808" => 808, - "809" => 809, - "810" => 810, - "811" => 811, - "812" => 812, - "813" => 813, - "814" => 814, - "815" => 815, - "816" => 816, - "817" => 817, - "818" => 818, - "819" => 819, - "820" => 820, - "821" => 821, - "822" => 822, - "823" => 823, - "824" => 824, - "825" => 825, - "826" => 826, - "827" => 827, - "828" => 828, - "829" => 829, - "830" => 830, - "831" => 831, - "832" => 832, - "833" => 833, - "834" => 834, - "835" => 835, - "836" => 836, - "837" => 837, - "838" => 838, - "839" => 839, - "840" => 840, - "841" => 841, - "842" => 842, - "843" => 843, - "844" => 844, - "845" => 845, - "846" => 846, - "847" => 847, - "848" => 848, - "849" => 849, - "850" => 850, - "851" => 851, - "852" => 852, - "853" => 853, - "854" => 854, - "855" => 855, - "856" => 856, - "857" => 857, - "858" => 858, - "859" => 859, - "860" => 860, - "861" => 861, - "862" => 862, - "863" => 863, - "864" => 864, - "865" => 865, - "866" => 866, - "867" => 867, - "868" => 868, - "869" => 869, - "870" => 870, - "871" => 871, - "872" => 872, - "873" => 873, - "874" => 874, - "875" => 875, - "876" => 876, - "877" => 877, - "878" => 878, - "879" => 879, - "880" => 880, - "881" => 881, - "882" => 882, - "883" => 883, - "884" => 884, - "885" => 885, - "886" => 886, - "887" => 887, - "888" => 888, - "889" => 889, - "890" => 890, - "891" => 891, - "892" => 892, - "893" => 893, - "894" => 894, - "895" => 895, - "896" => 896, - "897" => 897, - "898" => 898, - "899" => 899, - "900" => 900, - "901" => 901, - "902" => 902, - "903" => 903, - "904" => 904, - "905" => 905, - "906" => 906, - "907" => 907, - "908" => 908, - "909" => 909, - "910" => 910, - "911" => 911, - "912" => 912, - "913" => 913, - "914" => 914, - "915" => 915, - "916" => 916, - "917" => 917, - "918" => 918, - "919" => 919, - "920" => 920, - "921" => 921, - "922" => 922, - "923" => 923, - "924" => 924, - "925" => 925, - "926" => 926, - "927" => 927, - "928" => 928, - "929" => 929, - "930" => 930, - "931" => 931, - "932" => 932, - "933" => 933, - "934" => 934, - "935" => 935, - "936" => 936, - "937" => 937, - "938" => 938, - "939" => 939, - "940" => 940, - "941" => 941, - "942" => 942, - "943" => 943, - "944" => 944, - "945" => 945, - "946" => 946, - "947" => 947, - "948" => 948, - "949" => 949, - "950" => 950, - "951" => 951, - "952" => 952, - "953" => 953, - "954" => 954, - "955" => 955, - "956" => 956, - "957" => 957, - "958" => 958, - "959" => 959, - "960" => 960, - "961" => 961, - "962" => 962, - "963" => 963, - "964" => 964, - "965" => 965, - "966" => 966, - "967" => 967, - "968" => 968, - "969" => 969, - "970" => 970, - "971" => 971, - "972" => 972, - "973" => 973, - "974" => 974, - "975" => 975, - "976" => 976, - "977" => 977, - "978" => 978, - "979" => 979, - "980" => 980, - "981" => 981, - "982" => 982, - "983" => 983, - "984" => 984, - "985" => 985, - "986" => 986, - "987" => 987, - "988" => 988, - "989" => 989, - "990" => 990, - "991" => 991, - "992" => 992, - "993" => 993, - "994" => 994, - "995" => 995, - "996" => 996, - "997" => 997, - "998" => 998, - "999" => 999, - "1000" => 1000, - "1001" => 1001, - "1002" => 1002, - "1003" => 1003, - "1004" => 1004, - "1005" => 1005, - "1006" => 1006, - "1007" => 1007, - "1008" => 1008, - "1009" => 1009, - "1010" => 1010, - "1011" => 1011, - "1012" => 1012, - "1013" => 1013, - "1014" => 1014, - "1015" => 1015, - "1016" => 1016, - "1017" => 1017, - "1018" => 1018, - "1019" => 1019, - "1020" => 1020, - "1021" => 1021, - "1022" => 1022, - "1023" => 1023, - "1024" => 1024, - "1025" => 1025, - "1026" => 1026, - "1027" => 1027, - "1028" => 1028, - "1029" => 1029, - "1030" => 1030, - "1031" => 1031, - "1032" => 1032, - "1033" => 1033, - "1034" => 1034, - "1035" => 1035, - "1036" => 1036, - "1037" => 1037, - "1038" => 1038, - "1039" => 1039, - "1040" => 1040, - "1041" => 1041, - "1042" => 1042, - "1043" => 1043, - "1044" => 1044, - "1045" => 1045, - "1046" => 1046, - "1047" => 1047, - "1048" => 1048, - "1049" => 1049, - "1050" => 1050, - "1051" => 1051, - "1052" => 1052, - "1053" => 1053, - "1054" => 1054, - "1055" => 1055, - "1056" => 1056, - "1057" => 1057, - "1058" => 1058, - "1059" => 1059, - "1060" => 1060, - "1061" => 1061, - "1062" => 1062, - "1063" => 1063, - "1064" => 1064, - "1065" => 1065, - "1066" => 1066, - "1067" => 1067, - "1068" => 1068, - "1069" => 1069, - "1070" => 1070, - "1071" => 1071, - "1072" => 1072, - "1073" => 1073, - "1074" => 1074, - "1075" => 1075, - "1076" => 1076, - "1077" => 1077, - "1078" => 1078, - "1079" => 1079, - "1080" => 1080, - "1081" => 1081, - "1082" => 1082, - "1083" => 1083, - "1084" => 1084, - "1085" => 1085, - "1086" => 1086, - "1087" => 1087, - "1088" => 1088, - "1089" => 1089, - "1090" => 1090, - "1091" => 1091, - "1092" => 1092, - "1093" => 1093, - "1094" => 1094, - "1095" => 1095, - "1096" => 1096, - "1097" => 1097, - "1098" => 1098, - "1099" => 1099, - "1100" => 1100, - "1101" => 1101, - "1102" => 1102, - "1103" => 1103, - "1104" => 1104, - "1105" => 1105, - "1106" => 1106, - "1107" => 1107, - "1108" => 1108, - "1109" => 1109, - "1110" => 1110, - "1111" => 1111, - "1112" => 1112, - "1113" => 1113, - "1114" => 1114, - "1115" => 1115, - "1116" => 1116, - "1117" => 1117, - "1118" => 1118, - "1119" => 1119, - "1120" => 1120, - "1121" => 1121, - "1122" => 1122, - "1123" => 1123, - "1124" => 1124, - "1125" => 1125, - "1126" => 1126, - "1127" => 1127, - "1128" => 1128, - "1129" => 1129, - "1130" => 1130, - "1131" => 1131, - "1132" => 1132, - "1133" => 1133, - "1134" => 1134, - "1135" => 1135, - "1136" => 1136, - "1137" => 1137, - "1138" => 1138, - "1139" => 1139, - "1140" => 1140, - "1141" => 1141, - "1142" => 1142, - "1143" => 1143, - "1144" => 1144, - "1145" => 1145, - "1146" => 1146, - "1147" => 1147, - "1148" => 1148, - "1149" => 1149, - "1150" => 1150, - "1151" => 1151, - "1152" => 1152, - "1153" => 1153, - "1154" => 1154, - "1155" => 1155, - "1156" => 1156, - "1157" => 1157, - "1158" => 1158, - "1159" => 1159, - "1160" => 1160, - "1161" => 1161, - "1162" => 1162, - "1163" => 1163, - "1164" => 1164, - "1165" => 1165, - "1166" => 1166, - "1167" => 1167, - "1168" => 1168, - "1169" => 1169, - "1170" => 1170, - "1171" => 1171, - "1172" => 1172, - "1173" => 1173, - "1174" => 1174, - "1175" => 1175, - "1176" => 1176, - "1177" => 1177, - "1178" => 1178, - "1179" => 1179, - "1180" => 1180, - "1181" => 1181, - "1182" => 1182, - "1183" => 1183, - "1184" => 1184, - "1185" => 1185, - "1186" => 1186, - "1187" => 1187, - "1188" => 1188, - "1189" => 1189, - "1190" => 1190, - "1191" => 1191, - "1192" => 1192, - "1193" => 1193, - "1194" => 1194, - "1195" => 1195, - "1196" => 1196, - "1197" => 1197, - "1198" => 1198, - "1199" => 1199, - "1200" => 1200, - "1201" => 1201, - "1202" => 1202, - "1203" => 1203, - "1204" => 1204, - "1205" => 1205, - "1206" => 1206, - "1207" => 1207, - "1208" => 1208, - "1209" => 1209, - "1210" => 1210, - "1211" => 1211, - "1212" => 1212, - "1213" => 1213, - "1214" => 1214, - "1215" => 1215, - "1216" => 1216, - "1217" => 1217, - "1218" => 1218, - "1219" => 1219, - "1220" => 1220, - "1221" => 1221, - "1222" => 1222, - "1223" => 1223, - "1224" => 1224, - "1225" => 1225, - "1226" => 1226, - "1227" => 1227, - "1228" => 1228, - "1229" => 1229, - "1230" => 1230, - "1231" => 1231, - "1232" => 1232, - "1233" => 1233, - "1234" => 1234, - "1235" => 1235, - "1236" => 1236, - "1237" => 1237, - "1238" => 1238, - "1239" => 1239, - "1240" => 1240, - "1241" => 1241, - "1242" => 1242, - "1243" => 1243, - "1244" => 1244, - "1245" => 1245, - "1246" => 1246, - "1247" => 1247, - "1248" => 1248, - "1249" => 1249, - "1250" => 1250, - "1251" => 1251, - "1252" => 1252, - "1253" => 1253, - "1254" => 1254, - "1255" => 1255, - "1256" => 1256, - "1257" => 1257, - "1258" => 1258, - "1259" => 1259, - "1260" => 1260, - "1261" => 1261, - "1262" => 1262, - "1263" => 1263, - "1264" => 1264, - "1265" => 1265, - "1266" => 1266, - "1267" => 1267, - "1268" => 1268, - "1269" => 1269, - "1270" => 1270, - "1271" => 1271, - "1272" => 1272, - "1273" => 1273, - "1274" => 1274, - "1275" => 1275, - "1276" => 1276, - "1277" => 1277, - "1278" => 1278, - "1279" => 1279, - "1280" => 1280, - "1281" => 1281, - "1282" => 1282, - "1283" => 1283, - "1284" => 1284, - "1285" => 1285, - "1286" => 1286, - "1287" => 1287, - "1288" => 1288, - "1289" => 1289, - "1290" => 1290, - "1291" => 1291, - "1292" => 1292, - "1293" => 1293, - "1294" => 1294, - "1295" => 1295, - "1296" => 1296, - "1297" => 1297, - "1298" => 1298, - "1299" => 1299, - "1300" => 1300, - "1301" => 1301, - "1302" => 1302, - "1303" => 1303, - "1304" => 1304, - "1305" => 1305, - "1306" => 1306, - "1307" => 1307, - "1308" => 1308, - "1309" => 1309, - "1310" => 1310, - "1311" => 1311, - "1312" => 1312, - "1313" => 1313, - "1314" => 1314, - "1315" => 1315, - "1316" => 1316, - "1317" => 1317, - "1318" => 1318, - "1319" => 1319, - "1320" => 1320, - "1321" => 1321, - "1322" => 1322, - "1323" => 1323, - "1324" => 1324, - "1325" => 1325, - "1326" => 1326, - "1327" => 1327, - "1328" => 1328, - "1329" => 1329, - "1330" => 1330, - "1331" => 1331, - "1332" => 1332, - "1333" => 1333, - "1334" => 1334, - "1335" => 1335, - "1336" => 1336, - "1337" => 1337, - "1338" => 1338, - "1339" => 1339, - "1340" => 1340, - "1341" => 1341, - "1342" => 1342, - "1343" => 1343, - "1344" => 1344, - "1345" => 1345, - "1346" => 1346, - "1347" => 1347, - "1348" => 1348, - "1349" => 1349, - "1350" => 1350, - "1351" => 1351, - "1352" => 1352, - "1353" => 1353, - "1354" => 1354, - "1355" => 1355, - "1356" => 1356, - "1357" => 1357, - "1358" => 1358, - "1359" => 1359, - "1360" => 1360, - "1361" => 1361, - "1362" => 1362, - "1363" => 1363, - "1364" => 1364, - "1365" => 1365, - "1366" => 1366, - "1367" => 1367, - "1368" => 1368, - "1369" => 1369, - "1370" => 1370, - "1371" => 1371, - "1372" => 1372, - "1373" => 1373, - "1374" => 1374, - "1375" => 1375, - "1376" => 1376, - "1377" => 1377, - "1378" => 1378, - "1379" => 1379, - "1380" => 1380, - "1381" => 1381, - "1382" => 1382, - "1383" => 1383, - "1384" => 1384, - "1385" => 1385, - "1386" => 1386, - "1387" => 1387, - "1388" => 1388, - "1389" => 1389, - "1390" => 1390, - "1391" => 1391, - "1392" => 1392, - "1393" => 1393, - "1394" => 1394, - "1395" => 1395, - "1396" => 1396, - "1397" => 1397, - "1398" => 1398, - "1399" => 1399, - "1400" => 1400, - "1401" => 1401, - "1402" => 1402, - "1403" => 1403, - "1404" => 1404, - "1405" => 1405, - "1406" => 1406, - "1407" => 1407, - "1408" => 1408, - "1409" => 1409, - "1410" => 1410, - "1411" => 1411, - "1412" => 1412, - "1413" => 1413, - "1414" => 1414, - "1415" => 1415, - "1416" => 1416, - "1417" => 1417, - "1418" => 1418, - "1419" => 1419, - "1420" => 1420, - "1421" => 1421, - "1422" => 1422, - "1423" => 1423, - "1424" => 1424, - "1425" => 1425, - "1426" => 1426, - "1427" => 1427, - "1428" => 1428, - "1429" => 1429, - "1430" => 1430, - "1431" => 1431, - "1432" => 1432, - "1433" => 1433, - "1434" => 1434, - "1435" => 1435, - "1436" => 1436, - "1437" => 1437, - "1438" => 1438, - "1439" => 1439, - "1440" => 1440, - "1441" => 1441, - "1442" => 1442, - "1443" => 1443, - "1444" => 1444, - "1445" => 1445, - "1446" => 1446, - "1447" => 1447, - "1448" => 1448, - "1449" => 1449, - "1450" => 1450, - "1451" => 1451, - "1452" => 1452, - "1453" => 1453, - "1454" => 1454, - "1455" => 1455, - "1456" => 1456, - "1457" => 1457, - "1458" => 1458, - "1459" => 1459, - "1460" => 1460, - "1461" => 1461, - "1462" => 1462, - "1463" => 1463, - "1464" => 1464, - "1465" => 1465, - "1466" => 1466, - "1467" => 1467, - "1468" => 1468, - "1469" => 1469, - "1470" => 1470, - "1471" => 1471, - "1472" => 1472, - "1473" => 1473, - "1474" => 1474, - "1475" => 1475, - "1476" => 1476, - "1477" => 1477, - "1478" => 1478, - "1479" => 1479, - "1480" => 1480, - "1481" => 1481, - "1482" => 1482, - "1483" => 1483, - "1484" => 1484, - "1485" => 1485, - "1486" => 1486, - "1487" => 1487, - "1488" => 1488, - "1489" => 1489, - "1490" => 1490, - "1491" => 1491, - "1492" => 1492, - "1493" => 1493, - "1494" => 1494, - "1495" => 1495, - "1496" => 1496, - "1497" => 1497, - "1498" => 1498, - "1499" => 1499, - "1500" => 1500, - "1501" => 1501, - "1502" => 1502, - "1503" => 1503, - "1504" => 1504, - "1505" => 1505, - "1506" => 1506, - "1507" => 1507, - "1508" => 1508, - "1509" => 1509, - "1510" => 1510, - "1511" => 1511, - "1512" => 1512, - "1513" => 1513, - "1514" => 1514, - "1515" => 1515, - "1516" => 1516, - "1517" => 1517, - "1518" => 1518, - "1519" => 1519, - "1520" => 1520, - "1521" => 1521, - "1522" => 1522, - "1523" => 1523, - "1524" => 1524, - "1525" => 1525, - "1526" => 1526, - "1527" => 1527, - "1528" => 1528, - "1529" => 1529, - "1530" => 1530, - "1531" => 1531, - "1532" => 1532, - "1533" => 1533, - "1534" => 1534, - "1535" => 1535, - "1536" => 1536, - "1537" => 1537, - "1538" => 1538, - "1539" => 1539, - "1540" => 1540, - "1541" => 1541, - "1542" => 1542, - "1543" => 1543, - "1544" => 1544, - "1545" => 1545, - "1546" => 1546, - "1547" => 1547, - "1548" => 1548, - "1549" => 1549, - "1550" => 1550, - "1551" => 1551, - "1552" => 1552, - "1553" => 1553, - "1554" => 1554, - "1555" => 1555, - "1556" => 1556, - "1557" => 1557, - "1558" => 1558, - "1559" => 1559, - "1560" => 1560, - "1561" => 1561, - "1562" => 1562, - "1563" => 1563, - "1564" => 1564, - "1565" => 1565, - "1566" => 1566, - "1567" => 1567, - "1568" => 1568, - "1569" => 1569, - "1570" => 1570, - "1571" => 1571, - "1572" => 1572, - "1573" => 1573, - "1574" => 1574, - "1575" => 1575, - "1576" => 1576, - "1577" => 1577, - "1578" => 1578, - "1579" => 1579, - "1580" => 1580, - "1581" => 1581, - "1582" => 1582, - "1583" => 1583, - "1584" => 1584, - "1585" => 1585, - "1586" => 1586, - "1587" => 1587, - "1588" => 1588, - "1589" => 1589, - "1590" => 1590, - "1591" => 1591, - "1592" => 1592, - "1593" => 1593, - "1594" => 1594, - "1595" => 1595, - "1596" => 1596, - "1597" => 1597, - "1598" => 1598, - "1599" => 1599, - "1600" => 1600, - "1601" => 1601, - "1602" => 1602, - "1603" => 1603, - "1604" => 1604, - "1605" => 1605, - "1606" => 1606, - "1607" => 1607, - "1608" => 1608, - "1609" => 1609, - "1610" => 1610, - "1611" => 1611, - "1612" => 1612, - "1613" => 1613, - "1614" => 1614, - "1615" => 1615, - "1616" => 1616, - "1617" => 1617, - "1618" => 1618, - "1619" => 1619, - "1620" => 1620, - "1621" => 1621, - "1622" => 1622, - "1623" => 1623, - "1624" => 1624, - "1625" => 1625, - "1626" => 1626, - "1627" => 1627, - "1628" => 1628, - "1629" => 1629, - "1630" => 1630, - "1631" => 1631, - "1632" => 1632, - "1633" => 1633, - "1634" => 1634, - "1635" => 1635, - "1636" => 1636, - "1637" => 1637, - "1638" => 1638, - "1639" => 1639, - "1640" => 1640, - "1641" => 1641, - "1642" => 1642, - "1643" => 1643, - "1644" => 1644, - "1645" => 1645, - "1646" => 1646, - "1647" => 1647, - "1648" => 1648, - "1649" => 1649, - "1650" => 1650, - "1651" => 1651, - "1652" => 1652, - "1653" => 1653, - "1654" => 1654, - "1655" => 1655, - "1656" => 1656, - "1657" => 1657, - "1658" => 1658, - "1659" => 1659, - "1660" => 1660, - "1661" => 1661, - "1662" => 1662, - "1663" => 1663, - "1664" => 1664, - "1665" => 1665, - "1666" => 1666, - "1667" => 1667, - "1668" => 1668, - "1669" => 1669, - "1670" => 1670, - "1671" => 1671, - "1672" => 1672, - "1673" => 1673, - "1674" => 1674, - "1675" => 1675, - "1676" => 1676, - "1677" => 1677, - "1678" => 1678, - "1679" => 1679, - "1680" => 1680, - "1681" => 1681, - "1682" => 1682, - "1683" => 1683, - "1684" => 1684, - "1685" => 1685, - "1686" => 1686, - "1687" => 1687, - "1688" => 1688, - "1689" => 1689, - "1690" => 1690, - "1691" => 1691, - "1692" => 1692, - "1693" => 1693, - "1694" => 1694, - "1695" => 1695, - "1696" => 1696, - "1697" => 1697, - "1698" => 1698, - "1699" => 1699, - "1700" => 1700, - "1701" => 1701, - "1702" => 1702, - "1703" => 1703, - "1704" => 1704, - "1705" => 1705, - "1706" => 1706, - "1707" => 1707, - "1708" => 1708, - "1709" => 1709, - "1710" => 1710, - "1711" => 1711, - "1712" => 1712, - "1713" => 1713, - "1714" => 1714, - "1715" => 1715, - "1716" => 1716, - "1717" => 1717, - "1718" => 1718, - "1719" => 1719, - "1720" => 1720, - "1721" => 1721, - "1722" => 1722, - "1723" => 1723, - "1724" => 1724, - "1725" => 1725, - "1726" => 1726, - "1727" => 1727, - "1728" => 1728, - "1729" => 1729, - "1730" => 1730, - "1731" => 1731, - "1732" => 1732, - "1733" => 1733, - "1734" => 1734, - "1735" => 1735, - "1736" => 1736, - "1737" => 1737, - "1738" => 1738, - "1739" => 1739, - "1740" => 1740, - "1741" => 1741, - "1742" => 1742, - "1743" => 1743, - "1744" => 1744, - "1745" => 1745, - "1746" => 1746, - "1747" => 1747, - "1748" => 1748, - "1749" => 1749, - "1750" => 1750, - "1751" => 1751, - "1752" => 1752, - "1753" => 1753, - "1754" => 1754, - "1755" => 1755, - "1756" => 1756, - "1757" => 1757, - "1758" => 1758, - "1759" => 1759, - "1760" => 1760, - "1761" => 1761, - "1762" => 1762, - "1763" => 1763, - "1764" => 1764, - "1765" => 1765, - "1766" => 1766, - "1767" => 1767, - "1768" => 1768, - "1769" => 1769, - "1770" => 1770, - "1771" => 1771, - "1772" => 1772, - "1773" => 1773, - "1774" => 1774, - "1775" => 1775, - "1776" => 1776, - "1777" => 1777, - "1778" => 1778, - "1779" => 1779, - "1780" => 1780, - "1781" => 1781, - "1782" => 1782, - "1783" => 1783, - "1784" => 1784, - "1785" => 1785, - "1786" => 1786, - "1787" => 1787, - "1788" => 1788, - "1789" => 1789, - "1790" => 1790, - "1791" => 1791, - "1792" => 1792, - "1793" => 1793, - "1794" => 1794, - "1795" => 1795, - "1796" => 1796, - "1797" => 1797, - "1798" => 1798, - "1799" => 1799, - "1800" => 1800, - "1801" => 1801, - "1802" => 1802, - "1803" => 1803, - "1804" => 1804, - "1805" => 1805, - "1806" => 1806, - "1807" => 1807, - "1808" => 1808, - "1809" => 1809, - "1810" => 1810, - "1811" => 1811, - "1812" => 1812, - "1813" => 1813, - "1814" => 1814, - "1815" => 1815, - "1816" => 1816, - "1817" => 1817, - "1818" => 1818, - "1819" => 1819, - "1820" => 1820, - "1821" => 1821, - "1822" => 1822, - "1823" => 1823, - "1824" => 1824, - "1825" => 1825, - "1826" => 1826, - "1827" => 1827, - "1828" => 1828, - "1829" => 1829, - "1830" => 1830, - "1831" => 1831, - "1832" => 1832, - "1833" => 1833, - "1834" => 1834, - "1835" => 1835, - "1836" => 1836, - "1837" => 1837, - "1838" => 1838, - "1839" => 1839, - "1840" => 1840, - "1841" => 1841, - "1842" => 1842, - "1843" => 1843, - "1844" => 1844, - "1845" => 1845, - "1846" => 1846, - "1847" => 1847, - "1848" => 1848, - "1849" => 1849, - "1850" => 1850, - "1851" => 1851, - "1852" => 1852, - "1853" => 1853, - "1854" => 1854, - "1855" => 1855, - "1856" => 1856, - "1857" => 1857, - "1858" => 1858, - "1859" => 1859, - "1860" => 1860, - "1861" => 1861, - "1862" => 1862, - "1863" => 1863, - "1864" => 1864, - "1865" => 1865, - "1866" => 1866, - "1867" => 1867, - "1868" => 1868, - "1869" => 1869, - "1870" => 1870, - "1871" => 1871, - "1872" => 1872, - "1873" => 1873, - "1874" => 1874, - "1875" => 1875, - "1876" => 1876, - "1877" => 1877, - "1878" => 1878, - "1879" => 1879, - "1880" => 1880, - "1881" => 1881, - "1882" => 1882, - "1883" => 1883, - "1884" => 1884, - "1885" => 1885, - "1886" => 1886, - "1887" => 1887, - "1888" => 1888, - "1889" => 1889, - "1890" => 1890, - "1891" => 1891, - "1892" => 1892, - "1893" => 1893, - "1894" => 1894, - "1895" => 1895, - "1896" => 1896, - "1897" => 1897, - "1898" => 1898, - "1899" => 1899, - "1900" => 1900, - "1901" => 1901, - "1902" => 1902, - "1903" => 1903, - "1904" => 1904, - "1905" => 1905, - "1906" => 1906, - "1907" => 1907, - "1908" => 1908, - "1909" => 1909, - "1910" => 1910, - "1911" => 1911, - "1912" => 1912, - "1913" => 1913, - "1914" => 1914, - "1915" => 1915, - "1916" => 1916, - "1917" => 1917, - "1918" => 1918, - "1919" => 1919, - "1920" => 1920, - "1921" => 1921, - "1922" => 1922, - "1923" => 1923, - "1924" => 1924, - "1925" => 1925, - "1926" => 1926, - "1927" => 1927, - "1928" => 1928, - "1929" => 1929, - "1930" => 1930, - "1931" => 1931, - "1932" => 1932, - "1933" => 1933, - "1934" => 1934, - "1935" => 1935, - "1936" => 1936, - "1937" => 1937, - "1938" => 1938, - "1939" => 1939, - "1940" => 1940, - "1941" => 1941, - "1942" => 1942, - "1943" => 1943, - "1944" => 1944, - "1945" => 1945, - "1946" => 1946, - "1947" => 1947, - "1948" => 1948, - "1949" => 1949, - "1950" => 1950, - "1951" => 1951, - "1952" => 1952, - "1953" => 1953, - "1954" => 1954, - "1955" => 1955, - "1956" => 1956, - "1957" => 1957, - "1958" => 1958, - "1959" => 1959, - "1960" => 1960, - "1961" => 1961, - "1962" => 1962, - "1963" => 1963, - "1964" => 1964, - "1965" => 1965, - "1966" => 1966, - "1967" => 1967, - "1968" => 1968, - "1969" => 1969, - "1970" => 1970, - "1971" => 1971, - "1972" => 1972, - "1973" => 1973, - "1974" => 1974, - "1975" => 1975, - "1976" => 1976, - "1977" => 1977, - "1978" => 1978, - "1979" => 1979, - "1980" => 1980, - "1981" => 1981, - "1982" => 1982, - "1983" => 1983, - "1984" => 1984, - "1985" => 1985, - "1986" => 1986, - "1987" => 1987, - "1988" => 1988, - "1989" => 1989, - "1990" => 1990, - "1991" => 1991, - "1992" => 1992, - "1993" => 1993, - "1994" => 1994, - "1995" => 1995, - "1996" => 1996, - "1997" => 1997, - "1998" => 1998, - "1999" => 1999, - "2000" => 2000, - "2001" => 2001, - "2002" => 2002, - "2003" => 2003, - "2004" => 2004, - "2005" => 2005, - "2006" => 2006, - "2007" => 2007, - "2008" => 2008, - "2009" => 2009, - "2010" => 2010, - "2011" => 2011, - "2012" => 2012, - "2013" => 2013, - "2014" => 2014, - "2015" => 2015, - "2016" => 2016, - "2017" => 2017, - "2018" => 2018, - "2019" => 2019, - "2020" => 2020, - "2021" => 2021, - "2022" => 2022, - "2023" => 2023, - "2024" => 2024, - "2025" => 2025, - "2026" => 2026, - "2027" => 2027, - "2028" => 2028, - "2029" => 2029, - "2030" => 2030, - "2031" => 2031, - "2032" => 2032, - "2033" => 2033, - "2034" => 2034, - "2035" => 2035, - "2036" => 2036, - "2037" => 2037, - "2038" => 2038, - "2039" => 2039, - "2040" => 2040, - "2041" => 2041, - "2042" => 2042, - "2043" => 2043, - "2044" => 2044, - "2045" => 2045, - "2046" => 2046, - "2047" => 2047, - "2048" => 2048, - "2049" => 2049, - "2050" => 2050, - "2051" => 2051, - "2052" => 2052, - "2053" => 2053, - "2054" => 2054, - "2055" => 2055, - "2056" => 2056, - "2057" => 2057, - "2058" => 2058, - "2059" => 2059, - "2060" => 2060, - "2061" => 2061, - "2062" => 2062, - "2063" => 2063, - "2064" => 2064, - "2065" => 2065, - "2066" => 2066, - "2067" => 2067, - "2068" => 2068, - "2069" => 2069, - "2070" => 2070, - "2071" => 2071, - "2072" => 2072, - "2073" => 2073, - "2074" => 2074, - "2075" => 2075, - "2076" => 2076, - "2077" => 2077, - "2078" => 2078, - "2079" => 2079, - "2080" => 2080, - "2081" => 2081, - "2082" => 2082, - "2083" => 2083, - "2084" => 2084, - "2085" => 2085, - "2086" => 2086, - "2087" => 2087, - "2088" => 2088, - "2089" => 2089, - "2090" => 2090, - "2091" => 2091, - "2092" => 2092, - "2093" => 2093, - "2094" => 2094, - "2095" => 2095, - "2096" => 2096, - "2097" => 2097, - "2098" => 2098, - "2099" => 2099, - "2100" => 2100, - "2101" => 2101, - "2102" => 2102, - "2103" => 2103, - "2104" => 2104, - "2105" => 2105, - "2106" => 2106, - "2107" => 2107, - "2108" => 2108, - "2109" => 2109, - "2110" => 2110, - "2111" => 2111, - "2112" => 2112, - "2113" => 2113, - "2114" => 2114, - "2115" => 2115, - "2116" => 2116, - "2117" => 2117, - "2118" => 2118, - "2119" => 2119, - "2120" => 2120, - "2121" => 2121, - "2122" => 2122, - "2123" => 2123, - "2124" => 2124, - "2125" => 2125, - "2126" => 2126, - "2127" => 2127, - "2128" => 2128, - "2129" => 2129, - "2130" => 2130, - "2131" => 2131, - "2132" => 2132, - "2133" => 2133, - "2134" => 2134, - "2135" => 2135, - "2136" => 2136, - "2137" => 2137, - "2138" => 2138, - "2139" => 2139, - "2140" => 2140, - "2141" => 2141, - "2142" => 2142, - "2143" => 2143, - "2144" => 2144, - "2145" => 2145, - "2146" => 2146, - "2147" => 2147, - "2148" => 2148, - "2149" => 2149, - "2150" => 2150, - "2151" => 2151, - "2152" => 2152, - "2153" => 2153, - "2154" => 2154, - "2155" => 2155, - "2156" => 2156, - "2157" => 2157, - "2158" => 2158, - "2159" => 2159, - "2160" => 2160, - "2161" => 2161, - "2162" => 2162, - "2163" => 2163, - "2164" => 2164, - "2165" => 2165, - "2166" => 2166, - "2167" => 2167, - "2168" => 2168, - "2169" => 2169, - "2170" => 2170, - "2171" => 2171, - "2172" => 2172, - "2173" => 2173, - "2174" => 2174, - "2175" => 2175, - "2176" => 2176, - "2177" => 2177, - "2178" => 2178, - "2179" => 2179, - "2180" => 2180, - "2181" => 2181, - "2182" => 2182, - "2183" => 2183, - "2184" => 2184, - "2185" => 2185, - "2186" => 2186, - "2187" => 2187, - "2188" => 2188, - "2189" => 2189, - "2190" => 2190, - "2191" => 2191, - "2192" => 2192, - "2193" => 2193, - "2194" => 2194, - "2195" => 2195, - "2196" => 2196, - "2197" => 2197, - "2198" => 2198, - "2199" => 2199, - "2200" => 2200, - "2201" => 2201, - "2202" => 2202, - "2203" => 2203, - "2204" => 2204, - "2205" => 2205, - "2206" => 2206, - "2207" => 2207, - "2208" => 2208, - "2209" => 2209, - "2210" => 2210, - "2211" => 2211, - "2212" => 2212, - "2213" => 2213, - "2214" => 2214, - "2215" => 2215, - "2216" => 2216, - "2217" => 2217, - "2218" => 2218, - "2219" => 2219, - "2220" => 2220, - "2221" => 2221, - "2222" => 2222, - "2223" => 2223, - "2224" => 2224, - "2225" => 2225, - "2226" => 2226, - "2227" => 2227, - "2228" => 2228, - "2229" => 2229, - "2230" => 2230, - "2231" => 2231, - "2232" => 2232, - "2233" => 2233, - "2234" => 2234, - "2235" => 2235, - "2236" => 2236, - "2237" => 2237, - "2238" => 2238, - "2239" => 2239, - "2240" => 2240, - "2241" => 2241, - "2242" => 2242, - "2243" => 2243, - "2244" => 2244, - "2245" => 2245, - "2246" => 2246, - "2247" => 2247, - "2248" => 2248, - "2249" => 2249, - "2250" => 2250, - "2251" => 2251, - "2252" => 2252, - "2253" => 2253, - "2254" => 2254, - "2255" => 2255, - "2256" => 2256, - "2257" => 2257, - "2258" => 2258, - "2259" => 2259, - "2260" => 2260, - "2261" => 2261, - "2262" => 2262, - "2263" => 2263, - "2264" => 2264, - "2265" => 2265, - "2266" => 2266, - "2267" => 2267, - "2268" => 2268, - "2269" => 2269, - "2270" => 2270, - "2271" => 2271, - "2272" => 2272, - "2273" => 2273, - "2274" => 2274, - "2275" => 2275, - "2276" => 2276, - "2277" => 2277, - "2278" => 2278, - "2279" => 2279, - "2280" => 2280, - "2281" => 2281, - "2282" => 2282, - "2283" => 2283, - "2284" => 2284, - "2285" => 2285, - "2286" => 2286, - "2287" => 2287, - "2288" => 2288, - "2289" => 2289, - "2290" => 2290, - "2291" => 2291, - "2292" => 2292, - "2293" => 2293, - "2294" => 2294, - "2295" => 2295, - "2296" => 2296, - "2297" => 2297, - "2298" => 2298, - "2299" => 2299, - "2300" => 2300, - "2301" => 2301, - "2302" => 2302, - "2303" => 2303, - "2304" => 2304, - "2305" => 2305, - "2306" => 2306, - "2307" => 2307, - "2308" => 2308, - "2309" => 2309, - "2310" => 2310, - "2311" => 2311, - "2312" => 2312, - "2313" => 2313, - "2314" => 2314, - "2315" => 2315, - "2316" => 2316, - "2317" => 2317, - "2318" => 2318, - "2319" => 2319, - "2320" => 2320, - "2321" => 2321, - "2322" => 2322, - "2323" => 2323, - "2324" => 2324, - "2325" => 2325, - "2326" => 2326, - "2327" => 2327, - "2328" => 2328, - "2329" => 2329, - "2330" => 2330, - "2331" => 2331, - "2332" => 2332, - "2333" => 2333, - "2334" => 2334, - "2335" => 2335, - "2336" => 2336, - "2337" => 2337, - "2338" => 2338, - "2339" => 2339, - "2340" => 2340, - "2341" => 2341, - "2342" => 2342, - "2343" => 2343, - "2344" => 2344, - "2345" => 2345, - "2346" => 2346, - "2347" => 2347, - "2348" => 2348, - "2349" => 2349, - "2350" => 2350, - "2351" => 2351, - "2352" => 2352, - "2353" => 2353, - "2354" => 2354, - "2355" => 2355, - "2356" => 2356, - "2357" => 2357, - "2358" => 2358, - "2359" => 2359, - "2360" => 2360, - "2361" => 2361, - "2362" => 2362, - "2363" => 2363, - "2364" => 2364, - "2365" => 2365, - "2366" => 2366, - "2367" => 2367, - "2368" => 2368, - "2369" => 2369, - "2370" => 2370, - "2371" => 2371, - "2372" => 2372, - "2373" => 2373, - "2374" => 2374, - "2375" => 2375, - "2376" => 2376, - "2377" => 2377, - "2378" => 2378, - "2379" => 2379, - "2380" => 2380, - "2381" => 2381, - "2382" => 2382, - "2383" => 2383, - "2384" => 2384, - "2385" => 2385, - "2386" => 2386, - "2387" => 2387, - "2388" => 2388, - "2389" => 2389, - "2390" => 2390, - "2391" => 2391, - "2392" => 2392, - "2393" => 2393, - "2394" => 2394, - "2395" => 2395, - "2396" => 2396, - "2397" => 2397, - "2398" => 2398, - "2399" => 2399, - "2400" => 2400, - "2401" => 2401, - "2402" => 2402, - "2403" => 2403, - "2404" => 2404, - "2405" => 2405, - "2406" => 2406, - "2407" => 2407, - "2408" => 2408, - "2409" => 2409, - "2410" => 2410, - "2411" => 2411, - "2412" => 2412, - "2413" => 2413, - "2414" => 2414, - "2415" => 2415, - "2416" => 2416, - "2417" => 2417, - "2418" => 2418, - "2419" => 2419, - "2420" => 2420, - "2421" => 2421, - "2422" => 2422, - "2423" => 2423, - "2424" => 2424, - "2425" => 2425, - "2426" => 2426, - "2427" => 2427, - "2428" => 2428, - "2429" => 2429, - "2430" => 2430, - "2431" => 2431, - "2432" => 2432, - "2433" => 2433, - "2434" => 2434, - "2435" => 2435, - "2436" => 2436, - "2437" => 2437, - "2438" => 2438, - "2439" => 2439, - "2440" => 2440, - "2441" => 2441, - "2442" => 2442, - "2443" => 2443, - "2444" => 2444, - "2445" => 2445, - "2446" => 2446, - "2447" => 2447, - "2448" => 2448, - "2449" => 2449, - "2450" => 2450, - "2451" => 2451, - "2452" => 2452, - "2453" => 2453, - "2454" => 2454, - "2455" => 2455, - "2456" => 2456, - "2457" => 2457, - "2458" => 2458, - "2459" => 2459, - "2460" => 2460, - "2461" => 2461, - "2462" => 2462, - "2463" => 2463, - "2464" => 2464, - "2465" => 2465, - "2466" => 2466, - "2467" => 2467, - "2468" => 2468, - "2469" => 2469, - "2470" => 2470, - "2471" => 2471, - "2472" => 2472, - "2473" => 2473, - "2474" => 2474, - "2475" => 2475, - "2476" => 2476, - "2477" => 2477, - "2478" => 2478, - "2479" => 2479, - "2480" => 2480, - "2481" => 2481, - "2482" => 2482, - "2483" => 2483, - "2484" => 2484, - "2485" => 2485, - "2486" => 2486, - "2487" => 2487, - "2488" => 2488, - "2489" => 2489, - "2490" => 2490, - "2491" => 2491, - "2492" => 2492, - "2493" => 2493, - "2494" => 2494, - "2495" => 2495, - "2496" => 2496, - "2497" => 2497, - "2498" => 2498, - "2499" => 2499, - "2500" => 2500, - "2501" => 2501, - "2502" => 2502, - "2503" => 2503, - "2504" => 2504, - "2505" => 2505, - "2506" => 2506, - "2507" => 2507, - "2508" => 2508, - "2509" => 2509, - "2510" => 2510, - "2511" => 2511, - "2512" => 2512, - "2513" => 2513, - "2514" => 2514, - "2515" => 2515, - "2516" => 2516, - "2517" => 2517, - "2518" => 2518, - "2519" => 2519, - "2520" => 2520, - "2521" => 2521, - "2522" => 2522, - "2523" => 2523, - "2524" => 2524, - "2525" => 2525, - "2526" => 2526, - "2527" => 2527, - "2528" => 2528, - "2529" => 2529, - "2530" => 2530, - "2531" => 2531, - "2532" => 2532, - "2533" => 2533, - "2534" => 2534, - "2535" => 2535, - "2536" => 2536, - "2537" => 2537, - "2538" => 2538, - "2539" => 2539, - "2540" => 2540, - "2541" => 2541, - "2542" => 2542, - "2543" => 2543, - "2544" => 2544, - "2545" => 2545, - "2546" => 2546, - "2547" => 2547, - "2548" => 2548, - "2549" => 2549, - "2550" => 2550, - "2551" => 2551, - "2552" => 2552, - "2553" => 2553, - "2554" => 2554, - "2555" => 2555, - "2556" => 2556, - "2557" => 2557, - "2558" => 2558, - "2559" => 2559, - "2560" => 2560, - "2561" => 2561, - "2562" => 2562, - "2563" => 2563, - "2564" => 2564, - "2565" => 2565, - "2566" => 2566, - "2567" => 2567, - "2568" => 2568, - "2569" => 2569, - "2570" => 2570, - "2571" => 2571, - "2572" => 2572, - "2573" => 2573, - "2574" => 2574, - "2575" => 2575, - "2576" => 2576, - "2577" => 2577, - "2578" => 2578, - "2579" => 2579, - "2580" => 2580, - "2581" => 2581, - "2582" => 2582, - "2583" => 2583, - "2584" => 2584, - "2585" => 2585, - "2586" => 2586, - "2587" => 2587, - "2588" => 2588, - "2589" => 2589, - "2590" => 2590, - "2591" => 2591, - "2592" => 2592, - "2593" => 2593, - "2594" => 2594, - "2595" => 2595, - "2596" => 2596, - "2597" => 2597, - "2598" => 2598, - "2599" => 2599, - "2600" => 2600, - "2601" => 2601, - "2602" => 2602, - "2603" => 2603, - "2604" => 2604, - "2605" => 2605, - "2606" => 2606, - "2607" => 2607, - "2608" => 2608, - "2609" => 2609, - "2610" => 2610, - "2611" => 2611, - "2612" => 2612, - "2613" => 2613, - "2614" => 2614, - "2615" => 2615, - "2616" => 2616, - "2617" => 2617, - "2618" => 2618, - "2619" => 2619, - "2620" => 2620, - "2621" => 2621, - "2622" => 2622, - "2623" => 2623, - "2624" => 2624, - "2625" => 2625, - "2626" => 2626, - "2627" => 2627, - "2628" => 2628, - "2629" => 2629, - "2630" => 2630, - "2631" => 2631, - "2632" => 2632, - "2633" => 2633, - "2634" => 2634, - "2635" => 2635, - "2636" => 2636, - "2637" => 2637, - "2638" => 2638, - "2639" => 2639, - "2640" => 2640, - "2641" => 2641, - "2642" => 2642, - "2643" => 2643, - "2644" => 2644, - "2645" => 2645, - "2646" => 2646, - "2647" => 2647, - "2648" => 2648, - "2649" => 2649, - "2650" => 2650, - "2651" => 2651, - "2652" => 2652, - "2653" => 2653, - "2654" => 2654, - "2655" => 2655, - "2656" => 2656, - "2657" => 2657, - "2658" => 2658, - "2659" => 2659, - "2660" => 2660, - "2661" => 2661, - "2662" => 2662, - "2663" => 2663, - "2664" => 2664, - "2665" => 2665, - "2666" => 2666, - "2667" => 2667, - "2668" => 2668, - "2669" => 2669, - "2670" => 2670, - "2671" => 2671, - "2672" => 2672, - "2673" => 2673, - "2674" => 2674, - "2675" => 2675, - "2676" => 2676, - "2677" => 2677, - "2678" => 2678, - "2679" => 2679, - "2680" => 2680, - "2681" => 2681, - "2682" => 2682, - "2683" => 2683, - "2684" => 2684, - "2685" => 2685, - "2686" => 2686, - "2687" => 2687, - "2688" => 2688, - "2689" => 2689, - "2690" => 2690, - "2691" => 2691, - "2692" => 2692, - "2693" => 2693, - "2694" => 2694, - "2695" => 2695, - "2696" => 2696, - "2697" => 2697, - "2698" => 2698, - "2699" => 2699, - "2700" => 2700, - "2701" => 2701, - "2702" => 2702, - "2703" => 2703, - "2704" => 2704, - "2705" => 2705, - "2706" => 2706, - "2707" => 2707, - "2708" => 2708, - "2709" => 2709, - "2710" => 2710, - "2711" => 2711, - "2712" => 2712, - "2713" => 2713, - "2714" => 2714, - "2715" => 2715, - "2716" => 2716, - "2717" => 2717, - "2718" => 2718, - "2719" => 2719, - "2720" => 2720, - "2721" => 2721, - "2722" => 2722, - "2723" => 2723, - "2724" => 2724, - "2725" => 2725, - "2726" => 2726, - "2727" => 2727, - "2728" => 2728, - "2729" => 2729, - "2730" => 2730, - "2731" => 2731, - "2732" => 2732, - "2733" => 2733, - "2734" => 2734, - "2735" => 2735, - "2736" => 2736, - "2737" => 2737, - "2738" => 2738, - "2739" => 2739, - "2740" => 2740, - "2741" => 2741, - "2742" => 2742, - "2743" => 2743, - "2744" => 2744, - "2745" => 2745, - "2746" => 2746, - "2747" => 2747, - "2748" => 2748, - "2749" => 2749, - "2750" => 2750, - "2751" => 2751, - "2752" => 2752, - "2753" => 2753, - "2754" => 2754, - "2755" => 2755, - "2756" => 2756, - "2757" => 2757, - "2758" => 2758, - "2759" => 2759, - "2760" => 2760, - "2761" => 2761, - "2762" => 2762, - "2763" => 2763, - "2764" => 2764, - "2765" => 2765, - "2766" => 2766, - "2767" => 2767, - "2768" => 2768, - "2769" => 2769, - "2770" => 2770, - "2771" => 2771, - "2772" => 2772, - "2773" => 2773, - "2774" => 2774, - "2775" => 2775, - "2776" => 2776, - "2777" => 2777, - "2778" => 2778, - "2779" => 2779, - "2780" => 2780, - "2781" => 2781, - "2782" => 2782, - "2783" => 2783, - "2784" => 2784, - "2785" => 2785, - "2786" => 2786, - "2787" => 2787, - "2788" => 2788, - "2789" => 2789, - "2790" => 2790, - "2791" => 2791, - "2792" => 2792, - "2793" => 2793, - "2794" => 2794, - "2795" => 2795, - "2796" => 2796, - "2797" => 2797, - "2798" => 2798, - "2799" => 2799, - "2800" => 2800, - "2801" => 2801, - "2802" => 2802, - "2803" => 2803, - "2804" => 2804, - "2805" => 2805, - "2806" => 2806, - "2807" => 2807, - "2808" => 2808, - "2809" => 2809, - "2810" => 2810, - "2811" => 2811, - "2812" => 2812, - "2813" => 2813, - "2814" => 2814, - "2815" => 2815, - "2816" => 2816, - "2817" => 2817, - "2818" => 2818, - "2819" => 2819, - "2820" => 2820, - "2821" => 2821, - "2822" => 2822, - "2823" => 2823, - "2824" => 2824, - "2825" => 2825, - "2826" => 2826, - "2827" => 2827, - "2828" => 2828, - "2829" => 2829, - "2830" => 2830, - "2831" => 2831, - "2832" => 2832, - "2833" => 2833, - "2834" => 2834, - "2835" => 2835, - "2836" => 2836, - "2837" => 2837, - "2838" => 2838, - "2839" => 2839, - "2840" => 2840, - "2841" => 2841, - "2842" => 2842, - "2843" => 2843, - "2844" => 2844, - "2845" => 2845, - "2846" => 2846, - "2847" => 2847, - "2848" => 2848, - "2849" => 2849, - "2850" => 2850, - "2851" => 2851, - "2852" => 2852, - "2853" => 2853, - "2854" => 2854, - "2855" => 2855, - "2856" => 2856, - "2857" => 2857, - "2858" => 2858, - "2859" => 2859, - "2860" => 2860, - "2861" => 2861, - "2862" => 2862, - "2863" => 2863, - "2864" => 2864, - "2865" => 2865, - "2866" => 2866, - "2867" => 2867, - "2868" => 2868, - "2869" => 2869, - "2870" => 2870, - "2871" => 2871, - "2872" => 2872, - "2873" => 2873, - "2874" => 2874, - "2875" => 2875, - "2876" => 2876, - "2877" => 2877, - "2878" => 2878, - "2879" => 2879, - "2880" => 2880, - "2881" => 2881, - "2882" => 2882, - "2883" => 2883, - "2884" => 2884, - "2885" => 2885, - "2886" => 2886, - "2887" => 2887, - "2888" => 2888, - "2889" => 2889, - "2890" => 2890, - "2891" => 2891, - "2892" => 2892, - "2893" => 2893, - "2894" => 2894, - "2895" => 2895, - "2896" => 2896, - "2897" => 2897, - "2898" => 2898, - "2899" => 2899, - "2900" => 2900, - "2901" => 2901, - "2902" => 2902, - "2903" => 2903, - "2904" => 2904, - "2905" => 2905, - "2906" => 2906, - "2907" => 2907, - "2908" => 2908, - "2909" => 2909, - "2910" => 2910, - "2911" => 2911, - "2912" => 2912, - "2913" => 2913, - "2914" => 2914, - "2915" => 2915, - "2916" => 2916, - "2917" => 2917, - "2918" => 2918, - "2919" => 2919, - "2920" => 2920, - "2921" => 2921, - "2922" => 2922, - "2923" => 2923, - "2924" => 2924, - "2925" => 2925, - "2926" => 2926, - "2927" => 2927, - "2928" => 2928, - "2929" => 2929, - "2930" => 2930, - "2931" => 2931, - "2932" => 2932, - "2933" => 2933, - "2934" => 2934, - "2935" => 2935, - "2936" => 2936, - "2937" => 2937, - "2938" => 2938, - "2939" => 2939, - "2940" => 2940, - "2941" => 2941, - "2942" => 2942, - "2943" => 2943, - "2944" => 2944, - "2945" => 2945, - "2946" => 2946, - "2947" => 2947, - "2948" => 2948, - "2949" => 2949, - "2950" => 2950, - "2951" => 2951, - "2952" => 2952, - "2953" => 2953, - "2954" => 2954, - "2955" => 2955, - "2956" => 2956, - "2957" => 2957, - "2958" => 2958, - "2959" => 2959, - "2960" => 2960, - "2961" => 2961, - "2962" => 2962, - "2963" => 2963, - "2964" => 2964, - "2965" => 2965, - "2966" => 2966, - "2967" => 2967, - "2968" => 2968, - "2969" => 2969, - "2970" => 2970, - "2971" => 2971, - "2972" => 2972, - "2973" => 2973, - "2974" => 2974, - "2975" => 2975, - "2976" => 2976, - "2977" => 2977, - "2978" => 2978, - "2979" => 2979, - "2980" => 2980, - "2981" => 2981, - "2982" => 2982, - "2983" => 2983, - "2984" => 2984, - "2985" => 2985, - "2986" => 2986, - "2987" => 2987, - "2988" => 2988, - "2989" => 2989, - "2990" => 2990, - "2991" => 2991, - "2992" => 2992, - "2993" => 2993, - "2994" => 2994, - "2995" => 2995, - "2996" => 2996, - "2997" => 2997, - "2998" => 2998, - "2999" => 2999, - "3000" => 3000, - "3001" => 3001, - "3002" => 3002, - "3003" => 3003, - "3004" => 3004, - "3005" => 3005, - "3006" => 3006, - "3007" => 3007, - "3008" => 3008, - "3009" => 3009, - "3010" => 3010, - "3011" => 3011, - "3012" => 3012, - "3013" => 3013, - "3014" => 3014, - "3015" => 3015, - "3016" => 3016, - "3017" => 3017, - "3018" => 3018, - "3019" => 3019, - "3020" => 3020, - "3021" => 3021, - "3022" => 3022, - "3023" => 3023, - "3024" => 3024, - "3025" => 3025, - "3026" => 3026, - "3027" => 3027, - "3028" => 3028, - "3029" => 3029, - "3030" => 3030, - "3031" => 3031, - "3032" => 3032, - "3033" => 3033, - "3034" => 3034, - "3035" => 3035, - "3036" => 3036, - "3037" => 3037, - "3038" => 3038, - "3039" => 3039, - "3040" => 3040, - "3041" => 3041, - "3042" => 3042, - "3043" => 3043, - "3044" => 3044, - "3045" => 3045, - "3046" => 3046, - "3047" => 3047, - "3048" => 3048, - "3049" => 3049, - "3050" => 3050, - "3051" => 3051, - "3052" => 3052, - "3053" => 3053, - "3054" => 3054, - "3055" => 3055, - "3056" => 3056, - "3057" => 3057, - "3058" => 3058, - "3059" => 3059, - "3060" => 3060, - "3061" => 3061, - "3062" => 3062, - "3063" => 3063, - "3064" => 3064, - "3065" => 3065, - "3066" => 3066, - "3067" => 3067, - "3068" => 3068, - "3069" => 3069, - "3070" => 3070, - "3071" => 3071, - "3072" => 3072, - "3073" => 3073, - "3074" => 3074, - "3075" => 3075, - "3076" => 3076, - "3077" => 3077, - "3078" => 3078, - "3079" => 3079, - "3080" => 3080, - "3081" => 3081, - "3082" => 3082, - "3083" => 3083, - "3084" => 3084, - "3085" => 3085, - "3086" => 3086, - "3087" => 3087, - "3088" => 3088, - "3089" => 3089, - "3090" => 3090, - "3091" => 3091, - "3092" => 3092, - "3093" => 3093, - "3094" => 3094, - "3095" => 3095, - "3096" => 3096, - "3097" => 3097, - "3098" => 3098, - "3099" => 3099, - "3100" => 3100, - "3101" => 3101, - "3102" => 3102, - "3103" => 3103, - "3104" => 3104, - "3105" => 3105, - "3106" => 3106, - "3107" => 3107, - "3108" => 3108, - "3109" => 3109, - "3110" => 3110, - "3111" => 3111, - "3112" => 3112, - "3113" => 3113, - "3114" => 3114, - "3115" => 3115, - "3116" => 3116, - "3117" => 3117, - "3118" => 3118, - "3119" => 3119, - "3120" => 3120, - "3121" => 3121, - "3122" => 3122, - "3123" => 3123, - "3124" => 3124, - "3125" => 3125, - "3126" => 3126, - "3127" => 3127, - "3128" => 3128, - "3129" => 3129, - "3130" => 3130, - "3131" => 3131, - "3132" => 3132, - "3133" => 3133, - "3134" => 3134, - "3135" => 3135, - "3136" => 3136, - "3137" => 3137, - "3138" => 3138, - "3139" => 3139, - "3140" => 3140, - "3141" => 3141, - "3142" => 3142, - "3143" => 3143, - "3144" => 3144, - "3145" => 3145, - "3146" => 3146, - "3147" => 3147, - "3148" => 3148, - "3149" => 3149, - "3150" => 3150, - "3151" => 3151, - "3152" => 3152, - "3153" => 3153, - "3154" => 3154, - "3155" => 3155, - "3156" => 3156, - "3157" => 3157, - "3158" => 3158, - "3159" => 3159, - "3160" => 3160, - "3161" => 3161, - "3162" => 3162, - "3163" => 3163, - "3164" => 3164, - "3165" => 3165, - "3166" => 3166, - "3167" => 3167, - "3168" => 3168, - "3169" => 3169, - "3170" => 3170, - "3171" => 3171, - "3172" => 3172, - "3173" => 3173, - "3174" => 3174, - "3175" => 3175, - "3176" => 3176, - "3177" => 3177, - "3178" => 3178, - "3179" => 3179, - "3180" => 3180, - "3181" => 3181, - "3182" => 3182, - "3183" => 3183, - "3184" => 3184, - "3185" => 3185, - "3186" => 3186, - "3187" => 3187, - "3188" => 3188, - "3189" => 3189, - "3190" => 3190, - "3191" => 3191, - "3192" => 3192, - "3193" => 3193, - "3194" => 3194, - "3195" => 3195, - "3196" => 3196, - "3197" => 3197, - "3198" => 3198, - "3199" => 3199, - "3200" => 3200, - "3201" => 3201, - "3202" => 3202, - "3203" => 3203, - "3204" => 3204, - "3205" => 3205, - "3206" => 3206, - "3207" => 3207, - "3208" => 3208, - "3209" => 3209, - "3210" => 3210, - "3211" => 3211, - "3212" => 3212, - "3213" => 3213, - "3214" => 3214, - "3215" => 3215, - "3216" => 3216, - "3217" => 3217, - "3218" => 3218, - "3219" => 3219, - "3220" => 3220, - "3221" => 3221, - "3222" => 3222, - "3223" => 3223, - "3224" => 3224, - "3225" => 3225, - "3226" => 3226, - "3227" => 3227, - "3228" => 3228, - "3229" => 3229, - "3230" => 3230, - "3231" => 3231, - "3232" => 3232, - "3233" => 3233, - "3234" => 3234, - "3235" => 3235, - "3236" => 3236, - "3237" => 3237, - "3238" => 3238, - "3239" => 3239, - "3240" => 3240, - "3241" => 3241, - "3242" => 3242, - "3243" => 3243, - "3244" => 3244, - "3245" => 3245, - "3246" => 3246, - "3247" => 3247, - "3248" => 3248, - "3249" => 3249, - "3250" => 3250, - "3251" => 3251, - "3252" => 3252, - "3253" => 3253, - "3254" => 3254, - "3255" => 3255, - "3256" => 3256, - "3257" => 3257, - "3258" => 3258, - "3259" => 3259, - "3260" => 3260, - "3261" => 3261, - "3262" => 3262, - "3263" => 3263, - "3264" => 3264, - "3265" => 3265, - "3266" => 3266, - "3267" => 3267, - "3268" => 3268, - "3269" => 3269, - "3270" => 3270, - "3271" => 3271, - "3272" => 3272, - "3273" => 3273, - "3274" => 3274, - "3275" => 3275, - "3276" => 3276, - "3277" => 3277, - "3278" => 3278, - "3279" => 3279, - "3280" => 3280, - "3281" => 3281, - "3282" => 3282, - "3283" => 3283, - "3284" => 3284, - "3285" => 3285, - "3286" => 3286, - "3287" => 3287, - "3288" => 3288, - "3289" => 3289, - "3290" => 3290, - "3291" => 3291, - "3292" => 3292, - "3293" => 3293, - "3294" => 3294, - "3295" => 3295, - "3296" => 3296, - "3297" => 3297, - "3298" => 3298, - "3299" => 3299, - "3300" => 3300, - "3301" => 3301, - "3302" => 3302, - "3303" => 3303, - "3304" => 3304, - "3305" => 3305, - "3306" => 3306, - "3307" => 3307, - "3308" => 3308, - "3309" => 3309, - "3310" => 3310, - "3311" => 3311, - "3312" => 3312, - "3313" => 3313, - "3314" => 3314, - "3315" => 3315, - "3316" => 3316, - "3317" => 3317, - "3318" => 3318, - "3319" => 3319, - "3320" => 3320, - "3321" => 3321, - "3322" => 3322, - "3323" => 3323, - "3324" => 3324, - "3325" => 3325, - "3326" => 3326, - "3327" => 3327, - "3328" => 3328, - "3329" => 3329, - "3330" => 3330, - "3331" => 3331, - "3332" => 3332, - "3333" => 3333, - "3334" => 3334, - "3335" => 3335, - "3336" => 3336, - "3337" => 3337, - "3338" => 3338, - "3339" => 3339, - "3340" => 3340, - "3341" => 3341, - "3342" => 3342, - "3343" => 3343, - "3344" => 3344, - "3345" => 3345, - "3346" => 3346, - "3347" => 3347, - "3348" => 3348, - "3349" => 3349, - "3350" => 3350, - "3351" => 3351, - "3352" => 3352, - "3353" => 3353, - "3354" => 3354, - "3355" => 3355, - "3356" => 3356, - "3357" => 3357, - "3358" => 3358, - "3359" => 3359, - "3360" => 3360, - "3361" => 3361, - "3362" => 3362, - "3363" => 3363, - "3364" => 3364, - "3365" => 3365, - "3366" => 3366, - "3367" => 3367, - "3368" => 3368, - "3369" => 3369, - "3370" => 3370, - "3371" => 3371, - "3372" => 3372, - "3373" => 3373, - "3374" => 3374, - "3375" => 3375, - "3376" => 3376, - "3377" => 3377, - "3378" => 3378, - "3379" => 3379, - "3380" => 3380, - "3381" => 3381, - "3382" => 3382, - "3383" => 3383, - "3384" => 3384, - "3385" => 3385, - "3386" => 3386, - "3387" => 3387, - "3388" => 3388, - "3389" => 3389, - "3390" => 3390, - "3391" => 3391, - "3392" => 3392, - "3393" => 3393, - "3394" => 3394, - "3395" => 3395, - "3396" => 3396, - "3397" => 3397, - "3398" => 3398, - "3399" => 3399, - "3400" => 3400, - "3401" => 3401, - "3402" => 3402, - "3403" => 3403, - "3404" => 3404, - "3405" => 3405, - "3406" => 3406, - "3407" => 3407, - "3408" => 3408, - "3409" => 3409, - "3410" => 3410, - "3411" => 3411, - "3412" => 3412, - "3413" => 3413, - "3414" => 3414, - "3415" => 3415, - "3416" => 3416, - "3417" => 3417, - "3418" => 3418, - "3419" => 3419, - "3420" => 3420, - "3421" => 3421, - "3422" => 3422, - "3423" => 3423, - "3424" => 3424, - "3425" => 3425, - "3426" => 3426, - "3427" => 3427, - "3428" => 3428, - "3429" => 3429, - "3430" => 3430, - "3431" => 3431, - "3432" => 3432, - "3433" => 3433, - "3434" => 3434, - "3435" => 3435, - "3436" => 3436, - "3437" => 3437, - "3438" => 3438, - "3439" => 3439, - "3440" => 3440, - "3441" => 3441, - "3442" => 3442, - "3443" => 3443, - "3444" => 3444, - "3445" => 3445, - "3446" => 3446, - "3447" => 3447, - "3448" => 3448, - "3449" => 3449, - "3450" => 3450, - "3451" => 3451, - "3452" => 3452, - "3453" => 3453, - "3454" => 3454, - "3455" => 3455, - "3456" => 3456, - "3457" => 3457, - "3458" => 3458, - "3459" => 3459, - "3460" => 3460, - "3461" => 3461, - "3462" => 3462, - "3463" => 3463, - "3464" => 3464, - "3465" => 3465, - "3466" => 3466, - "3467" => 3467, - "3468" => 3468, - "3469" => 3469, - "3470" => 3470, - "3471" => 3471, - "3472" => 3472, - "3473" => 3473, - "3474" => 3474, - "3475" => 3475, - "3476" => 3476, - "3477" => 3477, - "3478" => 3478, - "3479" => 3479, - "3480" => 3480, - "3481" => 3481, - "3482" => 3482, - "3483" => 3483, - "3484" => 3484, - "3485" => 3485, - "3486" => 3486, - "3487" => 3487, - "3488" => 3488, - "3489" => 3489, - "3490" => 3490, - "3491" => 3491, - "3492" => 3492, - "3493" => 3493, - "3494" => 3494, - "3495" => 3495, - "3496" => 3496, - "3497" => 3497, - "3498" => 3498, - "3499" => 3499, - "3500" => 3500, - "3501" => 3501, - "3502" => 3502, - "3503" => 3503, - "3504" => 3504, - "3505" => 3505, - "3506" => 3506, - "3507" => 3507, - "3508" => 3508, - "3509" => 3509, - "3510" => 3510, - "3511" => 3511, - "3512" => 3512, - "3513" => 3513, - "3514" => 3514, - "3515" => 3515, - "3516" => 3516, - "3517" => 3517, - "3518" => 3518, - "3519" => 3519, - "3520" => 3520, - "3521" => 3521, - "3522" => 3522, - "3523" => 3523, - "3524" => 3524, - "3525" => 3525, - "3526" => 3526, - "3527" => 3527, - "3528" => 3528, - "3529" => 3529, - "3530" => 3530, - "3531" => 3531, - "3532" => 3532, - "3533" => 3533, - "3534" => 3534, - "3535" => 3535, - "3536" => 3536, - "3537" => 3537, - "3538" => 3538, - "3539" => 3539, - "3540" => 3540, - "3541" => 3541, - "3542" => 3542, - "3543" => 3543, - "3544" => 3544, - "3545" => 3545, - "3546" => 3546, - "3547" => 3547, - "3548" => 3548, - "3549" => 3549, - "3550" => 3550, - "3551" => 3551, - "3552" => 3552, - "3553" => 3553, - "3554" => 3554, - "3555" => 3555, - "3556" => 3556, - "3557" => 3557, - "3558" => 3558, - "3559" => 3559, - "3560" => 3560, - "3561" => 3561, - "3562" => 3562, - "3563" => 3563, - "3564" => 3564, - "3565" => 3565, - "3566" => 3566, - "3567" => 3567, - "3568" => 3568, - "3569" => 3569, - "3570" => 3570, - "3571" => 3571, - "3572" => 3572, - "3573" => 3573, - "3574" => 3574, - "3575" => 3575, - "3576" => 3576, - "3577" => 3577, - "3578" => 3578, - "3579" => 3579, - "3580" => 3580, - "3581" => 3581, - "3582" => 3582, - "3583" => 3583, - "3584" => 3584, - "3585" => 3585, - "3586" => 3586, - "3587" => 3587, - "3588" => 3588, - "3589" => 3589, - "3590" => 3590, - "3591" => 3591, - "3592" => 3592, - "3593" => 3593, - "3594" => 3594, - "3595" => 3595, - "3596" => 3596, - "3597" => 3597, - "3598" => 3598, - "3599" => 3599, - "3600" => 3600, - "3601" => 3601, - "3602" => 3602, - "3603" => 3603, - "3604" => 3604, - "3605" => 3605, - "3606" => 3606, - "3607" => 3607, - "3608" => 3608, - "3609" => 3609, - "3610" => 3610, - "3611" => 3611, - "3612" => 3612, - "3613" => 3613, - "3614" => 3614, - "3615" => 3615, - "3616" => 3616, - "3617" => 3617, - "3618" => 3618, - "3619" => 3619, - "3620" => 3620, - "3621" => 3621, - "3622" => 3622, - "3623" => 3623, - "3624" => 3624, - "3625" => 3625, - "3626" => 3626, - "3627" => 3627, - "3628" => 3628, - "3629" => 3629, - "3630" => 3630, - "3631" => 3631, - "3632" => 3632, - "3633" => 3633, - "3634" => 3634, - "3635" => 3635, - "3636" => 3636, - "3637" => 3637, - "3638" => 3638, - "3639" => 3639, - "3640" => 3640, - "3641" => 3641, - "3642" => 3642, - "3643" => 3643, - "3644" => 3644, - "3645" => 3645, - "3646" => 3646, - "3647" => 3647, - "3648" => 3648, - "3649" => 3649, - "3650" => 3650, - "3651" => 3651, - "3652" => 3652, - "3653" => 3653, - "3654" => 3654, - "3655" => 3655, - "3656" => 3656, - "3657" => 3657, - "3658" => 3658, - "3659" => 3659, - "3660" => 3660, - "3661" => 3661, - "3662" => 3662, - "3663" => 3663, - "3664" => 3664, - "3665" => 3665, - "3666" => 3666, - "3667" => 3667, - "3668" => 3668, - "3669" => 3669, - "3670" => 3670, - "3671" => 3671, - "3672" => 3672, - "3673" => 3673, - "3674" => 3674, - "3675" => 3675, - "3676" => 3676, - "3677" => 3677, - "3678" => 3678, - "3679" => 3679, - "3680" => 3680, - "3681" => 3681, - "3682" => 3682, - "3683" => 3683, - "3684" => 3684, - "3685" => 3685, - "3686" => 3686, - "3687" => 3687, - "3688" => 3688, - "3689" => 3689, - "3690" => 3690, - "3691" => 3691, - "3692" => 3692, - "3693" => 3693, - "3694" => 3694, - "3695" => 3695, - "3696" => 3696, - "3697" => 3697, - "3698" => 3698, - "3699" => 3699, - "3700" => 3700, - "3701" => 3701, - "3702" => 3702, - "3703" => 3703, - "3704" => 3704, - "3705" => 3705, - "3706" => 3706, - "3707" => 3707, - "3708" => 3708, - "3709" => 3709, - "3710" => 3710, - "3711" => 3711, - "3712" => 3712, - "3713" => 3713, - "3714" => 3714, - "3715" => 3715, - "3716" => 3716, - "3717" => 3717, - "3718" => 3718, - "3719" => 3719, - "3720" => 3720, - "3721" => 3721, - "3722" => 3722, - "3723" => 3723, - "3724" => 3724, - "3725" => 3725, - "3726" => 3726, - "3727" => 3727, - "3728" => 3728, - "3729" => 3729, - "3730" => 3730, - "3731" => 3731, - "3732" => 3732, - "3733" => 3733, - "3734" => 3734, - "3735" => 3735, - "3736" => 3736, - "3737" => 3737, - "3738" => 3738, - "3739" => 3739, - "3740" => 3740, - "3741" => 3741, - "3742" => 3742, - "3743" => 3743, - "3744" => 3744, - "3745" => 3745, - "3746" => 3746, - "3747" => 3747, - "3748" => 3748, - "3749" => 3749, - "3750" => 3750, - "3751" => 3751, - "3752" => 3752, - "3753" => 3753, - "3754" => 3754, - "3755" => 3755, - "3756" => 3756, - "3757" => 3757, - "3758" => 3758, - "3759" => 3759, - "3760" => 3760, - "3761" => 3761, - "3762" => 3762, - "3763" => 3763, - "3764" => 3764, - "3765" => 3765, - "3766" => 3766, - "3767" => 3767, - "3768" => 3768, - "3769" => 3769, - "3770" => 3770, - "3771" => 3771, - "3772" => 3772, - "3773" => 3773, - "3774" => 3774, - "3775" => 3775, - "3776" => 3776, - "3777" => 3777, - "3778" => 3778, - "3779" => 3779, - "3780" => 3780, - "3781" => 3781, - "3782" => 3782, - "3783" => 3783, - "3784" => 3784, - "3785" => 3785, - "3786" => 3786, - "3787" => 3787, - "3788" => 3788, - "3789" => 3789, - "3790" => 3790, - "3791" => 3791, - "3792" => 3792, - "3793" => 3793, - "3794" => 3794, - "3795" => 3795, - "3796" => 3796, - "3797" => 3797, - "3798" => 3798, - "3799" => 3799, - "3800" => 3800, - "3801" => 3801, - "3802" => 3802, - "3803" => 3803, - "3804" => 3804, - "3805" => 3805, - "3806" => 3806, - "3807" => 3807, - "3808" => 3808, - "3809" => 3809, - "3810" => 3810, - "3811" => 3811, - "3812" => 3812, - "3813" => 3813, - "3814" => 3814, - "3815" => 3815, - "3816" => 3816, - "3817" => 3817, - "3818" => 3818, - "3819" => 3819, - "3820" => 3820, - "3821" => 3821, - "3822" => 3822, - "3823" => 3823, - "3824" => 3824, - "3825" => 3825, - "3826" => 3826, - "3827" => 3827, - "3828" => 3828, - "3829" => 3829, - "3830" => 3830, - "3831" => 3831, - "3832" => 3832, - "3833" => 3833, - "3834" => 3834, - "3835" => 3835, - "3836" => 3836, - "3837" => 3837, - "3838" => 3838, - "3839" => 3839, - "3840" => 3840, - "3841" => 3841, - "3842" => 3842, - "3843" => 3843, - "3844" => 3844, - "3845" => 3845, - "3846" => 3846, - "3847" => 3847, - "3848" => 3848, - "3849" => 3849, - "3850" => 3850, - "3851" => 3851, - "3852" => 3852, - "3853" => 3853, - "3854" => 3854, - "3855" => 3855, - "3856" => 3856, - "3857" => 3857, - "3858" => 3858, - "3859" => 3859, - "3860" => 3860, - "3861" => 3861, - "3862" => 3862, - "3863" => 3863, - "3864" => 3864, - "3865" => 3865, - "3866" => 3866, - "3867" => 3867, - "3868" => 3868, - "3869" => 3869, - "3870" => 3870, - "3871" => 3871, - "3872" => 3872, - "3873" => 3873, - "3874" => 3874, - "3875" => 3875, - "3876" => 3876, - "3877" => 3877, - "3878" => 3878, - "3879" => 3879, - "3880" => 3880, - "3881" => 3881, - "3882" => 3882, - "3883" => 3883, - "3884" => 3884, - "3885" => 3885, - "3886" => 3886, - "3887" => 3887, - "3888" => 3888, - "3889" => 3889, - "3890" => 3890, - "3891" => 3891, - "3892" => 3892, - "3893" => 3893, - "3894" => 3894, - "3895" => 3895, - "3896" => 3896, - "3897" => 3897, - "3898" => 3898, - "3899" => 3899, - "3900" => 3900, - "3901" => 3901, - "3902" => 3902, - "3903" => 3903, - "3904" => 3904, - "3905" => 3905, - "3906" => 3906, - "3907" => 3907, - "3908" => 3908, - "3909" => 3909, - "3910" => 3910, - "3911" => 3911, - "3912" => 3912, - "3913" => 3913, - "3914" => 3914, - "3915" => 3915, - "3916" => 3916, - "3917" => 3917, - "3918" => 3918, - "3919" => 3919, - "3920" => 3920, - "3921" => 3921, - "3922" => 3922, - "3923" => 3923, - "3924" => 3924, - "3925" => 3925, - "3926" => 3926, - "3927" => 3927, - "3928" => 3928, - "3929" => 3929, - "3930" => 3930, - "3931" => 3931, - "3932" => 3932, - "3933" => 3933, - "3934" => 3934, - "3935" => 3935, - "3936" => 3936, - "3937" => 3937, - "3938" => 3938, - "3939" => 3939, - "3940" => 3940, - "3941" => 3941, - "3942" => 3942, - "3943" => 3943, - "3944" => 3944, - "3945" => 3945, - "3946" => 3946, - "3947" => 3947, - "3948" => 3948, - "3949" => 3949, - "3950" => 3950, - "3951" => 3951, - "3952" => 3952, - "3953" => 3953, - "3954" => 3954, - "3955" => 3955, - "3956" => 3956, - "3957" => 3957, - "3958" => 3958, - "3959" => 3959, - "3960" => 3960, - "3961" => 3961, - "3962" => 3962, - "3963" => 3963, - "3964" => 3964, - "3965" => 3965, - "3966" => 3966, - "3967" => 3967, - "3968" => 3968, - "3969" => 3969, - "3970" => 3970, - "3971" => 3971, - "3972" => 3972, - "3973" => 3973, - "3974" => 3974, - "3975" => 3975, - "3976" => 3976, - "3977" => 3977, - "3978" => 3978, - "3979" => 3979, - "3980" => 3980, - "3981" => 3981, - "3982" => 3982, - "3983" => 3983, - "3984" => 3984, - "3985" => 3985, - "3986" => 3986, - "3987" => 3987, - "3988" => 3988, - "3989" => 3989, - "3990" => 3990, - "3991" => 3991, - "3992" => 3992, - "3993" => 3993, - "3994" => 3994, - "3995" => 3995, - "3996" => 3996, - "3997" => 3997, - "3998" => 3998, - "3999" => 3999, - "4000" => 4000, - "4001" => 4001, - "4002" => 4002, - "4003" => 4003, - "4004" => 4004, - "4005" => 4005, - "4006" => 4006, - "4007" => 4007, - "4008" => 4008, - "4009" => 4009, - "4010" => 4010, - "4011" => 4011, - "4012" => 4012, - "4013" => 4013, - "4014" => 4014, - "4015" => 4015, - "4016" => 4016, - "4017" => 4017, - "4018" => 4018, - "4019" => 4019, - "4020" => 4020, - "4021" => 4021, - "4022" => 4022, - "4023" => 4023, - "4024" => 4024, - "4025" => 4025, - "4026" => 4026, - "4027" => 4027, - "4028" => 4028, - "4029" => 4029, - "4030" => 4030, - "4031" => 4031, - "4032" => 4032, - "4033" => 4033, - "4034" => 4034, - "4035" => 4035, - "4036" => 4036, - "4037" => 4037, - "4038" => 4038, - "4039" => 4039, - "4040" => 4040, - "4041" => 4041, - "4042" => 4042, - "4043" => 4043, - "4044" => 4044, - "4045" => 4045, - "4046" => 4046, - "4047" => 4047, - "4048" => 4048, - "4049" => 4049, - "4050" => 4050, - "4051" => 4051, - "4052" => 4052, - "4053" => 4053, - "4054" => 4054, - "4055" => 4055, - "4056" => 4056, - "4057" => 4057, - "4058" => 4058, - "4059" => 4059, - "4060" => 4060, - "4061" => 4061, - "4062" => 4062, - "4063" => 4063, - "4064" => 4064, - "4065" => 4065, - "4066" => 4066, - "4067" => 4067, - "4068" => 4068, - "4069" => 4069, - "4070" => 4070, - "4071" => 4071, - "4072" => 4072, - "4073" => 4073, - "4074" => 4074, - "4075" => 4075, - "4076" => 4076, - "4077" => 4077, - "4078" => 4078, - "4079" => 4079, - "4080" => 4080, - "4081" => 4081, - "4082" => 4082, - "4083" => 4083, - "4084" => 4084, - "4085" => 4085, - "4086" => 4086, - "4087" => 4087, - "4088" => 4088, - "4089" => 4089, - "4090" => 4090, - "4091" => 4091, - "4092" => 4092, - "4093" => 4093, - "4094" => 4094, - "4095" => 4095, - "4096" => 4096, - "4097" => 4097, - "4098" => 4098, - "4099" => 4099, - "4100" => 4100, - "4101" => 4101, - "4102" => 4102, - "4103" => 4103, - "4104" => 4104, - "4105" => 4105, - "4106" => 4106, - "4107" => 4107, - "4108" => 4108, - "4109" => 4109, - "4110" => 4110, - "4111" => 4111, - "4112" => 4112, - "4113" => 4113, - "4114" => 4114, - "4115" => 4115, - "4116" => 4116, - "4117" => 4117, - "4118" => 4118, - "4119" => 4119, - "4120" => 4120, - "4121" => 4121, - "4122" => 4122, - "4123" => 4123, - "4124" => 4124, - "4125" => 4125, - "4126" => 4126, - "4127" => 4127, - "4128" => 4128, - "4129" => 4129, - "4130" => 4130, - "4131" => 4131, - "4132" => 4132, - "4133" => 4133, - "4134" => 4134, - "4135" => 4135, - "4136" => 4136, - "4137" => 4137, - "4138" => 4138, - "4139" => 4139, - "4140" => 4140, - "4141" => 4141, - "4142" => 4142, - "4143" => 4143, - "4144" => 4144, - "4145" => 4145, - "4146" => 4146, - "4147" => 4147, - "4148" => 4148, - "4149" => 4149, - "4150" => 4150, - "4151" => 4151, - "4152" => 4152, - "4153" => 4153, - "4154" => 4154, - "4155" => 4155, - "4156" => 4156, - "4157" => 4157, - "4158" => 4158, - "4159" => 4159, - "4160" => 4160, - "4161" => 4161, - "4162" => 4162, - "4163" => 4163, - "4164" => 4164, - "4165" => 4165, - "4166" => 4166, - "4167" => 4167, - "4168" => 4168, - "4169" => 4169, - "4170" => 4170, - "4171" => 4171, - "4172" => 4172, - "4173" => 4173, - "4174" => 4174, - "4175" => 4175, - "4176" => 4176, - "4177" => 4177, - "4178" => 4178, - "4179" => 4179, - "4180" => 4180, - "4181" => 4181, - "4182" => 4182, - "4183" => 4183, - "4184" => 4184, - "4185" => 4185, - "4186" => 4186, - "4187" => 4187, - "4188" => 4188, - "4189" => 4189, - "4190" => 4190, - "4191" => 4191, - "4192" => 4192, - "4193" => 4193, - "4194" => 4194, - "4195" => 4195, - "4196" => 4196, - "4197" => 4197, - "4198" => 4198, - "4199" => 4199, - "4200" => 4200, - "4201" => 4201, - "4202" => 4202, - "4203" => 4203, - "4204" => 4204, - "4205" => 4205, - "4206" => 4206, - "4207" => 4207, - "4208" => 4208, - "4209" => 4209, - "4210" => 4210, - "4211" => 4211, - "4212" => 4212, - "4213" => 4213, - "4214" => 4214, - "4215" => 4215, - "4216" => 4216, - "4217" => 4217, - "4218" => 4218, - "4219" => 4219, - "4220" => 4220, - "4221" => 4221, - "4222" => 4222, - "4223" => 4223, - "4224" => 4224, - "4225" => 4225, - "4226" => 4226, - "4227" => 4227, - "4228" => 4228, - "4229" => 4229, - "4230" => 4230, - "4231" => 4231, - "4232" => 4232, - "4233" => 4233, - "4234" => 4234, - "4235" => 4235, - "4236" => 4236, - "4237" => 4237, - "4238" => 4238, - "4239" => 4239, - "4240" => 4240, - "4241" => 4241, - "4242" => 4242, - "4243" => 4243, - "4244" => 4244, - "4245" => 4245, - "4246" => 4246, - "4247" => 4247, - "4248" => 4248, - "4249" => 4249, - "4250" => 4250, - "4251" => 4251, - "4252" => 4252, - "4253" => 4253, - "4254" => 4254, - "4255" => 4255, - "4256" => 4256, - "4257" => 4257, - "4258" => 4258, - "4259" => 4259, - "4260" => 4260, - "4261" => 4261, - "4262" => 4262, - "4263" => 4263, - "4264" => 4264, - "4265" => 4265, - "4266" => 4266, - "4267" => 4267, - "4268" => 4268, - "4269" => 4269, - "4270" => 4270, - "4271" => 4271, - "4272" => 4272, - "4273" => 4273, - "4274" => 4274, - "4275" => 4275, - "4276" => 4276, - "4277" => 4277, - "4278" => 4278, - "4279" => 4279, - "4280" => 4280, - "4281" => 4281, - "4282" => 4282, - "4283" => 4283, - "4284" => 4284, - "4285" => 4285, - "4286" => 4286, - "4287" => 4287, - "4288" => 4288, - "4289" => 4289, - "4290" => 4290, - "4291" => 4291, - "4292" => 4292, - "4293" => 4293, - "4294" => 4294, - "4295" => 4295, - "4296" => 4296, - "4297" => 4297, - "4298" => 4298, - "4299" => 4299, - "4300" => 4300, - "4301" => 4301, - "4302" => 4302, - "4303" => 4303, - "4304" => 4304, - "4305" => 4305, - "4306" => 4306, - "4307" => 4307, - "4308" => 4308, - "4309" => 4309, - "4310" => 4310, - "4311" => 4311, - "4312" => 4312, - "4313" => 4313, - "4314" => 4314, - "4315" => 4315, - "4316" => 4316, - "4317" => 4317, - "4318" => 4318, - "4319" => 4319, - "4320" => 4320, - "4321" => 4321, - "4322" => 4322, - "4323" => 4323, - "4324" => 4324, - "4325" => 4325, - "4326" => 4326, - "4327" => 4327, - "4328" => 4328, - "4329" => 4329, - "4330" => 4330, - "4331" => 4331, - "4332" => 4332, - "4333" => 4333, - "4334" => 4334, - "4335" => 4335, - "4336" => 4336, - "4337" => 4337, - "4338" => 4338, - "4339" => 4339, - "4340" => 4340, - "4341" => 4341, - "4342" => 4342, - "4343" => 4343, - "4344" => 4344, - "4345" => 4345, - "4346" => 4346, - "4347" => 4347, - "4348" => 4348, - "4349" => 4349, - "4350" => 4350, - "4351" => 4351, - "4352" => 4352, - "4353" => 4353, - "4354" => 4354, - "4355" => 4355, - "4356" => 4356, - "4357" => 4357, - "4358" => 4358, - "4359" => 4359, - "4360" => 4360, - "4361" => 4361, - "4362" => 4362, - "4363" => 4363, - "4364" => 4364, - "4365" => 4365, - "4366" => 4366, - "4367" => 4367, - "4368" => 4368, - "4369" => 4369, - "4370" => 4370, - "4371" => 4371, - "4372" => 4372, - "4373" => 4373, - "4374" => 4374, - "4375" => 4375, - "4376" => 4376, - "4377" => 4377, - "4378" => 4378, - "4379" => 4379, - "4380" => 4380, - "4381" => 4381, - "4382" => 4382, - "4383" => 4383, - "4384" => 4384, - "4385" => 4385, - "4386" => 4386, - "4387" => 4387, - "4388" => 4388, - "4389" => 4389, - "4390" => 4390, - "4391" => 4391, - "4392" => 4392, - "4393" => 4393, - "4394" => 4394, - "4395" => 4395, - "4396" => 4396, - "4397" => 4397, - "4398" => 4398, - "4399" => 4399, - "4400" => 4400, - "4401" => 4401, - "4402" => 4402, - "4403" => 4403, - "4404" => 4404, - "4405" => 4405, - "4406" => 4406, - "4407" => 4407, - "4408" => 4408, - "4409" => 4409, - "4410" => 4410, - "4411" => 4411, - "4412" => 4412, - "4413" => 4413, - "4414" => 4414, - "4415" => 4415, - "4416" => 4416, - "4417" => 4417, - "4418" => 4418, - "4419" => 4419, - "4420" => 4420, - "4421" => 4421, - "4422" => 4422, - "4423" => 4423, - "4424" => 4424, - "4425" => 4425, - "4426" => 4426, - "4427" => 4427, - "4428" => 4428, - "4429" => 4429, - "4430" => 4430, - "4431" => 4431, - "4432" => 4432, - "4433" => 4433, - "4434" => 4434, - "4435" => 4435, - "4436" => 4436, - "4437" => 4437, - "4438" => 4438, - "4439" => 4439, - "4440" => 4440, - "4441" => 4441, - "4442" => 4442, - "4443" => 4443, - "4444" => 4444, - "4445" => 4445, - "4446" => 4446, - "4447" => 4447, - "4448" => 4448, - "4449" => 4449, - "4450" => 4450, - "4451" => 4451, - "4452" => 4452, - "4453" => 4453, - "4454" => 4454, - "4455" => 4455, - "4456" => 4456, - "4457" => 4457, - "4458" => 4458, - "4459" => 4459, - "4460" => 4460, - "4461" => 4461, - "4462" => 4462, - "4463" => 4463, - "4464" => 4464, - "4465" => 4465, - "4466" => 4466, - "4467" => 4467, - "4468" => 4468, - "4469" => 4469, - "4470" => 4470, - "4471" => 4471, - "4472" => 4472, - "4473" => 4473, - "4474" => 4474, - "4475" => 4475, - "4476" => 4476, - "4477" => 4477, - "4478" => 4478, - "4479" => 4479, - "4480" => 4480, - "4481" => 4481, - "4482" => 4482, - "4483" => 4483, - "4484" => 4484, - "4485" => 4485, - "4486" => 4486, - "4487" => 4487, - "4488" => 4488, - "4489" => 4489, - "4490" => 4490, - "4491" => 4491, - "4492" => 4492, - "4493" => 4493, - "4494" => 4494, - "4495" => 4495, - "4496" => 4496, - "4497" => 4497, - "4498" => 4498, - "4499" => 4499, - "4500" => 4500, - "4501" => 4501, - "4502" => 4502, - "4503" => 4503, - "4504" => 4504, - "4505" => 4505, - "4506" => 4506, - "4507" => 4507, - "4508" => 4508, - "4509" => 4509, - "4510" => 4510, - "4511" => 4511, - "4512" => 4512, - "4513" => 4513, - "4514" => 4514, - "4515" => 4515, - "4516" => 4516, - "4517" => 4517, - "4518" => 4518, - "4519" => 4519, - "4520" => 4520, - "4521" => 4521, - "4522" => 4522, - "4523" => 4523, - "4524" => 4524, - "4525" => 4525, - "4526" => 4526, - "4527" => 4527, - "4528" => 4528, - "4529" => 4529, - "4530" => 4530, - "4531" => 4531, - "4532" => 4532, - "4533" => 4533, - "4534" => 4534, - "4535" => 4535, - "4536" => 4536, - "4537" => 4537, - "4538" => 4538, - "4539" => 4539, - "4540" => 4540, - "4541" => 4541, - "4542" => 4542, - "4543" => 4543, - "4544" => 4544, - "4545" => 4545, - "4546" => 4546, - "4547" => 4547, - "4548" => 4548, - "4549" => 4549, - "4550" => 4550, - "4551" => 4551, - "4552" => 4552, - "4553" => 4553, - "4554" => 4554, - "4555" => 4555, - "4556" => 4556, - "4557" => 4557, - "4558" => 4558, - "4559" => 4559, - "4560" => 4560, - "4561" => 4561, - "4562" => 4562, - "4563" => 4563, - "4564" => 4564, - "4565" => 4565, - "4566" => 4566, - "4567" => 4567, - "4568" => 4568, - "4569" => 4569, - "4570" => 4570, - "4571" => 4571, - "4572" => 4572, - "4573" => 4573, - "4574" => 4574, - "4575" => 4575, - "4576" => 4576, - "4577" => 4577, - "4578" => 4578, - "4579" => 4579, - "4580" => 4580, - "4581" => 4581, - "4582" => 4582, - "4583" => 4583, - "4584" => 4584, - "4585" => 4585, - "4586" => 4586, - "4587" => 4587, - "4588" => 4588, - "4589" => 4589, - "4590" => 4590, - "4591" => 4591, - "4592" => 4592, - "4593" => 4593, - "4594" => 4594, - "4595" => 4595, - "4596" => 4596, - "4597" => 4597, - "4598" => 4598, - "4599" => 4599, - "4600" => 4600, - "4601" => 4601, - "4602" => 4602, - "4603" => 4603, - "4604" => 4604, - "4605" => 4605, - "4606" => 4606, - "4607" => 4607, - "4608" => 4608, - "4609" => 4609, - "4610" => 4610, - "4611" => 4611, - "4612" => 4612, - "4613" => 4613, - "4614" => 4614, - "4615" => 4615, - "4616" => 4616, - "4617" => 4617, - "4618" => 4618, - "4619" => 4619, - "4620" => 4620, - "4621" => 4621, - "4622" => 4622, - "4623" => 4623, - "4624" => 4624, - "4625" => 4625, - "4626" => 4626, - "4627" => 4627, - "4628" => 4628, - "4629" => 4629, - "4630" => 4630, - "4631" => 4631, - "4632" => 4632, - "4633" => 4633, - "4634" => 4634, - "4635" => 4635, - "4636" => 4636, - "4637" => 4637, - "4638" => 4638, - "4639" => 4639, - "4640" => 4640, - "4641" => 4641, - "4642" => 4642, - "4643" => 4643, - "4644" => 4644, - "4645" => 4645, - "4646" => 4646, - "4647" => 4647, - "4648" => 4648, - "4649" => 4649, - "4650" => 4650, - "4651" => 4651, - "4652" => 4652, - "4653" => 4653, - "4654" => 4654, - "4655" => 4655, - "4656" => 4656, - "4657" => 4657, - "4658" => 4658, - "4659" => 4659, - "4660" => 4660, - "4661" => 4661, - "4662" => 4662, - "4663" => 4663, - "4664" => 4664, - "4665" => 4665, - "4666" => 4666, - "4667" => 4667, - "4668" => 4668, - "4669" => 4669, - "4670" => 4670, - "4671" => 4671, - "4672" => 4672, - "4673" => 4673, - "4674" => 4674, - "4675" => 4675, - "4676" => 4676, - "4677" => 4677, - "4678" => 4678, - "4679" => 4679, - "4680" => 4680, - "4681" => 4681, - "4682" => 4682, - "4683" => 4683, - "4684" => 4684, - "4685" => 4685, - "4686" => 4686, - "4687" => 4687, - "4688" => 4688, - "4689" => 4689, - "4690" => 4690, - "4691" => 4691, - "4692" => 4692, - "4693" => 4693, - "4694" => 4694, - "4695" => 4695, - "4696" => 4696, - "4697" => 4697, - "4698" => 4698, - "4699" => 4699, - "4700" => 4700, - "4701" => 4701, - "4702" => 4702, - "4703" => 4703, - "4704" => 4704, - "4705" => 4705, - "4706" => 4706, - "4707" => 4707, - "4708" => 4708, - "4709" => 4709, - "4710" => 4710, - "4711" => 4711, - "4712" => 4712, - "4713" => 4713, - "4714" => 4714, - "4715" => 4715, - "4716" => 4716, - "4717" => 4717, - "4718" => 4718, - "4719" => 4719, - "4720" => 4720, - "4721" => 4721, - "4722" => 4722, - "4723" => 4723, - "4724" => 4724, - "4725" => 4725, - "4726" => 4726, - "4727" => 4727, - "4728" => 4728, - "4729" => 4729, - "4730" => 4730, - "4731" => 4731, - "4732" => 4732, - "4733" => 4733, - "4734" => 4734, - "4735" => 4735, - "4736" => 4736, - "4737" => 4737, - "4738" => 4738, - "4739" => 4739, - "4740" => 4740, - "4741" => 4741, - "4742" => 4742, - "4743" => 4743, - "4744" => 4744, - "4745" => 4745, - "4746" => 4746, - "4747" => 4747, - "4748" => 4748, - "4749" => 4749, - "4750" => 4750, - "4751" => 4751, - "4752" => 4752, - "4753" => 4753, - "4754" => 4754, - "4755" => 4755, - "4756" => 4756, - "4757" => 4757, - "4758" => 4758, - "4759" => 4759, - "4760" => 4760, - "4761" => 4761, - "4762" => 4762, - "4763" => 4763, - "4764" => 4764, - "4765" => 4765, - "4766" => 4766, - "4767" => 4767, - "4768" => 4768, - "4769" => 4769, - "4770" => 4770, - "4771" => 4771, - "4772" => 4772, - "4773" => 4773, - "4774" => 4774, - "4775" => 4775, - "4776" => 4776, - "4777" => 4777, - "4778" => 4778, - "4779" => 4779, - "4780" => 4780, - "4781" => 4781, - "4782" => 4782, - "4783" => 4783, - "4784" => 4784, - "4785" => 4785, - "4786" => 4786, - "4787" => 4787, - "4788" => 4788, - "4789" => 4789, - "4790" => 4790, - "4791" => 4791, - "4792" => 4792, - "4793" => 4793, - "4794" => 4794, - "4795" => 4795, - "4796" => 4796, - "4797" => 4797, - "4798" => 4798, - "4799" => 4799, - "4800" => 4800, - "4801" => 4801, - "4802" => 4802, - "4803" => 4803, - "4804" => 4804, - "4805" => 4805, - "4806" => 4806, - "4807" => 4807, - "4808" => 4808, - "4809" => 4809, - "4810" => 4810, - "4811" => 4811, - "4812" => 4812, - "4813" => 4813, - "4814" => 4814, - "4815" => 4815, - "4816" => 4816, - "4817" => 4817, - "4818" => 4818, - "4819" => 4819, - "4820" => 4820, - "4821" => 4821, - "4822" => 4822, - "4823" => 4823, - "4824" => 4824, - "4825" => 4825, - "4826" => 4826, - "4827" => 4827, - "4828" => 4828, - "4829" => 4829, - "4830" => 4830, - "4831" => 4831, - "4832" => 4832, - "4833" => 4833, - "4834" => 4834, - "4835" => 4835, - "4836" => 4836, - "4837" => 4837, - "4838" => 4838, - "4839" => 4839, - "4840" => 4840, - "4841" => 4841, - "4842" => 4842, - "4843" => 4843, - "4844" => 4844, - "4845" => 4845, - "4846" => 4846, - "4847" => 4847, - "4848" => 4848, - "4849" => 4849, - "4850" => 4850, - "4851" => 4851, - "4852" => 4852, - "4853" => 4853, - "4854" => 4854, - "4855" => 4855, - "4856" => 4856, - "4857" => 4857, - "4858" => 4858, - "4859" => 4859, - "4860" => 4860, - "4861" => 4861, - "4862" => 4862, - "4863" => 4863, - "4864" => 4864, - "4865" => 4865, - "4866" => 4866, - "4867" => 4867, - "4868" => 4868, - "4869" => 4869, - "4870" => 4870, - "4871" => 4871, - "4872" => 4872, - "4873" => 4873, - "4874" => 4874, - "4875" => 4875, - "4876" => 4876, - "4877" => 4877, - "4878" => 4878, - "4879" => 4879, - "4880" => 4880, - "4881" => 4881, - "4882" => 4882, - "4883" => 4883, - "4884" => 4884, - "4885" => 4885, - "4886" => 4886, - "4887" => 4887, - "4888" => 4888, - "4889" => 4889, - "4890" => 4890, - "4891" => 4891, - "4892" => 4892, - "4893" => 4893, - "4894" => 4894, - "4895" => 4895, - "4896" => 4896, - "4897" => 4897, - "4898" => 4898, - "4899" => 4899, - "4900" => 4900, - "4901" => 4901, - "4902" => 4902, - "4903" => 4903, - "4904" => 4904, - "4905" => 4905, - "4906" => 4906, - "4907" => 4907, - "4908" => 4908, - "4909" => 4909, - "4910" => 4910, - "4911" => 4911, - "4912" => 4912, - "4913" => 4913, - "4914" => 4914, - "4915" => 4915, - "4916" => 4916, - "4917" => 4917, - "4918" => 4918, - "4919" => 4919, - "4920" => 4920, - "4921" => 4921, - "4922" => 4922, - "4923" => 4923, - "4924" => 4924, - "4925" => 4925, - "4926" => 4926, - "4927" => 4927, - "4928" => 4928, - "4929" => 4929, - "4930" => 4930, - "4931" => 4931, - "4932" => 4932, - "4933" => 4933, - "4934" => 4934, - "4935" => 4935, - "4936" => 4936, - "4937" => 4937, - "4938" => 4938, - "4939" => 4939, - "4940" => 4940, - "4941" => 4941, - "4942" => 4942, - "4943" => 4943, - "4944" => 4944, - "4945" => 4945, - "4946" => 4946, - "4947" => 4947, - "4948" => 4948, - "4949" => 4949, - "4950" => 4950, - "4951" => 4951, - "4952" => 4952, - "4953" => 4953, - "4954" => 4954, - "4955" => 4955, - "4956" => 4956, - "4957" => 4957, - "4958" => 4958, - "4959" => 4959, - "4960" => 4960, - "4961" => 4961, - "4962" => 4962, - "4963" => 4963, - "4964" => 4964, - "4965" => 4965, - "4966" => 4966, - "4967" => 4967, - "4968" => 4968, - "4969" => 4969, - "4970" => 4970, - "4971" => 4971, - "4972" => 4972, - "4973" => 4973, - "4974" => 4974, - "4975" => 4975, - "4976" => 4976, - "4977" => 4977, - "4978" => 4978, - "4979" => 4979, - "4980" => 4980, - "4981" => 4981, - "4982" => 4982, - "4983" => 4983, - "4984" => 4984, - "4985" => 4985, - "4986" => 4986, - "4987" => 4987, - "4988" => 4988, - "4989" => 4989, - "4990" => 4990, - "4991" => 4991, - "4992" => 4992, - "4993" => 4993, - "4994" => 4994, - "4995" => 4995, - "4996" => 4996, - "4997" => 4997, - "4998" => 4998, - "4999" => 4999, - "5000" => 5000, - "5001" => 5001, - "5002" => 5002, - "5003" => 5003, - "5004" => 5004, - "5005" => 5005, - "5006" => 5006, - "5007" => 5007, - "5008" => 5008, - "5009" => 5009, - "5010" => 5010, - "5011" => 5011, - "5012" => 5012, - "5013" => 5013, - "5014" => 5014, - "5015" => 5015, - "5016" => 5016, - "5017" => 5017, - "5018" => 5018, - "5019" => 5019, - "5020" => 5020, - "5021" => 5021, - "5022" => 5022, - "5023" => 5023, - "5024" => 5024, - "5025" => 5025, - "5026" => 5026, - "5027" => 5027, - "5028" => 5028, - "5029" => 5029, - "5030" => 5030, - "5031" => 5031, - "5032" => 5032, - "5033" => 5033, - "5034" => 5034, - "5035" => 5035, - "5036" => 5036, - "5037" => 5037, - "5038" => 5038, - "5039" => 5039, - "5040" => 5040, - "5041" => 5041, - "5042" => 5042, - "5043" => 5043, - "5044" => 5044, - "5045" => 5045, - "5046" => 5046, - "5047" => 5047, - "5048" => 5048, - "5049" => 5049, - "5050" => 5050, - "5051" => 5051, - "5052" => 5052, - "5053" => 5053, - "5054" => 5054, - "5055" => 5055, - "5056" => 5056, - "5057" => 5057, - "5058" => 5058, - "5059" => 5059, - "5060" => 5060, - "5061" => 5061, - "5062" => 5062, - "5063" => 5063, - "5064" => 5064, - "5065" => 5065, - "5066" => 5066, - "5067" => 5067, - "5068" => 5068, - "5069" => 5069, - "5070" => 5070, - "5071" => 5071, - "5072" => 5072, - "5073" => 5073, - "5074" => 5074, - "5075" => 5075, - "5076" => 5076, - "5077" => 5077, - "5078" => 5078, - "5079" => 5079, - "5080" => 5080, - "5081" => 5081, - "5082" => 5082, - "5083" => 5083, - "5084" => 5084, - "5085" => 5085, - "5086" => 5086, - "5087" => 5087, - "5088" => 5088, - "5089" => 5089, - "5090" => 5090, - "5091" => 5091, - "5092" => 5092, - "5093" => 5093, - "5094" => 5094, - "5095" => 5095, - "5096" => 5096, - "5097" => 5097, - "5098" => 5098, - "5099" => 5099, - "5100" => 5100, - "5101" => 5101, - "5102" => 5102, - "5103" => 5103, - "5104" => 5104, - "5105" => 5105, - "5106" => 5106, - "5107" => 5107, - "5108" => 5108, - "5109" => 5109, - "5110" => 5110, - "5111" => 5111, - "5112" => 5112, - "5113" => 5113, - "5114" => 5114, - "5115" => 5115, - "5116" => 5116, - "5117" => 5117, - "5118" => 5118, - "5119" => 5119, - "5120" => 5120, - "5121" => 5121, - "5122" => 5122, - "5123" => 5123, - "5124" => 5124, - "5125" => 5125, - "5126" => 5126, - "5127" => 5127, - "5128" => 5128, - "5129" => 5129, - "5130" => 5130, - "5131" => 5131, - "5132" => 5132, - "5133" => 5133, - "5134" => 5134, - "5135" => 5135, - "5136" => 5136, - "5137" => 5137, - "5138" => 5138, - "5139" => 5139, - "5140" => 5140, - "5141" => 5141, - "5142" => 5142, - "5143" => 5143, - "5144" => 5144, - "5145" => 5145, - "5146" => 5146, - "5147" => 5147, - "5148" => 5148, - "5149" => 5149, - "5150" => 5150, - "5151" => 5151, - "5152" => 5152, - "5153" => 5153, - "5154" => 5154, - "5155" => 5155, - "5156" => 5156, - "5157" => 5157, - "5158" => 5158, - "5159" => 5159, - "5160" => 5160, - "5161" => 5161, - "5162" => 5162, - "5163" => 5163, - "5164" => 5164, - "5165" => 5165, - "5166" => 5166, - "5167" => 5167, - "5168" => 5168, - "5169" => 5169, - "5170" => 5170, - "5171" => 5171, - "5172" => 5172, - "5173" => 5173, - "5174" => 5174, - "5175" => 5175, - "5176" => 5176, - "5177" => 5177, - "5178" => 5178, - "5179" => 5179, - "5180" => 5180, - "5181" => 5181, - "5182" => 5182, - "5183" => 5183, - "5184" => 5184, - "5185" => 5185, - "5186" => 5186, - "5187" => 5187, - "5188" => 5188, - "5189" => 5189, - "5190" => 5190, - "5191" => 5191, - "5192" => 5192, - "5193" => 5193, - "5194" => 5194, - "5195" => 5195, - "5196" => 5196, - "5197" => 5197, - "5198" => 5198, - _ => 5199, - } -} diff --git a/tests/ui/issues/issue-74564-if-expr-stack-overflow.rs b/tests/ui/issues/issue-74564-if-expr-stack-overflow.rs deleted file mode 100644 index c0ffed27e6fb..000000000000 --- a/tests/ui/issues/issue-74564-if-expr-stack-overflow.rs +++ /dev/null @@ -1,10419 +0,0 @@ -//@ build-pass -// ignore-tidy-filelength -#![crate_type = "rlib"] - -fn banana(v: &str) -> u32 { - if v == "1" { - 1 - } else if v == "2" { - 2 - } else if v == "3" { - 3 - } else if v == "4" { - 4 - } else if v == "5" { - 5 - } else if v == "6" { - 6 - } else if v == "7" { - 7 - } else if v == "8" { - 8 - } else if v == "9" { - 9 - } else if v == "10" { - 10 - } else if v == "11" { - 11 - } else if v == "12" { - 12 - } else if v == "13" { - 13 - } else if v == "14" { - 14 - } else if v == "15" { - 15 - } else if v == "16" { - 16 - } else if v == "17" { - 17 - } else if v == "18" { - 18 - } else if v == "19" { - 19 - } else if v == "20" { - 20 - } else if v == "21" { - 21 - } else if v == "22" { - 22 - } else if v == "23" { - 23 - } else if v == "24" { - 24 - } else if v == "25" { - 25 - } else if v == "26" { - 26 - } else if v == "27" { - 27 - } else if v == "28" { - 28 - } else if v == "29" { - 29 - } else if v == "30" { - 30 - } else if v == "31" { - 31 - } else if v == "32" { - 32 - } else if v == "33" { - 33 - } else if v == "34" { - 34 - } else if v == "35" { - 35 - } else if v == "36" { - 36 - } else if v == "37" { - 37 - } else if v == "38" { - 38 - } else if v == "39" { - 39 - } else if v == "40" { - 40 - } else if v == "41" { - 41 - } else if v == "42" { - 42 - } else if v == "43" { - 43 - } else if v == "44" { - 44 - } else if v == "45" { - 45 - } else if v == "46" { - 46 - } else if v == "47" { - 47 - } else if v == "48" { - 48 - } else if v == "49" { - 49 - } else if v == "50" { - 50 - } else if v == "51" { - 51 - } else if v == "52" { - 52 - } else if v == "53" { - 53 - } else if v == "54" { - 54 - } else if v == "55" { - 55 - } else if v == "56" { - 56 - } else if v == "57" { - 57 - } else if v == "58" { - 58 - } else if v == "59" { - 59 - } else if v == "60" { - 60 - } else if v == "61" { - 61 - } else if v == "62" { - 62 - } else if v == "63" { - 63 - } else if v == "64" { - 64 - } else if v == "65" { - 65 - } else if v == "66" { - 66 - } else if v == "67" { - 67 - } else if v == "68" { - 68 - } else if v == "69" { - 69 - } else if v == "70" { - 70 - } else if v == "71" { - 71 - } else if v == "72" { - 72 - } else if v == "73" { - 73 - } else if v == "74" { - 74 - } else if v == "75" { - 75 - } else if v == "76" { - 76 - } else if v == "77" { - 77 - } else if v == "78" { - 78 - } else if v == "79" { - 79 - } else if v == "80" { - 80 - } else if v == "81" { - 81 - } else if v == "82" { - 82 - } else if v == "83" { - 83 - } else if v == "84" { - 84 - } else if v == "85" { - 85 - } else if v == "86" { - 86 - } else if v == "87" { - 87 - } else if v == "88" { - 88 - } else if v == "89" { - 89 - } else if v == "90" { - 90 - } else if v == "91" { - 91 - } else if v == "92" { - 92 - } else if v == "93" { - 93 - } else if v == "94" { - 94 - } else if v == "95" { - 95 - } else if v == "96" { - 96 - } else if v == "97" { - 97 - } else if v == "98" { - 98 - } else if v == "99" { - 99 - } else if v == "100" { - 100 - } else if v == "101" { - 101 - } else if v == "102" { - 102 - } else if v == "103" { - 103 - } else if v == "104" { - 104 - } else if v == "105" { - 105 - } else if v == "106" { - 106 - } else if v == "107" { - 107 - } else if v == "108" { - 108 - } else if v == "109" { - 109 - } else if v == "110" { - 110 - } else if v == "111" { - 111 - } else if v == "112" { - 112 - } else if v == "113" { - 113 - } else if v == "114" { - 114 - } else if v == "115" { - 115 - } else if v == "116" { - 116 - } else if v == "117" { - 117 - } else if v == "118" { - 118 - } else if v == "119" { - 119 - } else if v == "120" { - 120 - } else if v == "121" { - 121 - } else if v == "122" { - 122 - } else if v == "123" { - 123 - } else if v == "124" { - 124 - } else if v == "125" { - 125 - } else if v == "126" { - 126 - } else if v == "127" { - 127 - } else if v == "128" { - 128 - } else if v == "129" { - 129 - } else if v == "130" { - 130 - } else if v == "131" { - 131 - } else if v == "132" { - 132 - } else if v == "133" { - 133 - } else if v == "134" { - 134 - } else if v == "135" { - 135 - } else if v == "136" { - 136 - } else if v == "137" { - 137 - } else if v == "138" { - 138 - } else if v == "139" { - 139 - } else if v == "140" { - 140 - } else if v == "141" { - 141 - } else if v == "142" { - 142 - } else if v == "143" { - 143 - } else if v == "144" { - 144 - } else if v == "145" { - 145 - } else if v == "146" { - 146 - } else if v == "147" { - 147 - } else if v == "148" { - 148 - } else if v == "149" { - 149 - } else if v == "150" { - 150 - } else if v == "151" { - 151 - } else if v == "152" { - 152 - } else if v == "153" { - 153 - } else if v == "154" { - 154 - } else if v == "155" { - 155 - } else if v == "156" { - 156 - } else if v == "157" { - 157 - } else if v == "158" { - 158 - } else if v == "159" { - 159 - } else if v == "160" { - 160 - } else if v == "161" { - 161 - } else if v == "162" { - 162 - } else if v == "163" { - 163 - } else if v == "164" { - 164 - } else if v == "165" { - 165 - } else if v == "166" { - 166 - } else if v == "167" { - 167 - } else if v == "168" { - 168 - } else if v == "169" { - 169 - } else if v == "170" { - 170 - } else if v == "171" { - 171 - } else if v == "172" { - 172 - } else if v == "173" { - 173 - } else if v == "174" { - 174 - } else if v == "175" { - 175 - } else if v == "176" { - 176 - } else if v == "177" { - 177 - } else if v == "178" { - 178 - } else if v == "179" { - 179 - } else if v == "180" { - 180 - } else if v == "181" { - 181 - } else if v == "182" { - 182 - } else if v == "183" { - 183 - } else if v == "184" { - 184 - } else if v == "185" { - 185 - } else if v == "186" { - 186 - } else if v == "187" { - 187 - } else if v == "188" { - 188 - } else if v == "189" { - 189 - } else if v == "190" { - 190 - } else if v == "191" { - 191 - } else if v == "192" { - 192 - } else if v == "193" { - 193 - } else if v == "194" { - 194 - } else if v == "195" { - 195 - } else if v == "196" { - 196 - } else if v == "197" { - 197 - } else if v == "198" { - 198 - } else if v == "199" { - 199 - } else if v == "200" { - 200 - } else if v == "201" { - 201 - } else if v == "202" { - 202 - } else if v == "203" { - 203 - } else if v == "204" { - 204 - } else if v == "205" { - 205 - } else if v == "206" { - 206 - } else if v == "207" { - 207 - } else if v == "208" { - 208 - } else if v == "209" { - 209 - } else if v == "210" { - 210 - } else if v == "211" { - 211 - } else if v == "212" { - 212 - } else if v == "213" { - 213 - } else if v == "214" { - 214 - } else if v == "215" { - 215 - } else if v == "216" { - 216 - } else if v == "217" { - 217 - } else if v == "218" { - 218 - } else if v == "219" { - 219 - } else if v == "220" { - 220 - } else if v == "221" { - 221 - } else if v == "222" { - 222 - } else if v == "223" { - 223 - } else if v == "224" { - 224 - } else if v == "225" { - 225 - } else if v == "226" { - 226 - } else if v == "227" { - 227 - } else if v == "228" { - 228 - } else if v == "229" { - 229 - } else if v == "230" { - 230 - } else if v == "231" { - 231 - } else if v == "232" { - 232 - } else if v == "233" { - 233 - } else if v == "234" { - 234 - } else if v == "235" { - 235 - } else if v == "236" { - 236 - } else if v == "237" { - 237 - } else if v == "238" { - 238 - } else if v == "239" { - 239 - } else if v == "240" { - 240 - } else if v == "241" { - 241 - } else if v == "242" { - 242 - } else if v == "243" { - 243 - } else if v == "244" { - 244 - } else if v == "245" { - 245 - } else if v == "246" { - 246 - } else if v == "247" { - 247 - } else if v == "248" { - 248 - } else if v == "249" { - 249 - } else if v == "250" { - 250 - } else if v == "251" { - 251 - } else if v == "252" { - 252 - } else if v == "253" { - 253 - } else if v == "254" { - 254 - } else if v == "255" { - 255 - } else if v == "256" { - 256 - } else if v == "257" { - 257 - } else if v == "258" { - 258 - } else if v == "259" { - 259 - } else if v == "260" { - 260 - } else if v == "261" { - 261 - } else if v == "262" { - 262 - } else if v == "263" { - 263 - } else if v == "264" { - 264 - } else if v == "265" { - 265 - } else if v == "266" { - 266 - } else if v == "267" { - 267 - } else if v == "268" { - 268 - } else if v == "269" { - 269 - } else if v == "270" { - 270 - } else if v == "271" { - 271 - } else if v == "272" { - 272 - } else if v == "273" { - 273 - } else if v == "274" { - 274 - } else if v == "275" { - 275 - } else if v == "276" { - 276 - } else if v == "277" { - 277 - } else if v == "278" { - 278 - } else if v == "279" { - 279 - } else if v == "280" { - 280 - } else if v == "281" { - 281 - } else if v == "282" { - 282 - } else if v == "283" { - 283 - } else if v == "284" { - 284 - } else if v == "285" { - 285 - } else if v == "286" { - 286 - } else if v == "287" { - 287 - } else if v == "288" { - 288 - } else if v == "289" { - 289 - } else if v == "290" { - 290 - } else if v == "291" { - 291 - } else if v == "292" { - 292 - } else if v == "293" { - 293 - } else if v == "294" { - 294 - } else if v == "295" { - 295 - } else if v == "296" { - 296 - } else if v == "297" { - 297 - } else if v == "298" { - 298 - } else if v == "299" { - 299 - } else if v == "300" { - 300 - } else if v == "301" { - 301 - } else if v == "302" { - 302 - } else if v == "303" { - 303 - } else if v == "304" { - 304 - } else if v == "305" { - 305 - } else if v == "306" { - 306 - } else if v == "307" { - 307 - } else if v == "308" { - 308 - } else if v == "309" { - 309 - } else if v == "310" { - 310 - } else if v == "311" { - 311 - } else if v == "312" { - 312 - } else if v == "313" { - 313 - } else if v == "314" { - 314 - } else if v == "315" { - 315 - } else if v == "316" { - 316 - } else if v == "317" { - 317 - } else if v == "318" { - 318 - } else if v == "319" { - 319 - } else if v == "320" { - 320 - } else if v == "321" { - 321 - } else if v == "322" { - 322 - } else if v == "323" { - 323 - } else if v == "324" { - 324 - } else if v == "325" { - 325 - } else if v == "326" { - 326 - } else if v == "327" { - 327 - } else if v == "328" { - 328 - } else if v == "329" { - 329 - } else if v == "330" { - 330 - } else if v == "331" { - 331 - } else if v == "332" { - 332 - } else if v == "333" { - 333 - } else if v == "334" { - 334 - } else if v == "335" { - 335 - } else if v == "336" { - 336 - } else if v == "337" { - 337 - } else if v == "338" { - 338 - } else if v == "339" { - 339 - } else if v == "340" { - 340 - } else if v == "341" { - 341 - } else if v == "342" { - 342 - } else if v == "343" { - 343 - } else if v == "344" { - 344 - } else if v == "345" { - 345 - } else if v == "346" { - 346 - } else if v == "347" { - 347 - } else if v == "348" { - 348 - } else if v == "349" { - 349 - } else if v == "350" { - 350 - } else if v == "351" { - 351 - } else if v == "352" { - 352 - } else if v == "353" { - 353 - } else if v == "354" { - 354 - } else if v == "355" { - 355 - } else if v == "356" { - 356 - } else if v == "357" { - 357 - } else if v == "358" { - 358 - } else if v == "359" { - 359 - } else if v == "360" { - 360 - } else if v == "361" { - 361 - } else if v == "362" { - 362 - } else if v == "363" { - 363 - } else if v == "364" { - 364 - } else if v == "365" { - 365 - } else if v == "366" { - 366 - } else if v == "367" { - 367 - } else if v == "368" { - 368 - } else if v == "369" { - 369 - } else if v == "370" { - 370 - } else if v == "371" { - 371 - } else if v == "372" { - 372 - } else if v == "373" { - 373 - } else if v == "374" { - 374 - } else if v == "375" { - 375 - } else if v == "376" { - 376 - } else if v == "377" { - 377 - } else if v == "378" { - 378 - } else if v == "379" { - 379 - } else if v == "380" { - 380 - } else if v == "381" { - 381 - } else if v == "382" { - 382 - } else if v == "383" { - 383 - } else if v == "384" { - 384 - } else if v == "385" { - 385 - } else if v == "386" { - 386 - } else if v == "387" { - 387 - } else if v == "388" { - 388 - } else if v == "389" { - 389 - } else if v == "390" { - 390 - } else if v == "391" { - 391 - } else if v == "392" { - 392 - } else if v == "393" { - 393 - } else if v == "394" { - 394 - } else if v == "395" { - 395 - } else if v == "396" { - 396 - } else if v == "397" { - 397 - } else if v == "398" { - 398 - } else if v == "399" { - 399 - } else if v == "400" { - 400 - } else if v == "401" { - 401 - } else if v == "402" { - 402 - } else if v == "403" { - 403 - } else if v == "404" { - 404 - } else if v == "405" { - 405 - } else if v == "406" { - 406 - } else if v == "407" { - 407 - } else if v == "408" { - 408 - } else if v == "409" { - 409 - } else if v == "410" { - 410 - } else if v == "411" { - 411 - } else if v == "412" { - 412 - } else if v == "413" { - 413 - } else if v == "414" { - 414 - } else if v == "415" { - 415 - } else if v == "416" { - 416 - } else if v == "417" { - 417 - } else if v == "418" { - 418 - } else if v == "419" { - 419 - } else if v == "420" { - 420 - } else if v == "421" { - 421 - } else if v == "422" { - 422 - } else if v == "423" { - 423 - } else if v == "424" { - 424 - } else if v == "425" { - 425 - } else if v == "426" { - 426 - } else if v == "427" { - 427 - } else if v == "428" { - 428 - } else if v == "429" { - 429 - } else if v == "430" { - 430 - } else if v == "431" { - 431 - } else if v == "432" { - 432 - } else if v == "433" { - 433 - } else if v == "434" { - 434 - } else if v == "435" { - 435 - } else if v == "436" { - 436 - } else if v == "437" { - 437 - } else if v == "438" { - 438 - } else if v == "439" { - 439 - } else if v == "440" { - 440 - } else if v == "441" { - 441 - } else if v == "442" { - 442 - } else if v == "443" { - 443 - } else if v == "444" { - 444 - } else if v == "445" { - 445 - } else if v == "446" { - 446 - } else if v == "447" { - 447 - } else if v == "448" { - 448 - } else if v == "449" { - 449 - } else if v == "450" { - 450 - } else if v == "451" { - 451 - } else if v == "452" { - 452 - } else if v == "453" { - 453 - } else if v == "454" { - 454 - } else if v == "455" { - 455 - } else if v == "456" { - 456 - } else if v == "457" { - 457 - } else if v == "458" { - 458 - } else if v == "459" { - 459 - } else if v == "460" { - 460 - } else if v == "461" { - 461 - } else if v == "462" { - 462 - } else if v == "463" { - 463 - } else if v == "464" { - 464 - } else if v == "465" { - 465 - } else if v == "466" { - 466 - } else if v == "467" { - 467 - } else if v == "468" { - 468 - } else if v == "469" { - 469 - } else if v == "470" { - 470 - } else if v == "471" { - 471 - } else if v == "472" { - 472 - } else if v == "473" { - 473 - } else if v == "474" { - 474 - } else if v == "475" { - 475 - } else if v == "476" { - 476 - } else if v == "477" { - 477 - } else if v == "478" { - 478 - } else if v == "479" { - 479 - } else if v == "480" { - 480 - } else if v == "481" { - 481 - } else if v == "482" { - 482 - } else if v == "483" { - 483 - } else if v == "484" { - 484 - } else if v == "485" { - 485 - } else if v == "486" { - 486 - } else if v == "487" { - 487 - } else if v == "488" { - 488 - } else if v == "489" { - 489 - } else if v == "490" { - 490 - } else if v == "491" { - 491 - } else if v == "492" { - 492 - } else if v == "493" { - 493 - } else if v == "494" { - 494 - } else if v == "495" { - 495 - } else if v == "496" { - 496 - } else if v == "497" { - 497 - } else if v == "498" { - 498 - } else if v == "499" { - 499 - } else if v == "500" { - 500 - } else if v == "501" { - 501 - } else if v == "502" { - 502 - } else if v == "503" { - 503 - } else if v == "504" { - 504 - } else if v == "505" { - 505 - } else if v == "506" { - 506 - } else if v == "507" { - 507 - } else if v == "508" { - 508 - } else if v == "509" { - 509 - } else if v == "510" { - 510 - } else if v == "511" { - 511 - } else if v == "512" { - 512 - } else if v == "513" { - 513 - } else if v == "514" { - 514 - } else if v == "515" { - 515 - } else if v == "516" { - 516 - } else if v == "517" { - 517 - } else if v == "518" { - 518 - } else if v == "519" { - 519 - } else if v == "520" { - 520 - } else if v == "521" { - 521 - } else if v == "522" { - 522 - } else if v == "523" { - 523 - } else if v == "524" { - 524 - } else if v == "525" { - 525 - } else if v == "526" { - 526 - } else if v == "527" { - 527 - } else if v == "528" { - 528 - } else if v == "529" { - 529 - } else if v == "530" { - 530 - } else if v == "531" { - 531 - } else if v == "532" { - 532 - } else if v == "533" { - 533 - } else if v == "534" { - 534 - } else if v == "535" { - 535 - } else if v == "536" { - 536 - } else if v == "537" { - 537 - } else if v == "538" { - 538 - } else if v == "539" { - 539 - } else if v == "540" { - 540 - } else if v == "541" { - 541 - } else if v == "542" { - 542 - } else if v == "543" { - 543 - } else if v == "544" { - 544 - } else if v == "545" { - 545 - } else if v == "546" { - 546 - } else if v == "547" { - 547 - } else if v == "548" { - 548 - } else if v == "549" { - 549 - } else if v == "550" { - 550 - } else if v == "551" { - 551 - } else if v == "552" { - 552 - } else if v == "553" { - 553 - } else if v == "554" { - 554 - } else if v == "555" { - 555 - } else if v == "556" { - 556 - } else if v == "557" { - 557 - } else if v == "558" { - 558 - } else if v == "559" { - 559 - } else if v == "560" { - 560 - } else if v == "561" { - 561 - } else if v == "562" { - 562 - } else if v == "563" { - 563 - } else if v == "564" { - 564 - } else if v == "565" { - 565 - } else if v == "566" { - 566 - } else if v == "567" { - 567 - } else if v == "568" { - 568 - } else if v == "569" { - 569 - } else if v == "570" { - 570 - } else if v == "571" { - 571 - } else if v == "572" { - 572 - } else if v == "573" { - 573 - } else if v == "574" { - 574 - } else if v == "575" { - 575 - } else if v == "576" { - 576 - } else if v == "577" { - 577 - } else if v == "578" { - 578 - } else if v == "579" { - 579 - } else if v == "580" { - 580 - } else if v == "581" { - 581 - } else if v == "582" { - 582 - } else if v == "583" { - 583 - } else if v == "584" { - 584 - } else if v == "585" { - 585 - } else if v == "586" { - 586 - } else if v == "587" { - 587 - } else if v == "588" { - 588 - } else if v == "589" { - 589 - } else if v == "590" { - 590 - } else if v == "591" { - 591 - } else if v == "592" { - 592 - } else if v == "593" { - 593 - } else if v == "594" { - 594 - } else if v == "595" { - 595 - } else if v == "596" { - 596 - } else if v == "597" { - 597 - } else if v == "598" { - 598 - } else if v == "599" { - 599 - } else if v == "600" { - 600 - } else if v == "601" { - 601 - } else if v == "602" { - 602 - } else if v == "603" { - 603 - } else if v == "604" { - 604 - } else if v == "605" { - 605 - } else if v == "606" { - 606 - } else if v == "607" { - 607 - } else if v == "608" { - 608 - } else if v == "609" { - 609 - } else if v == "610" { - 610 - } else if v == "611" { - 611 - } else if v == "612" { - 612 - } else if v == "613" { - 613 - } else if v == "614" { - 614 - } else if v == "615" { - 615 - } else if v == "616" { - 616 - } else if v == "617" { - 617 - } else if v == "618" { - 618 - } else if v == "619" { - 619 - } else if v == "620" { - 620 - } else if v == "621" { - 621 - } else if v == "622" { - 622 - } else if v == "623" { - 623 - } else if v == "624" { - 624 - } else if v == "625" { - 625 - } else if v == "626" { - 626 - } else if v == "627" { - 627 - } else if v == "628" { - 628 - } else if v == "629" { - 629 - } else if v == "630" { - 630 - } else if v == "631" { - 631 - } else if v == "632" { - 632 - } else if v == "633" { - 633 - } else if v == "634" { - 634 - } else if v == "635" { - 635 - } else if v == "636" { - 636 - } else if v == "637" { - 637 - } else if v == "638" { - 638 - } else if v == "639" { - 639 - } else if v == "640" { - 640 - } else if v == "641" { - 641 - } else if v == "642" { - 642 - } else if v == "643" { - 643 - } else if v == "644" { - 644 - } else if v == "645" { - 645 - } else if v == "646" { - 646 - } else if v == "647" { - 647 - } else if v == "648" { - 648 - } else if v == "649" { - 649 - } else if v == "650" { - 650 - } else if v == "651" { - 651 - } else if v == "652" { - 652 - } else if v == "653" { - 653 - } else if v == "654" { - 654 - } else if v == "655" { - 655 - } else if v == "656" { - 656 - } else if v == "657" { - 657 - } else if v == "658" { - 658 - } else if v == "659" { - 659 - } else if v == "660" { - 660 - } else if v == "661" { - 661 - } else if v == "662" { - 662 - } else if v == "663" { - 663 - } else if v == "664" { - 664 - } else if v == "665" { - 665 - } else if v == "666" { - 666 - } else if v == "667" { - 667 - } else if v == "668" { - 668 - } else if v == "669" { - 669 - } else if v == "670" { - 670 - } else if v == "671" { - 671 - } else if v == "672" { - 672 - } else if v == "673" { - 673 - } else if v == "674" { - 674 - } else if v == "675" { - 675 - } else if v == "676" { - 676 - } else if v == "677" { - 677 - } else if v == "678" { - 678 - } else if v == "679" { - 679 - } else if v == "680" { - 680 - } else if v == "681" { - 681 - } else if v == "682" { - 682 - } else if v == "683" { - 683 - } else if v == "684" { - 684 - } else if v == "685" { - 685 - } else if v == "686" { - 686 - } else if v == "687" { - 687 - } else if v == "688" { - 688 - } else if v == "689" { - 689 - } else if v == "690" { - 690 - } else if v == "691" { - 691 - } else if v == "692" { - 692 - } else if v == "693" { - 693 - } else if v == "694" { - 694 - } else if v == "695" { - 695 - } else if v == "696" { - 696 - } else if v == "697" { - 697 - } else if v == "698" { - 698 - } else if v == "699" { - 699 - } else if v == "700" { - 700 - } else if v == "701" { - 701 - } else if v == "702" { - 702 - } else if v == "703" { - 703 - } else if v == "704" { - 704 - } else if v == "705" { - 705 - } else if v == "706" { - 706 - } else if v == "707" { - 707 - } else if v == "708" { - 708 - } else if v == "709" { - 709 - } else if v == "710" { - 710 - } else if v == "711" { - 711 - } else if v == "712" { - 712 - } else if v == "713" { - 713 - } else if v == "714" { - 714 - } else if v == "715" { - 715 - } else if v == "716" { - 716 - } else if v == "717" { - 717 - } else if v == "718" { - 718 - } else if v == "719" { - 719 - } else if v == "720" { - 720 - } else if v == "721" { - 721 - } else if v == "722" { - 722 - } else if v == "723" { - 723 - } else if v == "724" { - 724 - } else if v == "725" { - 725 - } else if v == "726" { - 726 - } else if v == "727" { - 727 - } else if v == "728" { - 728 - } else if v == "729" { - 729 - } else if v == "730" { - 730 - } else if v == "731" { - 731 - } else if v == "732" { - 732 - } else if v == "733" { - 733 - } else if v == "734" { - 734 - } else if v == "735" { - 735 - } else if v == "736" { - 736 - } else if v == "737" { - 737 - } else if v == "738" { - 738 - } else if v == "739" { - 739 - } else if v == "740" { - 740 - } else if v == "741" { - 741 - } else if v == "742" { - 742 - } else if v == "743" { - 743 - } else if v == "744" { - 744 - } else if v == "745" { - 745 - } else if v == "746" { - 746 - } else if v == "747" { - 747 - } else if v == "748" { - 748 - } else if v == "749" { - 749 - } else if v == "750" { - 750 - } else if v == "751" { - 751 - } else if v == "752" { - 752 - } else if v == "753" { - 753 - } else if v == "754" { - 754 - } else if v == "755" { - 755 - } else if v == "756" { - 756 - } else if v == "757" { - 757 - } else if v == "758" { - 758 - } else if v == "759" { - 759 - } else if v == "760" { - 760 - } else if v == "761" { - 761 - } else if v == "762" { - 762 - } else if v == "763" { - 763 - } else if v == "764" { - 764 - } else if v == "765" { - 765 - } else if v == "766" { - 766 - } else if v == "767" { - 767 - } else if v == "768" { - 768 - } else if v == "769" { - 769 - } else if v == "770" { - 770 - } else if v == "771" { - 771 - } else if v == "772" { - 772 - } else if v == "773" { - 773 - } else if v == "774" { - 774 - } else if v == "775" { - 775 - } else if v == "776" { - 776 - } else if v == "777" { - 777 - } else if v == "778" { - 778 - } else if v == "779" { - 779 - } else if v == "780" { - 780 - } else if v == "781" { - 781 - } else if v == "782" { - 782 - } else if v == "783" { - 783 - } else if v == "784" { - 784 - } else if v == "785" { - 785 - } else if v == "786" { - 786 - } else if v == "787" { - 787 - } else if v == "788" { - 788 - } else if v == "789" { - 789 - } else if v == "790" { - 790 - } else if v == "791" { - 791 - } else if v == "792" { - 792 - } else if v == "793" { - 793 - } else if v == "794" { - 794 - } else if v == "795" { - 795 - } else if v == "796" { - 796 - } else if v == "797" { - 797 - } else if v == "798" { - 798 - } else if v == "799" { - 799 - } else if v == "800" { - 800 - } else if v == "801" { - 801 - } else if v == "802" { - 802 - } else if v == "803" { - 803 - } else if v == "804" { - 804 - } else if v == "805" { - 805 - } else if v == "806" { - 806 - } else if v == "807" { - 807 - } else if v == "808" { - 808 - } else if v == "809" { - 809 - } else if v == "810" { - 810 - } else if v == "811" { - 811 - } else if v == "812" { - 812 - } else if v == "813" { - 813 - } else if v == "814" { - 814 - } else if v == "815" { - 815 - } else if v == "816" { - 816 - } else if v == "817" { - 817 - } else if v == "818" { - 818 - } else if v == "819" { - 819 - } else if v == "820" { - 820 - } else if v == "821" { - 821 - } else if v == "822" { - 822 - } else if v == "823" { - 823 - } else if v == "824" { - 824 - } else if v == "825" { - 825 - } else if v == "826" { - 826 - } else if v == "827" { - 827 - } else if v == "828" { - 828 - } else if v == "829" { - 829 - } else if v == "830" { - 830 - } else if v == "831" { - 831 - } else if v == "832" { - 832 - } else if v == "833" { - 833 - } else if v == "834" { - 834 - } else if v == "835" { - 835 - } else if v == "836" { - 836 - } else if v == "837" { - 837 - } else if v == "838" { - 838 - } else if v == "839" { - 839 - } else if v == "840" { - 840 - } else if v == "841" { - 841 - } else if v == "842" { - 842 - } else if v == "843" { - 843 - } else if v == "844" { - 844 - } else if v == "845" { - 845 - } else if v == "846" { - 846 - } else if v == "847" { - 847 - } else if v == "848" { - 848 - } else if v == "849" { - 849 - } else if v == "850" { - 850 - } else if v == "851" { - 851 - } else if v == "852" { - 852 - } else if v == "853" { - 853 - } else if v == "854" { - 854 - } else if v == "855" { - 855 - } else if v == "856" { - 856 - } else if v == "857" { - 857 - } else if v == "858" { - 858 - } else if v == "859" { - 859 - } else if v == "860" { - 860 - } else if v == "861" { - 861 - } else if v == "862" { - 862 - } else if v == "863" { - 863 - } else if v == "864" { - 864 - } else if v == "865" { - 865 - } else if v == "866" { - 866 - } else if v == "867" { - 867 - } else if v == "868" { - 868 - } else if v == "869" { - 869 - } else if v == "870" { - 870 - } else if v == "871" { - 871 - } else if v == "872" { - 872 - } else if v == "873" { - 873 - } else if v == "874" { - 874 - } else if v == "875" { - 875 - } else if v == "876" { - 876 - } else if v == "877" { - 877 - } else if v == "878" { - 878 - } else if v == "879" { - 879 - } else if v == "880" { - 880 - } else if v == "881" { - 881 - } else if v == "882" { - 882 - } else if v == "883" { - 883 - } else if v == "884" { - 884 - } else if v == "885" { - 885 - } else if v == "886" { - 886 - } else if v == "887" { - 887 - } else if v == "888" { - 888 - } else if v == "889" { - 889 - } else if v == "890" { - 890 - } else if v == "891" { - 891 - } else if v == "892" { - 892 - } else if v == "893" { - 893 - } else if v == "894" { - 894 - } else if v == "895" { - 895 - } else if v == "896" { - 896 - } else if v == "897" { - 897 - } else if v == "898" { - 898 - } else if v == "899" { - 899 - } else if v == "900" { - 900 - } else if v == "901" { - 901 - } else if v == "902" { - 902 - } else if v == "903" { - 903 - } else if v == "904" { - 904 - } else if v == "905" { - 905 - } else if v == "906" { - 906 - } else if v == "907" { - 907 - } else if v == "908" { - 908 - } else if v == "909" { - 909 - } else if v == "910" { - 910 - } else if v == "911" { - 911 - } else if v == "912" { - 912 - } else if v == "913" { - 913 - } else if v == "914" { - 914 - } else if v == "915" { - 915 - } else if v == "916" { - 916 - } else if v == "917" { - 917 - } else if v == "918" { - 918 - } else if v == "919" { - 919 - } else if v == "920" { - 920 - } else if v == "921" { - 921 - } else if v == "922" { - 922 - } else if v == "923" { - 923 - } else if v == "924" { - 924 - } else if v == "925" { - 925 - } else if v == "926" { - 926 - } else if v == "927" { - 927 - } else if v == "928" { - 928 - } else if v == "929" { - 929 - } else if v == "930" { - 930 - } else if v == "931" { - 931 - } else if v == "932" { - 932 - } else if v == "933" { - 933 - } else if v == "934" { - 934 - } else if v == "935" { - 935 - } else if v == "936" { - 936 - } else if v == "937" { - 937 - } else if v == "938" { - 938 - } else if v == "939" { - 939 - } else if v == "940" { - 940 - } else if v == "941" { - 941 - } else if v == "942" { - 942 - } else if v == "943" { - 943 - } else if v == "944" { - 944 - } else if v == "945" { - 945 - } else if v == "946" { - 946 - } else if v == "947" { - 947 - } else if v == "948" { - 948 - } else if v == "949" { - 949 - } else if v == "950" { - 950 - } else if v == "951" { - 951 - } else if v == "952" { - 952 - } else if v == "953" { - 953 - } else if v == "954" { - 954 - } else if v == "955" { - 955 - } else if v == "956" { - 956 - } else if v == "957" { - 957 - } else if v == "958" { - 958 - } else if v == "959" { - 959 - } else if v == "960" { - 960 - } else if v == "961" { - 961 - } else if v == "962" { - 962 - } else if v == "963" { - 963 - } else if v == "964" { - 964 - } else if v == "965" { - 965 - } else if v == "966" { - 966 - } else if v == "967" { - 967 - } else if v == "968" { - 968 - } else if v == "969" { - 969 - } else if v == "970" { - 970 - } else if v == "971" { - 971 - } else if v == "972" { - 972 - } else if v == "973" { - 973 - } else if v == "974" { - 974 - } else if v == "975" { - 975 - } else if v == "976" { - 976 - } else if v == "977" { - 977 - } else if v == "978" { - 978 - } else if v == "979" { - 979 - } else if v == "980" { - 980 - } else if v == "981" { - 981 - } else if v == "982" { - 982 - } else if v == "983" { - 983 - } else if v == "984" { - 984 - } else if v == "985" { - 985 - } else if v == "986" { - 986 - } else if v == "987" { - 987 - } else if v == "988" { - 988 - } else if v == "989" { - 989 - } else if v == "990" { - 990 - } else if v == "991" { - 991 - } else if v == "992" { - 992 - } else if v == "993" { - 993 - } else if v == "994" { - 994 - } else if v == "995" { - 995 - } else if v == "996" { - 996 - } else if v == "997" { - 997 - } else if v == "998" { - 998 - } else if v == "999" { - 999 - } else if v == "1000" { - 1000 - } else if v == "1001" { - 1001 - } else if v == "1002" { - 1002 - } else if v == "1003" { - 1003 - } else if v == "1004" { - 1004 - } else if v == "1005" { - 1005 - } else if v == "1006" { - 1006 - } else if v == "1007" { - 1007 - } else if v == "1008" { - 1008 - } else if v == "1009" { - 1009 - } else if v == "1010" { - 1010 - } else if v == "1011" { - 1011 - } else if v == "1012" { - 1012 - } else if v == "1013" { - 1013 - } else if v == "1014" { - 1014 - } else if v == "1015" { - 1015 - } else if v == "1016" { - 1016 - } else if v == "1017" { - 1017 - } else if v == "1018" { - 1018 - } else if v == "1019" { - 1019 - } else if v == "1020" { - 1020 - } else if v == "1021" { - 1021 - } else if v == "1022" { - 1022 - } else if v == "1023" { - 1023 - } else if v == "1024" { - 1024 - } else if v == "1025" { - 1025 - } else if v == "1026" { - 1026 - } else if v == "1027" { - 1027 - } else if v == "1028" { - 1028 - } else if v == "1029" { - 1029 - } else if v == "1030" { - 1030 - } else if v == "1031" { - 1031 - } else if v == "1032" { - 1032 - } else if v == "1033" { - 1033 - } else if v == "1034" { - 1034 - } else if v == "1035" { - 1035 - } else if v == "1036" { - 1036 - } else if v == "1037" { - 1037 - } else if v == "1038" { - 1038 - } else if v == "1039" { - 1039 - } else if v == "1040" { - 1040 - } else if v == "1041" { - 1041 - } else if v == "1042" { - 1042 - } else if v == "1043" { - 1043 - } else if v == "1044" { - 1044 - } else if v == "1045" { - 1045 - } else if v == "1046" { - 1046 - } else if v == "1047" { - 1047 - } else if v == "1048" { - 1048 - } else if v == "1049" { - 1049 - } else if v == "1050" { - 1050 - } else if v == "1051" { - 1051 - } else if v == "1052" { - 1052 - } else if v == "1053" { - 1053 - } else if v == "1054" { - 1054 - } else if v == "1055" { - 1055 - } else if v == "1056" { - 1056 - } else if v == "1057" { - 1057 - } else if v == "1058" { - 1058 - } else if v == "1059" { - 1059 - } else if v == "1060" { - 1060 - } else if v == "1061" { - 1061 - } else if v == "1062" { - 1062 - } else if v == "1063" { - 1063 - } else if v == "1064" { - 1064 - } else if v == "1065" { - 1065 - } else if v == "1066" { - 1066 - } else if v == "1067" { - 1067 - } else if v == "1068" { - 1068 - } else if v == "1069" { - 1069 - } else if v == "1070" { - 1070 - } else if v == "1071" { - 1071 - } else if v == "1072" { - 1072 - } else if v == "1073" { - 1073 - } else if v == "1074" { - 1074 - } else if v == "1075" { - 1075 - } else if v == "1076" { - 1076 - } else if v == "1077" { - 1077 - } else if v == "1078" { - 1078 - } else if v == "1079" { - 1079 - } else if v == "1080" { - 1080 - } else if v == "1081" { - 1081 - } else if v == "1082" { - 1082 - } else if v == "1083" { - 1083 - } else if v == "1084" { - 1084 - } else if v == "1085" { - 1085 - } else if v == "1086" { - 1086 - } else if v == "1087" { - 1087 - } else if v == "1088" { - 1088 - } else if v == "1089" { - 1089 - } else if v == "1090" { - 1090 - } else if v == "1091" { - 1091 - } else if v == "1092" { - 1092 - } else if v == "1093" { - 1093 - } else if v == "1094" { - 1094 - } else if v == "1095" { - 1095 - } else if v == "1096" { - 1096 - } else if v == "1097" { - 1097 - } else if v == "1098" { - 1098 - } else if v == "1099" { - 1099 - } else if v == "1100" { - 1100 - } else if v == "1101" { - 1101 - } else if v == "1102" { - 1102 - } else if v == "1103" { - 1103 - } else if v == "1104" { - 1104 - } else if v == "1105" { - 1105 - } else if v == "1106" { - 1106 - } else if v == "1107" { - 1107 - } else if v == "1108" { - 1108 - } else if v == "1109" { - 1109 - } else if v == "1110" { - 1110 - } else if v == "1111" { - 1111 - } else if v == "1112" { - 1112 - } else if v == "1113" { - 1113 - } else if v == "1114" { - 1114 - } else if v == "1115" { - 1115 - } else if v == "1116" { - 1116 - } else if v == "1117" { - 1117 - } else if v == "1118" { - 1118 - } else if v == "1119" { - 1119 - } else if v == "1120" { - 1120 - } else if v == "1121" { - 1121 - } else if v == "1122" { - 1122 - } else if v == "1123" { - 1123 - } else if v == "1124" { - 1124 - } else if v == "1125" { - 1125 - } else if v == "1126" { - 1126 - } else if v == "1127" { - 1127 - } else if v == "1128" { - 1128 - } else if v == "1129" { - 1129 - } else if v == "1130" { - 1130 - } else if v == "1131" { - 1131 - } else if v == "1132" { - 1132 - } else if v == "1133" { - 1133 - } else if v == "1134" { - 1134 - } else if v == "1135" { - 1135 - } else if v == "1136" { - 1136 - } else if v == "1137" { - 1137 - } else if v == "1138" { - 1138 - } else if v == "1139" { - 1139 - } else if v == "1140" { - 1140 - } else if v == "1141" { - 1141 - } else if v == "1142" { - 1142 - } else if v == "1143" { - 1143 - } else if v == "1144" { - 1144 - } else if v == "1145" { - 1145 - } else if v == "1146" { - 1146 - } else if v == "1147" { - 1147 - } else if v == "1148" { - 1148 - } else if v == "1149" { - 1149 - } else if v == "1150" { - 1150 - } else if v == "1151" { - 1151 - } else if v == "1152" { - 1152 - } else if v == "1153" { - 1153 - } else if v == "1154" { - 1154 - } else if v == "1155" { - 1155 - } else if v == "1156" { - 1156 - } else if v == "1157" { - 1157 - } else if v == "1158" { - 1158 - } else if v == "1159" { - 1159 - } else if v == "1160" { - 1160 - } else if v == "1161" { - 1161 - } else if v == "1162" { - 1162 - } else if v == "1163" { - 1163 - } else if v == "1164" { - 1164 - } else if v == "1165" { - 1165 - } else if v == "1166" { - 1166 - } else if v == "1167" { - 1167 - } else if v == "1168" { - 1168 - } else if v == "1169" { - 1169 - } else if v == "1170" { - 1170 - } else if v == "1171" { - 1171 - } else if v == "1172" { - 1172 - } else if v == "1173" { - 1173 - } else if v == "1174" { - 1174 - } else if v == "1175" { - 1175 - } else if v == "1176" { - 1176 - } else if v == "1177" { - 1177 - } else if v == "1178" { - 1178 - } else if v == "1179" { - 1179 - } else if v == "1180" { - 1180 - } else if v == "1181" { - 1181 - } else if v == "1182" { - 1182 - } else if v == "1183" { - 1183 - } else if v == "1184" { - 1184 - } else if v == "1185" { - 1185 - } else if v == "1186" { - 1186 - } else if v == "1187" { - 1187 - } else if v == "1188" { - 1188 - } else if v == "1189" { - 1189 - } else if v == "1190" { - 1190 - } else if v == "1191" { - 1191 - } else if v == "1192" { - 1192 - } else if v == "1193" { - 1193 - } else if v == "1194" { - 1194 - } else if v == "1195" { - 1195 - } else if v == "1196" { - 1196 - } else if v == "1197" { - 1197 - } else if v == "1198" { - 1198 - } else if v == "1199" { - 1199 - } else if v == "1200" { - 1200 - } else if v == "1201" { - 1201 - } else if v == "1202" { - 1202 - } else if v == "1203" { - 1203 - } else if v == "1204" { - 1204 - } else if v == "1205" { - 1205 - } else if v == "1206" { - 1206 - } else if v == "1207" { - 1207 - } else if v == "1208" { - 1208 - } else if v == "1209" { - 1209 - } else if v == "1210" { - 1210 - } else if v == "1211" { - 1211 - } else if v == "1212" { - 1212 - } else if v == "1213" { - 1213 - } else if v == "1214" { - 1214 - } else if v == "1215" { - 1215 - } else if v == "1216" { - 1216 - } else if v == "1217" { - 1217 - } else if v == "1218" { - 1218 - } else if v == "1219" { - 1219 - } else if v == "1220" { - 1220 - } else if v == "1221" { - 1221 - } else if v == "1222" { - 1222 - } else if v == "1223" { - 1223 - } else if v == "1224" { - 1224 - } else if v == "1225" { - 1225 - } else if v == "1226" { - 1226 - } else if v == "1227" { - 1227 - } else if v == "1228" { - 1228 - } else if v == "1229" { - 1229 - } else if v == "1230" { - 1230 - } else if v == "1231" { - 1231 - } else if v == "1232" { - 1232 - } else if v == "1233" { - 1233 - } else if v == "1234" { - 1234 - } else if v == "1235" { - 1235 - } else if v == "1236" { - 1236 - } else if v == "1237" { - 1237 - } else if v == "1238" { - 1238 - } else if v == "1239" { - 1239 - } else if v == "1240" { - 1240 - } else if v == "1241" { - 1241 - } else if v == "1242" { - 1242 - } else if v == "1243" { - 1243 - } else if v == "1244" { - 1244 - } else if v == "1245" { - 1245 - } else if v == "1246" { - 1246 - } else if v == "1247" { - 1247 - } else if v == "1248" { - 1248 - } else if v == "1249" { - 1249 - } else if v == "1250" { - 1250 - } else if v == "1251" { - 1251 - } else if v == "1252" { - 1252 - } else if v == "1253" { - 1253 - } else if v == "1254" { - 1254 - } else if v == "1255" { - 1255 - } else if v == "1256" { - 1256 - } else if v == "1257" { - 1257 - } else if v == "1258" { - 1258 - } else if v == "1259" { - 1259 - } else if v == "1260" { - 1260 - } else if v == "1261" { - 1261 - } else if v == "1262" { - 1262 - } else if v == "1263" { - 1263 - } else if v == "1264" { - 1264 - } else if v == "1265" { - 1265 - } else if v == "1266" { - 1266 - } else if v == "1267" { - 1267 - } else if v == "1268" { - 1268 - } else if v == "1269" { - 1269 - } else if v == "1270" { - 1270 - } else if v == "1271" { - 1271 - } else if v == "1272" { - 1272 - } else if v == "1273" { - 1273 - } else if v == "1274" { - 1274 - } else if v == "1275" { - 1275 - } else if v == "1276" { - 1276 - } else if v == "1277" { - 1277 - } else if v == "1278" { - 1278 - } else if v == "1279" { - 1279 - } else if v == "1280" { - 1280 - } else if v == "1281" { - 1281 - } else if v == "1282" { - 1282 - } else if v == "1283" { - 1283 - } else if v == "1284" { - 1284 - } else if v == "1285" { - 1285 - } else if v == "1286" { - 1286 - } else if v == "1287" { - 1287 - } else if v == "1288" { - 1288 - } else if v == "1289" { - 1289 - } else if v == "1290" { - 1290 - } else if v == "1291" { - 1291 - } else if v == "1292" { - 1292 - } else if v == "1293" { - 1293 - } else if v == "1294" { - 1294 - } else if v == "1295" { - 1295 - } else if v == "1296" { - 1296 - } else if v == "1297" { - 1297 - } else if v == "1298" { - 1298 - } else if v == "1299" { - 1299 - } else if v == "1300" { - 1300 - } else if v == "1301" { - 1301 - } else if v == "1302" { - 1302 - } else if v == "1303" { - 1303 - } else if v == "1304" { - 1304 - } else if v == "1305" { - 1305 - } else if v == "1306" { - 1306 - } else if v == "1307" { - 1307 - } else if v == "1308" { - 1308 - } else if v == "1309" { - 1309 - } else if v == "1310" { - 1310 - } else if v == "1311" { - 1311 - } else if v == "1312" { - 1312 - } else if v == "1313" { - 1313 - } else if v == "1314" { - 1314 - } else if v == "1315" { - 1315 - } else if v == "1316" { - 1316 - } else if v == "1317" { - 1317 - } else if v == "1318" { - 1318 - } else if v == "1319" { - 1319 - } else if v == "1320" { - 1320 - } else if v == "1321" { - 1321 - } else if v == "1322" { - 1322 - } else if v == "1323" { - 1323 - } else if v == "1324" { - 1324 - } else if v == "1325" { - 1325 - } else if v == "1326" { - 1326 - } else if v == "1327" { - 1327 - } else if v == "1328" { - 1328 - } else if v == "1329" { - 1329 - } else if v == "1330" { - 1330 - } else if v == "1331" { - 1331 - } else if v == "1332" { - 1332 - } else if v == "1333" { - 1333 - } else if v == "1334" { - 1334 - } else if v == "1335" { - 1335 - } else if v == "1336" { - 1336 - } else if v == "1337" { - 1337 - } else if v == "1338" { - 1338 - } else if v == "1339" { - 1339 - } else if v == "1340" { - 1340 - } else if v == "1341" { - 1341 - } else if v == "1342" { - 1342 - } else if v == "1343" { - 1343 - } else if v == "1344" { - 1344 - } else if v == "1345" { - 1345 - } else if v == "1346" { - 1346 - } else if v == "1347" { - 1347 - } else if v == "1348" { - 1348 - } else if v == "1349" { - 1349 - } else if v == "1350" { - 1350 - } else if v == "1351" { - 1351 - } else if v == "1352" { - 1352 - } else if v == "1353" { - 1353 - } else if v == "1354" { - 1354 - } else if v == "1355" { - 1355 - } else if v == "1356" { - 1356 - } else if v == "1357" { - 1357 - } else if v == "1358" { - 1358 - } else if v == "1359" { - 1359 - } else if v == "1360" { - 1360 - } else if v == "1361" { - 1361 - } else if v == "1362" { - 1362 - } else if v == "1363" { - 1363 - } else if v == "1364" { - 1364 - } else if v == "1365" { - 1365 - } else if v == "1366" { - 1366 - } else if v == "1367" { - 1367 - } else if v == "1368" { - 1368 - } else if v == "1369" { - 1369 - } else if v == "1370" { - 1370 - } else if v == "1371" { - 1371 - } else if v == "1372" { - 1372 - } else if v == "1373" { - 1373 - } else if v == "1374" { - 1374 - } else if v == "1375" { - 1375 - } else if v == "1376" { - 1376 - } else if v == "1377" { - 1377 - } else if v == "1378" { - 1378 - } else if v == "1379" { - 1379 - } else if v == "1380" { - 1380 - } else if v == "1381" { - 1381 - } else if v == "1382" { - 1382 - } else if v == "1383" { - 1383 - } else if v == "1384" { - 1384 - } else if v == "1385" { - 1385 - } else if v == "1386" { - 1386 - } else if v == "1387" { - 1387 - } else if v == "1388" { - 1388 - } else if v == "1389" { - 1389 - } else if v == "1390" { - 1390 - } else if v == "1391" { - 1391 - } else if v == "1392" { - 1392 - } else if v == "1393" { - 1393 - } else if v == "1394" { - 1394 - } else if v == "1395" { - 1395 - } else if v == "1396" { - 1396 - } else if v == "1397" { - 1397 - } else if v == "1398" { - 1398 - } else if v == "1399" { - 1399 - } else if v == "1400" { - 1400 - } else if v == "1401" { - 1401 - } else if v == "1402" { - 1402 - } else if v == "1403" { - 1403 - } else if v == "1404" { - 1404 - } else if v == "1405" { - 1405 - } else if v == "1406" { - 1406 - } else if v == "1407" { - 1407 - } else if v == "1408" { - 1408 - } else if v == "1409" { - 1409 - } else if v == "1410" { - 1410 - } else if v == "1411" { - 1411 - } else if v == "1412" { - 1412 - } else if v == "1413" { - 1413 - } else if v == "1414" { - 1414 - } else if v == "1415" { - 1415 - } else if v == "1416" { - 1416 - } else if v == "1417" { - 1417 - } else if v == "1418" { - 1418 - } else if v == "1419" { - 1419 - } else if v == "1420" { - 1420 - } else if v == "1421" { - 1421 - } else if v == "1422" { - 1422 - } else if v == "1423" { - 1423 - } else if v == "1424" { - 1424 - } else if v == "1425" { - 1425 - } else if v == "1426" { - 1426 - } else if v == "1427" { - 1427 - } else if v == "1428" { - 1428 - } else if v == "1429" { - 1429 - } else if v == "1430" { - 1430 - } else if v == "1431" { - 1431 - } else if v == "1432" { - 1432 - } else if v == "1433" { - 1433 - } else if v == "1434" { - 1434 - } else if v == "1435" { - 1435 - } else if v == "1436" { - 1436 - } else if v == "1437" { - 1437 - } else if v == "1438" { - 1438 - } else if v == "1439" { - 1439 - } else if v == "1440" { - 1440 - } else if v == "1441" { - 1441 - } else if v == "1442" { - 1442 - } else if v == "1443" { - 1443 - } else if v == "1444" { - 1444 - } else if v == "1445" { - 1445 - } else if v == "1446" { - 1446 - } else if v == "1447" { - 1447 - } else if v == "1448" { - 1448 - } else if v == "1449" { - 1449 - } else if v == "1450" { - 1450 - } else if v == "1451" { - 1451 - } else if v == "1452" { - 1452 - } else if v == "1453" { - 1453 - } else if v == "1454" { - 1454 - } else if v == "1455" { - 1455 - } else if v == "1456" { - 1456 - } else if v == "1457" { - 1457 - } else if v == "1458" { - 1458 - } else if v == "1459" { - 1459 - } else if v == "1460" { - 1460 - } else if v == "1461" { - 1461 - } else if v == "1462" { - 1462 - } else if v == "1463" { - 1463 - } else if v == "1464" { - 1464 - } else if v == "1465" { - 1465 - } else if v == "1466" { - 1466 - } else if v == "1467" { - 1467 - } else if v == "1468" { - 1468 - } else if v == "1469" { - 1469 - } else if v == "1470" { - 1470 - } else if v == "1471" { - 1471 - } else if v == "1472" { - 1472 - } else if v == "1473" { - 1473 - } else if v == "1474" { - 1474 - } else if v == "1475" { - 1475 - } else if v == "1476" { - 1476 - } else if v == "1477" { - 1477 - } else if v == "1478" { - 1478 - } else if v == "1479" { - 1479 - } else if v == "1480" { - 1480 - } else if v == "1481" { - 1481 - } else if v == "1482" { - 1482 - } else if v == "1483" { - 1483 - } else if v == "1484" { - 1484 - } else if v == "1485" { - 1485 - } else if v == "1486" { - 1486 - } else if v == "1487" { - 1487 - } else if v == "1488" { - 1488 - } else if v == "1489" { - 1489 - } else if v == "1490" { - 1490 - } else if v == "1491" { - 1491 - } else if v == "1492" { - 1492 - } else if v == "1493" { - 1493 - } else if v == "1494" { - 1494 - } else if v == "1495" { - 1495 - } else if v == "1496" { - 1496 - } else if v == "1497" { - 1497 - } else if v == "1498" { - 1498 - } else if v == "1499" { - 1499 - } else if v == "1500" { - 1500 - } else if v == "1501" { - 1501 - } else if v == "1502" { - 1502 - } else if v == "1503" { - 1503 - } else if v == "1504" { - 1504 - } else if v == "1505" { - 1505 - } else if v == "1506" { - 1506 - } else if v == "1507" { - 1507 - } else if v == "1508" { - 1508 - } else if v == "1509" { - 1509 - } else if v == "1510" { - 1510 - } else if v == "1511" { - 1511 - } else if v == "1512" { - 1512 - } else if v == "1513" { - 1513 - } else if v == "1514" { - 1514 - } else if v == "1515" { - 1515 - } else if v == "1516" { - 1516 - } else if v == "1517" { - 1517 - } else if v == "1518" { - 1518 - } else if v == "1519" { - 1519 - } else if v == "1520" { - 1520 - } else if v == "1521" { - 1521 - } else if v == "1522" { - 1522 - } else if v == "1523" { - 1523 - } else if v == "1524" { - 1524 - } else if v == "1525" { - 1525 - } else if v == "1526" { - 1526 - } else if v == "1527" { - 1527 - } else if v == "1528" { - 1528 - } else if v == "1529" { - 1529 - } else if v == "1530" { - 1530 - } else if v == "1531" { - 1531 - } else if v == "1532" { - 1532 - } else if v == "1533" { - 1533 - } else if v == "1534" { - 1534 - } else if v == "1535" { - 1535 - } else if v == "1536" { - 1536 - } else if v == "1537" { - 1537 - } else if v == "1538" { - 1538 - } else if v == "1539" { - 1539 - } else if v == "1540" { - 1540 - } else if v == "1541" { - 1541 - } else if v == "1542" { - 1542 - } else if v == "1543" { - 1543 - } else if v == "1544" { - 1544 - } else if v == "1545" { - 1545 - } else if v == "1546" { - 1546 - } else if v == "1547" { - 1547 - } else if v == "1548" { - 1548 - } else if v == "1549" { - 1549 - } else if v == "1550" { - 1550 - } else if v == "1551" { - 1551 - } else if v == "1552" { - 1552 - } else if v == "1553" { - 1553 - } else if v == "1554" { - 1554 - } else if v == "1555" { - 1555 - } else if v == "1556" { - 1556 - } else if v == "1557" { - 1557 - } else if v == "1558" { - 1558 - } else if v == "1559" { - 1559 - } else if v == "1560" { - 1560 - } else if v == "1561" { - 1561 - } else if v == "1562" { - 1562 - } else if v == "1563" { - 1563 - } else if v == "1564" { - 1564 - } else if v == "1565" { - 1565 - } else if v == "1566" { - 1566 - } else if v == "1567" { - 1567 - } else if v == "1568" { - 1568 - } else if v == "1569" { - 1569 - } else if v == "1570" { - 1570 - } else if v == "1571" { - 1571 - } else if v == "1572" { - 1572 - } else if v == "1573" { - 1573 - } else if v == "1574" { - 1574 - } else if v == "1575" { - 1575 - } else if v == "1576" { - 1576 - } else if v == "1577" { - 1577 - } else if v == "1578" { - 1578 - } else if v == "1579" { - 1579 - } else if v == "1580" { - 1580 - } else if v == "1581" { - 1581 - } else if v == "1582" { - 1582 - } else if v == "1583" { - 1583 - } else if v == "1584" { - 1584 - } else if v == "1585" { - 1585 - } else if v == "1586" { - 1586 - } else if v == "1587" { - 1587 - } else if v == "1588" { - 1588 - } else if v == "1589" { - 1589 - } else if v == "1590" { - 1590 - } else if v == "1591" { - 1591 - } else if v == "1592" { - 1592 - } else if v == "1593" { - 1593 - } else if v == "1594" { - 1594 - } else if v == "1595" { - 1595 - } else if v == "1596" { - 1596 - } else if v == "1597" { - 1597 - } else if v == "1598" { - 1598 - } else if v == "1599" { - 1599 - } else if v == "1600" { - 1600 - } else if v == "1601" { - 1601 - } else if v == "1602" { - 1602 - } else if v == "1603" { - 1603 - } else if v == "1604" { - 1604 - } else if v == "1605" { - 1605 - } else if v == "1606" { - 1606 - } else if v == "1607" { - 1607 - } else if v == "1608" { - 1608 - } else if v == "1609" { - 1609 - } else if v == "1610" { - 1610 - } else if v == "1611" { - 1611 - } else if v == "1612" { - 1612 - } else if v == "1613" { - 1613 - } else if v == "1614" { - 1614 - } else if v == "1615" { - 1615 - } else if v == "1616" { - 1616 - } else if v == "1617" { - 1617 - } else if v == "1618" { - 1618 - } else if v == "1619" { - 1619 - } else if v == "1620" { - 1620 - } else if v == "1621" { - 1621 - } else if v == "1622" { - 1622 - } else if v == "1623" { - 1623 - } else if v == "1624" { - 1624 - } else if v == "1625" { - 1625 - } else if v == "1626" { - 1626 - } else if v == "1627" { - 1627 - } else if v == "1628" { - 1628 - } else if v == "1629" { - 1629 - } else if v == "1630" { - 1630 - } else if v == "1631" { - 1631 - } else if v == "1632" { - 1632 - } else if v == "1633" { - 1633 - } else if v == "1634" { - 1634 - } else if v == "1635" { - 1635 - } else if v == "1636" { - 1636 - } else if v == "1637" { - 1637 - } else if v == "1638" { - 1638 - } else if v == "1639" { - 1639 - } else if v == "1640" { - 1640 - } else if v == "1641" { - 1641 - } else if v == "1642" { - 1642 - } else if v == "1643" { - 1643 - } else if v == "1644" { - 1644 - } else if v == "1645" { - 1645 - } else if v == "1646" { - 1646 - } else if v == "1647" { - 1647 - } else if v == "1648" { - 1648 - } else if v == "1649" { - 1649 - } else if v == "1650" { - 1650 - } else if v == "1651" { - 1651 - } else if v == "1652" { - 1652 - } else if v == "1653" { - 1653 - } else if v == "1654" { - 1654 - } else if v == "1655" { - 1655 - } else if v == "1656" { - 1656 - } else if v == "1657" { - 1657 - } else if v == "1658" { - 1658 - } else if v == "1659" { - 1659 - } else if v == "1660" { - 1660 - } else if v == "1661" { - 1661 - } else if v == "1662" { - 1662 - } else if v == "1663" { - 1663 - } else if v == "1664" { - 1664 - } else if v == "1665" { - 1665 - } else if v == "1666" { - 1666 - } else if v == "1667" { - 1667 - } else if v == "1668" { - 1668 - } else if v == "1669" { - 1669 - } else if v == "1670" { - 1670 - } else if v == "1671" { - 1671 - } else if v == "1672" { - 1672 - } else if v == "1673" { - 1673 - } else if v == "1674" { - 1674 - } else if v == "1675" { - 1675 - } else if v == "1676" { - 1676 - } else if v == "1677" { - 1677 - } else if v == "1678" { - 1678 - } else if v == "1679" { - 1679 - } else if v == "1680" { - 1680 - } else if v == "1681" { - 1681 - } else if v == "1682" { - 1682 - } else if v == "1683" { - 1683 - } else if v == "1684" { - 1684 - } else if v == "1685" { - 1685 - } else if v == "1686" { - 1686 - } else if v == "1687" { - 1687 - } else if v == "1688" { - 1688 - } else if v == "1689" { - 1689 - } else if v == "1690" { - 1690 - } else if v == "1691" { - 1691 - } else if v == "1692" { - 1692 - } else if v == "1693" { - 1693 - } else if v == "1694" { - 1694 - } else if v == "1695" { - 1695 - } else if v == "1696" { - 1696 - } else if v == "1697" { - 1697 - } else if v == "1698" { - 1698 - } else if v == "1699" { - 1699 - } else if v == "1700" { - 1700 - } else if v == "1701" { - 1701 - } else if v == "1702" { - 1702 - } else if v == "1703" { - 1703 - } else if v == "1704" { - 1704 - } else if v == "1705" { - 1705 - } else if v == "1706" { - 1706 - } else if v == "1707" { - 1707 - } else if v == "1708" { - 1708 - } else if v == "1709" { - 1709 - } else if v == "1710" { - 1710 - } else if v == "1711" { - 1711 - } else if v == "1712" { - 1712 - } else if v == "1713" { - 1713 - } else if v == "1714" { - 1714 - } else if v == "1715" { - 1715 - } else if v == "1716" { - 1716 - } else if v == "1717" { - 1717 - } else if v == "1718" { - 1718 - } else if v == "1719" { - 1719 - } else if v == "1720" { - 1720 - } else if v == "1721" { - 1721 - } else if v == "1722" { - 1722 - } else if v == "1723" { - 1723 - } else if v == "1724" { - 1724 - } else if v == "1725" { - 1725 - } else if v == "1726" { - 1726 - } else if v == "1727" { - 1727 - } else if v == "1728" { - 1728 - } else if v == "1729" { - 1729 - } else if v == "1730" { - 1730 - } else if v == "1731" { - 1731 - } else if v == "1732" { - 1732 - } else if v == "1733" { - 1733 - } else if v == "1734" { - 1734 - } else if v == "1735" { - 1735 - } else if v == "1736" { - 1736 - } else if v == "1737" { - 1737 - } else if v == "1738" { - 1738 - } else if v == "1739" { - 1739 - } else if v == "1740" { - 1740 - } else if v == "1741" { - 1741 - } else if v == "1742" { - 1742 - } else if v == "1743" { - 1743 - } else if v == "1744" { - 1744 - } else if v == "1745" { - 1745 - } else if v == "1746" { - 1746 - } else if v == "1747" { - 1747 - } else if v == "1748" { - 1748 - } else if v == "1749" { - 1749 - } else if v == "1750" { - 1750 - } else if v == "1751" { - 1751 - } else if v == "1752" { - 1752 - } else if v == "1753" { - 1753 - } else if v == "1754" { - 1754 - } else if v == "1755" { - 1755 - } else if v == "1756" { - 1756 - } else if v == "1757" { - 1757 - } else if v == "1758" { - 1758 - } else if v == "1759" { - 1759 - } else if v == "1760" { - 1760 - } else if v == "1761" { - 1761 - } else if v == "1762" { - 1762 - } else if v == "1763" { - 1763 - } else if v == "1764" { - 1764 - } else if v == "1765" { - 1765 - } else if v == "1766" { - 1766 - } else if v == "1767" { - 1767 - } else if v == "1768" { - 1768 - } else if v == "1769" { - 1769 - } else if v == "1770" { - 1770 - } else if v == "1771" { - 1771 - } else if v == "1772" { - 1772 - } else if v == "1773" { - 1773 - } else if v == "1774" { - 1774 - } else if v == "1775" { - 1775 - } else if v == "1776" { - 1776 - } else if v == "1777" { - 1777 - } else if v == "1778" { - 1778 - } else if v == "1779" { - 1779 - } else if v == "1780" { - 1780 - } else if v == "1781" { - 1781 - } else if v == "1782" { - 1782 - } else if v == "1783" { - 1783 - } else if v == "1784" { - 1784 - } else if v == "1785" { - 1785 - } else if v == "1786" { - 1786 - } else if v == "1787" { - 1787 - } else if v == "1788" { - 1788 - } else if v == "1789" { - 1789 - } else if v == "1790" { - 1790 - } else if v == "1791" { - 1791 - } else if v == "1792" { - 1792 - } else if v == "1793" { - 1793 - } else if v == "1794" { - 1794 - } else if v == "1795" { - 1795 - } else if v == "1796" { - 1796 - } else if v == "1797" { - 1797 - } else if v == "1798" { - 1798 - } else if v == "1799" { - 1799 - } else if v == "1800" { - 1800 - } else if v == "1801" { - 1801 - } else if v == "1802" { - 1802 - } else if v == "1803" { - 1803 - } else if v == "1804" { - 1804 - } else if v == "1805" { - 1805 - } else if v == "1806" { - 1806 - } else if v == "1807" { - 1807 - } else if v == "1808" { - 1808 - } else if v == "1809" { - 1809 - } else if v == "1810" { - 1810 - } else if v == "1811" { - 1811 - } else if v == "1812" { - 1812 - } else if v == "1813" { - 1813 - } else if v == "1814" { - 1814 - } else if v == "1815" { - 1815 - } else if v == "1816" { - 1816 - } else if v == "1817" { - 1817 - } else if v == "1818" { - 1818 - } else if v == "1819" { - 1819 - } else if v == "1820" { - 1820 - } else if v == "1821" { - 1821 - } else if v == "1822" { - 1822 - } else if v == "1823" { - 1823 - } else if v == "1824" { - 1824 - } else if v == "1825" { - 1825 - } else if v == "1826" { - 1826 - } else if v == "1827" { - 1827 - } else if v == "1828" { - 1828 - } else if v == "1829" { - 1829 - } else if v == "1830" { - 1830 - } else if v == "1831" { - 1831 - } else if v == "1832" { - 1832 - } else if v == "1833" { - 1833 - } else if v == "1834" { - 1834 - } else if v == "1835" { - 1835 - } else if v == "1836" { - 1836 - } else if v == "1837" { - 1837 - } else if v == "1838" { - 1838 - } else if v == "1839" { - 1839 - } else if v == "1840" { - 1840 - } else if v == "1841" { - 1841 - } else if v == "1842" { - 1842 - } else if v == "1843" { - 1843 - } else if v == "1844" { - 1844 - } else if v == "1845" { - 1845 - } else if v == "1846" { - 1846 - } else if v == "1847" { - 1847 - } else if v == "1848" { - 1848 - } else if v == "1849" { - 1849 - } else if v == "1850" { - 1850 - } else if v == "1851" { - 1851 - } else if v == "1852" { - 1852 - } else if v == "1853" { - 1853 - } else if v == "1854" { - 1854 - } else if v == "1855" { - 1855 - } else if v == "1856" { - 1856 - } else if v == "1857" { - 1857 - } else if v == "1858" { - 1858 - } else if v == "1859" { - 1859 - } else if v == "1860" { - 1860 - } else if v == "1861" { - 1861 - } else if v == "1862" { - 1862 - } else if v == "1863" { - 1863 - } else if v == "1864" { - 1864 - } else if v == "1865" { - 1865 - } else if v == "1866" { - 1866 - } else if v == "1867" { - 1867 - } else if v == "1868" { - 1868 - } else if v == "1869" { - 1869 - } else if v == "1870" { - 1870 - } else if v == "1871" { - 1871 - } else if v == "1872" { - 1872 - } else if v == "1873" { - 1873 - } else if v == "1874" { - 1874 - } else if v == "1875" { - 1875 - } else if v == "1876" { - 1876 - } else if v == "1877" { - 1877 - } else if v == "1878" { - 1878 - } else if v == "1879" { - 1879 - } else if v == "1880" { - 1880 - } else if v == "1881" { - 1881 - } else if v == "1882" { - 1882 - } else if v == "1883" { - 1883 - } else if v == "1884" { - 1884 - } else if v == "1885" { - 1885 - } else if v == "1886" { - 1886 - } else if v == "1887" { - 1887 - } else if v == "1888" { - 1888 - } else if v == "1889" { - 1889 - } else if v == "1890" { - 1890 - } else if v == "1891" { - 1891 - } else if v == "1892" { - 1892 - } else if v == "1893" { - 1893 - } else if v == "1894" { - 1894 - } else if v == "1895" { - 1895 - } else if v == "1896" { - 1896 - } else if v == "1897" { - 1897 - } else if v == "1898" { - 1898 - } else if v == "1899" { - 1899 - } else if v == "1900" { - 1900 - } else if v == "1901" { - 1901 - } else if v == "1902" { - 1902 - } else if v == "1903" { - 1903 - } else if v == "1904" { - 1904 - } else if v == "1905" { - 1905 - } else if v == "1906" { - 1906 - } else if v == "1907" { - 1907 - } else if v == "1908" { - 1908 - } else if v == "1909" { - 1909 - } else if v == "1910" { - 1910 - } else if v == "1911" { - 1911 - } else if v == "1912" { - 1912 - } else if v == "1913" { - 1913 - } else if v == "1914" { - 1914 - } else if v == "1915" { - 1915 - } else if v == "1916" { - 1916 - } else if v == "1917" { - 1917 - } else if v == "1918" { - 1918 - } else if v == "1919" { - 1919 - } else if v == "1920" { - 1920 - } else if v == "1921" { - 1921 - } else if v == "1922" { - 1922 - } else if v == "1923" { - 1923 - } else if v == "1924" { - 1924 - } else if v == "1925" { - 1925 - } else if v == "1926" { - 1926 - } else if v == "1927" { - 1927 - } else if v == "1928" { - 1928 - } else if v == "1929" { - 1929 - } else if v == "1930" { - 1930 - } else if v == "1931" { - 1931 - } else if v == "1932" { - 1932 - } else if v == "1933" { - 1933 - } else if v == "1934" { - 1934 - } else if v == "1935" { - 1935 - } else if v == "1936" { - 1936 - } else if v == "1937" { - 1937 - } else if v == "1938" { - 1938 - } else if v == "1939" { - 1939 - } else if v == "1940" { - 1940 - } else if v == "1941" { - 1941 - } else if v == "1942" { - 1942 - } else if v == "1943" { - 1943 - } else if v == "1944" { - 1944 - } else if v == "1945" { - 1945 - } else if v == "1946" { - 1946 - } else if v == "1947" { - 1947 - } else if v == "1948" { - 1948 - } else if v == "1949" { - 1949 - } else if v == "1950" { - 1950 - } else if v == "1951" { - 1951 - } else if v == "1952" { - 1952 - } else if v == "1953" { - 1953 - } else if v == "1954" { - 1954 - } else if v == "1955" { - 1955 - } else if v == "1956" { - 1956 - } else if v == "1957" { - 1957 - } else if v == "1958" { - 1958 - } else if v == "1959" { - 1959 - } else if v == "1960" { - 1960 - } else if v == "1961" { - 1961 - } else if v == "1962" { - 1962 - } else if v == "1963" { - 1963 - } else if v == "1964" { - 1964 - } else if v == "1965" { - 1965 - } else if v == "1966" { - 1966 - } else if v == "1967" { - 1967 - } else if v == "1968" { - 1968 - } else if v == "1969" { - 1969 - } else if v == "1970" { - 1970 - } else if v == "1971" { - 1971 - } else if v == "1972" { - 1972 - } else if v == "1973" { - 1973 - } else if v == "1974" { - 1974 - } else if v == "1975" { - 1975 - } else if v == "1976" { - 1976 - } else if v == "1977" { - 1977 - } else if v == "1978" { - 1978 - } else if v == "1979" { - 1979 - } else if v == "1980" { - 1980 - } else if v == "1981" { - 1981 - } else if v == "1982" { - 1982 - } else if v == "1983" { - 1983 - } else if v == "1984" { - 1984 - } else if v == "1985" { - 1985 - } else if v == "1986" { - 1986 - } else if v == "1987" { - 1987 - } else if v == "1988" { - 1988 - } else if v == "1989" { - 1989 - } else if v == "1990" { - 1990 - } else if v == "1991" { - 1991 - } else if v == "1992" { - 1992 - } else if v == "1993" { - 1993 - } else if v == "1994" { - 1994 - } else if v == "1995" { - 1995 - } else if v == "1996" { - 1996 - } else if v == "1997" { - 1997 - } else if v == "1998" { - 1998 - } else if v == "1999" { - 1999 - } else if v == "2000" { - 2000 - } else if v == "2001" { - 2001 - } else if v == "2002" { - 2002 - } else if v == "2003" { - 2003 - } else if v == "2004" { - 2004 - } else if v == "2005" { - 2005 - } else if v == "2006" { - 2006 - } else if v == "2007" { - 2007 - } else if v == "2008" { - 2008 - } else if v == "2009" { - 2009 - } else if v == "2010" { - 2010 - } else if v == "2011" { - 2011 - } else if v == "2012" { - 2012 - } else if v == "2013" { - 2013 - } else if v == "2014" { - 2014 - } else if v == "2015" { - 2015 - } else if v == "2016" { - 2016 - } else if v == "2017" { - 2017 - } else if v == "2018" { - 2018 - } else if v == "2019" { - 2019 - } else if v == "2020" { - 2020 - } else if v == "2021" { - 2021 - } else if v == "2022" { - 2022 - } else if v == "2023" { - 2023 - } else if v == "2024" { - 2024 - } else if v == "2025" { - 2025 - } else if v == "2026" { - 2026 - } else if v == "2027" { - 2027 - } else if v == "2028" { - 2028 - } else if v == "2029" { - 2029 - } else if v == "2030" { - 2030 - } else if v == "2031" { - 2031 - } else if v == "2032" { - 2032 - } else if v == "2033" { - 2033 - } else if v == "2034" { - 2034 - } else if v == "2035" { - 2035 - } else if v == "2036" { - 2036 - } else if v == "2037" { - 2037 - } else if v == "2038" { - 2038 - } else if v == "2039" { - 2039 - } else if v == "2040" { - 2040 - } else if v == "2041" { - 2041 - } else if v == "2042" { - 2042 - } else if v == "2043" { - 2043 - } else if v == "2044" { - 2044 - } else if v == "2045" { - 2045 - } else if v == "2046" { - 2046 - } else if v == "2047" { - 2047 - } else if v == "2048" { - 2048 - } else if v == "2049" { - 2049 - } else if v == "2050" { - 2050 - } else if v == "2051" { - 2051 - } else if v == "2052" { - 2052 - } else if v == "2053" { - 2053 - } else if v == "2054" { - 2054 - } else if v == "2055" { - 2055 - } else if v == "2056" { - 2056 - } else if v == "2057" { - 2057 - } else if v == "2058" { - 2058 - } else if v == "2059" { - 2059 - } else if v == "2060" { - 2060 - } else if v == "2061" { - 2061 - } else if v == "2062" { - 2062 - } else if v == "2063" { - 2063 - } else if v == "2064" { - 2064 - } else if v == "2065" { - 2065 - } else if v == "2066" { - 2066 - } else if v == "2067" { - 2067 - } else if v == "2068" { - 2068 - } else if v == "2069" { - 2069 - } else if v == "2070" { - 2070 - } else if v == "2071" { - 2071 - } else if v == "2072" { - 2072 - } else if v == "2073" { - 2073 - } else if v == "2074" { - 2074 - } else if v == "2075" { - 2075 - } else if v == "2076" { - 2076 - } else if v == "2077" { - 2077 - } else if v == "2078" { - 2078 - } else if v == "2079" { - 2079 - } else if v == "2080" { - 2080 - } else if v == "2081" { - 2081 - } else if v == "2082" { - 2082 - } else if v == "2083" { - 2083 - } else if v == "2084" { - 2084 - } else if v == "2085" { - 2085 - } else if v == "2086" { - 2086 - } else if v == "2087" { - 2087 - } else if v == "2088" { - 2088 - } else if v == "2089" { - 2089 - } else if v == "2090" { - 2090 - } else if v == "2091" { - 2091 - } else if v == "2092" { - 2092 - } else if v == "2093" { - 2093 - } else if v == "2094" { - 2094 - } else if v == "2095" { - 2095 - } else if v == "2096" { - 2096 - } else if v == "2097" { - 2097 - } else if v == "2098" { - 2098 - } else if v == "2099" { - 2099 - } else if v == "2100" { - 2100 - } else if v == "2101" { - 2101 - } else if v == "2102" { - 2102 - } else if v == "2103" { - 2103 - } else if v == "2104" { - 2104 - } else if v == "2105" { - 2105 - } else if v == "2106" { - 2106 - } else if v == "2107" { - 2107 - } else if v == "2108" { - 2108 - } else if v == "2109" { - 2109 - } else if v == "2110" { - 2110 - } else if v == "2111" { - 2111 - } else if v == "2112" { - 2112 - } else if v == "2113" { - 2113 - } else if v == "2114" { - 2114 - } else if v == "2115" { - 2115 - } else if v == "2116" { - 2116 - } else if v == "2117" { - 2117 - } else if v == "2118" { - 2118 - } else if v == "2119" { - 2119 - } else if v == "2120" { - 2120 - } else if v == "2121" { - 2121 - } else if v == "2122" { - 2122 - } else if v == "2123" { - 2123 - } else if v == "2124" { - 2124 - } else if v == "2125" { - 2125 - } else if v == "2126" { - 2126 - } else if v == "2127" { - 2127 - } else if v == "2128" { - 2128 - } else if v == "2129" { - 2129 - } else if v == "2130" { - 2130 - } else if v == "2131" { - 2131 - } else if v == "2132" { - 2132 - } else if v == "2133" { - 2133 - } else if v == "2134" { - 2134 - } else if v == "2135" { - 2135 - } else if v == "2136" { - 2136 - } else if v == "2137" { - 2137 - } else if v == "2138" { - 2138 - } else if v == "2139" { - 2139 - } else if v == "2140" { - 2140 - } else if v == "2141" { - 2141 - } else if v == "2142" { - 2142 - } else if v == "2143" { - 2143 - } else if v == "2144" { - 2144 - } else if v == "2145" { - 2145 - } else if v == "2146" { - 2146 - } else if v == "2147" { - 2147 - } else if v == "2148" { - 2148 - } else if v == "2149" { - 2149 - } else if v == "2150" { - 2150 - } else if v == "2151" { - 2151 - } else if v == "2152" { - 2152 - } else if v == "2153" { - 2153 - } else if v == "2154" { - 2154 - } else if v == "2155" { - 2155 - } else if v == "2156" { - 2156 - } else if v == "2157" { - 2157 - } else if v == "2158" { - 2158 - } else if v == "2159" { - 2159 - } else if v == "2160" { - 2160 - } else if v == "2161" { - 2161 - } else if v == "2162" { - 2162 - } else if v == "2163" { - 2163 - } else if v == "2164" { - 2164 - } else if v == "2165" { - 2165 - } else if v == "2166" { - 2166 - } else if v == "2167" { - 2167 - } else if v == "2168" { - 2168 - } else if v == "2169" { - 2169 - } else if v == "2170" { - 2170 - } else if v == "2171" { - 2171 - } else if v == "2172" { - 2172 - } else if v == "2173" { - 2173 - } else if v == "2174" { - 2174 - } else if v == "2175" { - 2175 - } else if v == "2176" { - 2176 - } else if v == "2177" { - 2177 - } else if v == "2178" { - 2178 - } else if v == "2179" { - 2179 - } else if v == "2180" { - 2180 - } else if v == "2181" { - 2181 - } else if v == "2182" { - 2182 - } else if v == "2183" { - 2183 - } else if v == "2184" { - 2184 - } else if v == "2185" { - 2185 - } else if v == "2186" { - 2186 - } else if v == "2187" { - 2187 - } else if v == "2188" { - 2188 - } else if v == "2189" { - 2189 - } else if v == "2190" { - 2190 - } else if v == "2191" { - 2191 - } else if v == "2192" { - 2192 - } else if v == "2193" { - 2193 - } else if v == "2194" { - 2194 - } else if v == "2195" { - 2195 - } else if v == "2196" { - 2196 - } else if v == "2197" { - 2197 - } else if v == "2198" { - 2198 - } else if v == "2199" { - 2199 - } else if v == "2200" { - 2200 - } else if v == "2201" { - 2201 - } else if v == "2202" { - 2202 - } else if v == "2203" { - 2203 - } else if v == "2204" { - 2204 - } else if v == "2205" { - 2205 - } else if v == "2206" { - 2206 - } else if v == "2207" { - 2207 - } else if v == "2208" { - 2208 - } else if v == "2209" { - 2209 - } else if v == "2210" { - 2210 - } else if v == "2211" { - 2211 - } else if v == "2212" { - 2212 - } else if v == "2213" { - 2213 - } else if v == "2214" { - 2214 - } else if v == "2215" { - 2215 - } else if v == "2216" { - 2216 - } else if v == "2217" { - 2217 - } else if v == "2218" { - 2218 - } else if v == "2219" { - 2219 - } else if v == "2220" { - 2220 - } else if v == "2221" { - 2221 - } else if v == "2222" { - 2222 - } else if v == "2223" { - 2223 - } else if v == "2224" { - 2224 - } else if v == "2225" { - 2225 - } else if v == "2226" { - 2226 - } else if v == "2227" { - 2227 - } else if v == "2228" { - 2228 - } else if v == "2229" { - 2229 - } else if v == "2230" { - 2230 - } else if v == "2231" { - 2231 - } else if v == "2232" { - 2232 - } else if v == "2233" { - 2233 - } else if v == "2234" { - 2234 - } else if v == "2235" { - 2235 - } else if v == "2236" { - 2236 - } else if v == "2237" { - 2237 - } else if v == "2238" { - 2238 - } else if v == "2239" { - 2239 - } else if v == "2240" { - 2240 - } else if v == "2241" { - 2241 - } else if v == "2242" { - 2242 - } else if v == "2243" { - 2243 - } else if v == "2244" { - 2244 - } else if v == "2245" { - 2245 - } else if v == "2246" { - 2246 - } else if v == "2247" { - 2247 - } else if v == "2248" { - 2248 - } else if v == "2249" { - 2249 - } else if v == "2250" { - 2250 - } else if v == "2251" { - 2251 - } else if v == "2252" { - 2252 - } else if v == "2253" { - 2253 - } else if v == "2254" { - 2254 - } else if v == "2255" { - 2255 - } else if v == "2256" { - 2256 - } else if v == "2257" { - 2257 - } else if v == "2258" { - 2258 - } else if v == "2259" { - 2259 - } else if v == "2260" { - 2260 - } else if v == "2261" { - 2261 - } else if v == "2262" { - 2262 - } else if v == "2263" { - 2263 - } else if v == "2264" { - 2264 - } else if v == "2265" { - 2265 - } else if v == "2266" { - 2266 - } else if v == "2267" { - 2267 - } else if v == "2268" { - 2268 - } else if v == "2269" { - 2269 - } else if v == "2270" { - 2270 - } else if v == "2271" { - 2271 - } else if v == "2272" { - 2272 - } else if v == "2273" { - 2273 - } else if v == "2274" { - 2274 - } else if v == "2275" { - 2275 - } else if v == "2276" { - 2276 - } else if v == "2277" { - 2277 - } else if v == "2278" { - 2278 - } else if v == "2279" { - 2279 - } else if v == "2280" { - 2280 - } else if v == "2281" { - 2281 - } else if v == "2282" { - 2282 - } else if v == "2283" { - 2283 - } else if v == "2284" { - 2284 - } else if v == "2285" { - 2285 - } else if v == "2286" { - 2286 - } else if v == "2287" { - 2287 - } else if v == "2288" { - 2288 - } else if v == "2289" { - 2289 - } else if v == "2290" { - 2290 - } else if v == "2291" { - 2291 - } else if v == "2292" { - 2292 - } else if v == "2293" { - 2293 - } else if v == "2294" { - 2294 - } else if v == "2295" { - 2295 - } else if v == "2296" { - 2296 - } else if v == "2297" { - 2297 - } else if v == "2298" { - 2298 - } else if v == "2299" { - 2299 - } else if v == "2300" { - 2300 - } else if v == "2301" { - 2301 - } else if v == "2302" { - 2302 - } else if v == "2303" { - 2303 - } else if v == "2304" { - 2304 - } else if v == "2305" { - 2305 - } else if v == "2306" { - 2306 - } else if v == "2307" { - 2307 - } else if v == "2308" { - 2308 - } else if v == "2309" { - 2309 - } else if v == "2310" { - 2310 - } else if v == "2311" { - 2311 - } else if v == "2312" { - 2312 - } else if v == "2313" { - 2313 - } else if v == "2314" { - 2314 - } else if v == "2315" { - 2315 - } else if v == "2316" { - 2316 - } else if v == "2317" { - 2317 - } else if v == "2318" { - 2318 - } else if v == "2319" { - 2319 - } else if v == "2320" { - 2320 - } else if v == "2321" { - 2321 - } else if v == "2322" { - 2322 - } else if v == "2323" { - 2323 - } else if v == "2324" { - 2324 - } else if v == "2325" { - 2325 - } else if v == "2326" { - 2326 - } else if v == "2327" { - 2327 - } else if v == "2328" { - 2328 - } else if v == "2329" { - 2329 - } else if v == "2330" { - 2330 - } else if v == "2331" { - 2331 - } else if v == "2332" { - 2332 - } else if v == "2333" { - 2333 - } else if v == "2334" { - 2334 - } else if v == "2335" { - 2335 - } else if v == "2336" { - 2336 - } else if v == "2337" { - 2337 - } else if v == "2338" { - 2338 - } else if v == "2339" { - 2339 - } else if v == "2340" { - 2340 - } else if v == "2341" { - 2341 - } else if v == "2342" { - 2342 - } else if v == "2343" { - 2343 - } else if v == "2344" { - 2344 - } else if v == "2345" { - 2345 - } else if v == "2346" { - 2346 - } else if v == "2347" { - 2347 - } else if v == "2348" { - 2348 - } else if v == "2349" { - 2349 - } else if v == "2350" { - 2350 - } else if v == "2351" { - 2351 - } else if v == "2352" { - 2352 - } else if v == "2353" { - 2353 - } else if v == "2354" { - 2354 - } else if v == "2355" { - 2355 - } else if v == "2356" { - 2356 - } else if v == "2357" { - 2357 - } else if v == "2358" { - 2358 - } else if v == "2359" { - 2359 - } else if v == "2360" { - 2360 - } else if v == "2361" { - 2361 - } else if v == "2362" { - 2362 - } else if v == "2363" { - 2363 - } else if v == "2364" { - 2364 - } else if v == "2365" { - 2365 - } else if v == "2366" { - 2366 - } else if v == "2367" { - 2367 - } else if v == "2368" { - 2368 - } else if v == "2369" { - 2369 - } else if v == "2370" { - 2370 - } else if v == "2371" { - 2371 - } else if v == "2372" { - 2372 - } else if v == "2373" { - 2373 - } else if v == "2374" { - 2374 - } else if v == "2375" { - 2375 - } else if v == "2376" { - 2376 - } else if v == "2377" { - 2377 - } else if v == "2378" { - 2378 - } else if v == "2379" { - 2379 - } else if v == "2380" { - 2380 - } else if v == "2381" { - 2381 - } else if v == "2382" { - 2382 - } else if v == "2383" { - 2383 - } else if v == "2384" { - 2384 - } else if v == "2385" { - 2385 - } else if v == "2386" { - 2386 - } else if v == "2387" { - 2387 - } else if v == "2388" { - 2388 - } else if v == "2389" { - 2389 - } else if v == "2390" { - 2390 - } else if v == "2391" { - 2391 - } else if v == "2392" { - 2392 - } else if v == "2393" { - 2393 - } else if v == "2394" { - 2394 - } else if v == "2395" { - 2395 - } else if v == "2396" { - 2396 - } else if v == "2397" { - 2397 - } else if v == "2398" { - 2398 - } else if v == "2399" { - 2399 - } else if v == "2400" { - 2400 - } else if v == "2401" { - 2401 - } else if v == "2402" { - 2402 - } else if v == "2403" { - 2403 - } else if v == "2404" { - 2404 - } else if v == "2405" { - 2405 - } else if v == "2406" { - 2406 - } else if v == "2407" { - 2407 - } else if v == "2408" { - 2408 - } else if v == "2409" { - 2409 - } else if v == "2410" { - 2410 - } else if v == "2411" { - 2411 - } else if v == "2412" { - 2412 - } else if v == "2413" { - 2413 - } else if v == "2414" { - 2414 - } else if v == "2415" { - 2415 - } else if v == "2416" { - 2416 - } else if v == "2417" { - 2417 - } else if v == "2418" { - 2418 - } else if v == "2419" { - 2419 - } else if v == "2420" { - 2420 - } else if v == "2421" { - 2421 - } else if v == "2422" { - 2422 - } else if v == "2423" { - 2423 - } else if v == "2424" { - 2424 - } else if v == "2425" { - 2425 - } else if v == "2426" { - 2426 - } else if v == "2427" { - 2427 - } else if v == "2428" { - 2428 - } else if v == "2429" { - 2429 - } else if v == "2430" { - 2430 - } else if v == "2431" { - 2431 - } else if v == "2432" { - 2432 - } else if v == "2433" { - 2433 - } else if v == "2434" { - 2434 - } else if v == "2435" { - 2435 - } else if v == "2436" { - 2436 - } else if v == "2437" { - 2437 - } else if v == "2438" { - 2438 - } else if v == "2439" { - 2439 - } else if v == "2440" { - 2440 - } else if v == "2441" { - 2441 - } else if v == "2442" { - 2442 - } else if v == "2443" { - 2443 - } else if v == "2444" { - 2444 - } else if v == "2445" { - 2445 - } else if v == "2446" { - 2446 - } else if v == "2447" { - 2447 - } else if v == "2448" { - 2448 - } else if v == "2449" { - 2449 - } else if v == "2450" { - 2450 - } else if v == "2451" { - 2451 - } else if v == "2452" { - 2452 - } else if v == "2453" { - 2453 - } else if v == "2454" { - 2454 - } else if v == "2455" { - 2455 - } else if v == "2456" { - 2456 - } else if v == "2457" { - 2457 - } else if v == "2458" { - 2458 - } else if v == "2459" { - 2459 - } else if v == "2460" { - 2460 - } else if v == "2461" { - 2461 - } else if v == "2462" { - 2462 - } else if v == "2463" { - 2463 - } else if v == "2464" { - 2464 - } else if v == "2465" { - 2465 - } else if v == "2466" { - 2466 - } else if v == "2467" { - 2467 - } else if v == "2468" { - 2468 - } else if v == "2469" { - 2469 - } else if v == "2470" { - 2470 - } else if v == "2471" { - 2471 - } else if v == "2472" { - 2472 - } else if v == "2473" { - 2473 - } else if v == "2474" { - 2474 - } else if v == "2475" { - 2475 - } else if v == "2476" { - 2476 - } else if v == "2477" { - 2477 - } else if v == "2478" { - 2478 - } else if v == "2479" { - 2479 - } else if v == "2480" { - 2480 - } else if v == "2481" { - 2481 - } else if v == "2482" { - 2482 - } else if v == "2483" { - 2483 - } else if v == "2484" { - 2484 - } else if v == "2485" { - 2485 - } else if v == "2486" { - 2486 - } else if v == "2487" { - 2487 - } else if v == "2488" { - 2488 - } else if v == "2489" { - 2489 - } else if v == "2490" { - 2490 - } else if v == "2491" { - 2491 - } else if v == "2492" { - 2492 - } else if v == "2493" { - 2493 - } else if v == "2494" { - 2494 - } else if v == "2495" { - 2495 - } else if v == "2496" { - 2496 - } else if v == "2497" { - 2497 - } else if v == "2498" { - 2498 - } else if v == "2499" { - 2499 - } else if v == "2500" { - 2500 - } else if v == "2501" { - 2501 - } else if v == "2502" { - 2502 - } else if v == "2503" { - 2503 - } else if v == "2504" { - 2504 - } else if v == "2505" { - 2505 - } else if v == "2506" { - 2506 - } else if v == "2507" { - 2507 - } else if v == "2508" { - 2508 - } else if v == "2509" { - 2509 - } else if v == "2510" { - 2510 - } else if v == "2511" { - 2511 - } else if v == "2512" { - 2512 - } else if v == "2513" { - 2513 - } else if v == "2514" { - 2514 - } else if v == "2515" { - 2515 - } else if v == "2516" { - 2516 - } else if v == "2517" { - 2517 - } else if v == "2518" { - 2518 - } else if v == "2519" { - 2519 - } else if v == "2520" { - 2520 - } else if v == "2521" { - 2521 - } else if v == "2522" { - 2522 - } else if v == "2523" { - 2523 - } else if v == "2524" { - 2524 - } else if v == "2525" { - 2525 - } else if v == "2526" { - 2526 - } else if v == "2527" { - 2527 - } else if v == "2528" { - 2528 - } else if v == "2529" { - 2529 - } else if v == "2530" { - 2530 - } else if v == "2531" { - 2531 - } else if v == "2532" { - 2532 - } else if v == "2533" { - 2533 - } else if v == "2534" { - 2534 - } else if v == "2535" { - 2535 - } else if v == "2536" { - 2536 - } else if v == "2537" { - 2537 - } else if v == "2538" { - 2538 - } else if v == "2539" { - 2539 - } else if v == "2540" { - 2540 - } else if v == "2541" { - 2541 - } else if v == "2542" { - 2542 - } else if v == "2543" { - 2543 - } else if v == "2544" { - 2544 - } else if v == "2545" { - 2545 - } else if v == "2546" { - 2546 - } else if v == "2547" { - 2547 - } else if v == "2548" { - 2548 - } else if v == "2549" { - 2549 - } else if v == "2550" { - 2550 - } else if v == "2551" { - 2551 - } else if v == "2552" { - 2552 - } else if v == "2553" { - 2553 - } else if v == "2554" { - 2554 - } else if v == "2555" { - 2555 - } else if v == "2556" { - 2556 - } else if v == "2557" { - 2557 - } else if v == "2558" { - 2558 - } else if v == "2559" { - 2559 - } else if v == "2560" { - 2560 - } else if v == "2561" { - 2561 - } else if v == "2562" { - 2562 - } else if v == "2563" { - 2563 - } else if v == "2564" { - 2564 - } else if v == "2565" { - 2565 - } else if v == "2566" { - 2566 - } else if v == "2567" { - 2567 - } else if v == "2568" { - 2568 - } else if v == "2569" { - 2569 - } else if v == "2570" { - 2570 - } else if v == "2571" { - 2571 - } else if v == "2572" { - 2572 - } else if v == "2573" { - 2573 - } else if v == "2574" { - 2574 - } else if v == "2575" { - 2575 - } else if v == "2576" { - 2576 - } else if v == "2577" { - 2577 - } else if v == "2578" { - 2578 - } else if v == "2579" { - 2579 - } else if v == "2580" { - 2580 - } else if v == "2581" { - 2581 - } else if v == "2582" { - 2582 - } else if v == "2583" { - 2583 - } else if v == "2584" { - 2584 - } else if v == "2585" { - 2585 - } else if v == "2586" { - 2586 - } else if v == "2587" { - 2587 - } else if v == "2588" { - 2588 - } else if v == "2589" { - 2589 - } else if v == "2590" { - 2590 - } else if v == "2591" { - 2591 - } else if v == "2592" { - 2592 - } else if v == "2593" { - 2593 - } else if v == "2594" { - 2594 - } else if v == "2595" { - 2595 - } else if v == "2596" { - 2596 - } else if v == "2597" { - 2597 - } else if v == "2598" { - 2598 - } else if v == "2599" { - 2599 - } else if v == "2600" { - 2600 - } else if v == "2601" { - 2601 - } else if v == "2602" { - 2602 - } else if v == "2603" { - 2603 - } else if v == "2604" { - 2604 - } else if v == "2605" { - 2605 - } else if v == "2606" { - 2606 - } else if v == "2607" { - 2607 - } else if v == "2608" { - 2608 - } else if v == "2609" { - 2609 - } else if v == "2610" { - 2610 - } else if v == "2611" { - 2611 - } else if v == "2612" { - 2612 - } else if v == "2613" { - 2613 - } else if v == "2614" { - 2614 - } else if v == "2615" { - 2615 - } else if v == "2616" { - 2616 - } else if v == "2617" { - 2617 - } else if v == "2618" { - 2618 - } else if v == "2619" { - 2619 - } else if v == "2620" { - 2620 - } else if v == "2621" { - 2621 - } else if v == "2622" { - 2622 - } else if v == "2623" { - 2623 - } else if v == "2624" { - 2624 - } else if v == "2625" { - 2625 - } else if v == "2626" { - 2626 - } else if v == "2627" { - 2627 - } else if v == "2628" { - 2628 - } else if v == "2629" { - 2629 - } else if v == "2630" { - 2630 - } else if v == "2631" { - 2631 - } else if v == "2632" { - 2632 - } else if v == "2633" { - 2633 - } else if v == "2634" { - 2634 - } else if v == "2635" { - 2635 - } else if v == "2636" { - 2636 - } else if v == "2637" { - 2637 - } else if v == "2638" { - 2638 - } else if v == "2639" { - 2639 - } else if v == "2640" { - 2640 - } else if v == "2641" { - 2641 - } else if v == "2642" { - 2642 - } else if v == "2643" { - 2643 - } else if v == "2644" { - 2644 - } else if v == "2645" { - 2645 - } else if v == "2646" { - 2646 - } else if v == "2647" { - 2647 - } else if v == "2648" { - 2648 - } else if v == "2649" { - 2649 - } else if v == "2650" { - 2650 - } else if v == "2651" { - 2651 - } else if v == "2652" { - 2652 - } else if v == "2653" { - 2653 - } else if v == "2654" { - 2654 - } else if v == "2655" { - 2655 - } else if v == "2656" { - 2656 - } else if v == "2657" { - 2657 - } else if v == "2658" { - 2658 - } else if v == "2659" { - 2659 - } else if v == "2660" { - 2660 - } else if v == "2661" { - 2661 - } else if v == "2662" { - 2662 - } else if v == "2663" { - 2663 - } else if v == "2664" { - 2664 - } else if v == "2665" { - 2665 - } else if v == "2666" { - 2666 - } else if v == "2667" { - 2667 - } else if v == "2668" { - 2668 - } else if v == "2669" { - 2669 - } else if v == "2670" { - 2670 - } else if v == "2671" { - 2671 - } else if v == "2672" { - 2672 - } else if v == "2673" { - 2673 - } else if v == "2674" { - 2674 - } else if v == "2675" { - 2675 - } else if v == "2676" { - 2676 - } else if v == "2677" { - 2677 - } else if v == "2678" { - 2678 - } else if v == "2679" { - 2679 - } else if v == "2680" { - 2680 - } else if v == "2681" { - 2681 - } else if v == "2682" { - 2682 - } else if v == "2683" { - 2683 - } else if v == "2684" { - 2684 - } else if v == "2685" { - 2685 - } else if v == "2686" { - 2686 - } else if v == "2687" { - 2687 - } else if v == "2688" { - 2688 - } else if v == "2689" { - 2689 - } else if v == "2690" { - 2690 - } else if v == "2691" { - 2691 - } else if v == "2692" { - 2692 - } else if v == "2693" { - 2693 - } else if v == "2694" { - 2694 - } else if v == "2695" { - 2695 - } else if v == "2696" { - 2696 - } else if v == "2697" { - 2697 - } else if v == "2698" { - 2698 - } else if v == "2699" { - 2699 - } else if v == "2700" { - 2700 - } else if v == "2701" { - 2701 - } else if v == "2702" { - 2702 - } else if v == "2703" { - 2703 - } else if v == "2704" { - 2704 - } else if v == "2705" { - 2705 - } else if v == "2706" { - 2706 - } else if v == "2707" { - 2707 - } else if v == "2708" { - 2708 - } else if v == "2709" { - 2709 - } else if v == "2710" { - 2710 - } else if v == "2711" { - 2711 - } else if v == "2712" { - 2712 - } else if v == "2713" { - 2713 - } else if v == "2714" { - 2714 - } else if v == "2715" { - 2715 - } else if v == "2716" { - 2716 - } else if v == "2717" { - 2717 - } else if v == "2718" { - 2718 - } else if v == "2719" { - 2719 - } else if v == "2720" { - 2720 - } else if v == "2721" { - 2721 - } else if v == "2722" { - 2722 - } else if v == "2723" { - 2723 - } else if v == "2724" { - 2724 - } else if v == "2725" { - 2725 - } else if v == "2726" { - 2726 - } else if v == "2727" { - 2727 - } else if v == "2728" { - 2728 - } else if v == "2729" { - 2729 - } else if v == "2730" { - 2730 - } else if v == "2731" { - 2731 - } else if v == "2732" { - 2732 - } else if v == "2733" { - 2733 - } else if v == "2734" { - 2734 - } else if v == "2735" { - 2735 - } else if v == "2736" { - 2736 - } else if v == "2737" { - 2737 - } else if v == "2738" { - 2738 - } else if v == "2739" { - 2739 - } else if v == "2740" { - 2740 - } else if v == "2741" { - 2741 - } else if v == "2742" { - 2742 - } else if v == "2743" { - 2743 - } else if v == "2744" { - 2744 - } else if v == "2745" { - 2745 - } else if v == "2746" { - 2746 - } else if v == "2747" { - 2747 - } else if v == "2748" { - 2748 - } else if v == "2749" { - 2749 - } else if v == "2750" { - 2750 - } else if v == "2751" { - 2751 - } else if v == "2752" { - 2752 - } else if v == "2753" { - 2753 - } else if v == "2754" { - 2754 - } else if v == "2755" { - 2755 - } else if v == "2756" { - 2756 - } else if v == "2757" { - 2757 - } else if v == "2758" { - 2758 - } else if v == "2759" { - 2759 - } else if v == "2760" { - 2760 - } else if v == "2761" { - 2761 - } else if v == "2762" { - 2762 - } else if v == "2763" { - 2763 - } else if v == "2764" { - 2764 - } else if v == "2765" { - 2765 - } else if v == "2766" { - 2766 - } else if v == "2767" { - 2767 - } else if v == "2768" { - 2768 - } else if v == "2769" { - 2769 - } else if v == "2770" { - 2770 - } else if v == "2771" { - 2771 - } else if v == "2772" { - 2772 - } else if v == "2773" { - 2773 - } else if v == "2774" { - 2774 - } else if v == "2775" { - 2775 - } else if v == "2776" { - 2776 - } else if v == "2777" { - 2777 - } else if v == "2778" { - 2778 - } else if v == "2779" { - 2779 - } else if v == "2780" { - 2780 - } else if v == "2781" { - 2781 - } else if v == "2782" { - 2782 - } else if v == "2783" { - 2783 - } else if v == "2784" { - 2784 - } else if v == "2785" { - 2785 - } else if v == "2786" { - 2786 - } else if v == "2787" { - 2787 - } else if v == "2788" { - 2788 - } else if v == "2789" { - 2789 - } else if v == "2790" { - 2790 - } else if v == "2791" { - 2791 - } else if v == "2792" { - 2792 - } else if v == "2793" { - 2793 - } else if v == "2794" { - 2794 - } else if v == "2795" { - 2795 - } else if v == "2796" { - 2796 - } else if v == "2797" { - 2797 - } else if v == "2798" { - 2798 - } else if v == "2799" { - 2799 - } else if v == "2800" { - 2800 - } else if v == "2801" { - 2801 - } else if v == "2802" { - 2802 - } else if v == "2803" { - 2803 - } else if v == "2804" { - 2804 - } else if v == "2805" { - 2805 - } else if v == "2806" { - 2806 - } else if v == "2807" { - 2807 - } else if v == "2808" { - 2808 - } else if v == "2809" { - 2809 - } else if v == "2810" { - 2810 - } else if v == "2811" { - 2811 - } else if v == "2812" { - 2812 - } else if v == "2813" { - 2813 - } else if v == "2814" { - 2814 - } else if v == "2815" { - 2815 - } else if v == "2816" { - 2816 - } else if v == "2817" { - 2817 - } else if v == "2818" { - 2818 - } else if v == "2819" { - 2819 - } else if v == "2820" { - 2820 - } else if v == "2821" { - 2821 - } else if v == "2822" { - 2822 - } else if v == "2823" { - 2823 - } else if v == "2824" { - 2824 - } else if v == "2825" { - 2825 - } else if v == "2826" { - 2826 - } else if v == "2827" { - 2827 - } else if v == "2828" { - 2828 - } else if v == "2829" { - 2829 - } else if v == "2830" { - 2830 - } else if v == "2831" { - 2831 - } else if v == "2832" { - 2832 - } else if v == "2833" { - 2833 - } else if v == "2834" { - 2834 - } else if v == "2835" { - 2835 - } else if v == "2836" { - 2836 - } else if v == "2837" { - 2837 - } else if v == "2838" { - 2838 - } else if v == "2839" { - 2839 - } else if v == "2840" { - 2840 - } else if v == "2841" { - 2841 - } else if v == "2842" { - 2842 - } else if v == "2843" { - 2843 - } else if v == "2844" { - 2844 - } else if v == "2845" { - 2845 - } else if v == "2846" { - 2846 - } else if v == "2847" { - 2847 - } else if v == "2848" { - 2848 - } else if v == "2849" { - 2849 - } else if v == "2850" { - 2850 - } else if v == "2851" { - 2851 - } else if v == "2852" { - 2852 - } else if v == "2853" { - 2853 - } else if v == "2854" { - 2854 - } else if v == "2855" { - 2855 - } else if v == "2856" { - 2856 - } else if v == "2857" { - 2857 - } else if v == "2858" { - 2858 - } else if v == "2859" { - 2859 - } else if v == "2860" { - 2860 - } else if v == "2861" { - 2861 - } else if v == "2862" { - 2862 - } else if v == "2863" { - 2863 - } else if v == "2864" { - 2864 - } else if v == "2865" { - 2865 - } else if v == "2866" { - 2866 - } else if v == "2867" { - 2867 - } else if v == "2868" { - 2868 - } else if v == "2869" { - 2869 - } else if v == "2870" { - 2870 - } else if v == "2871" { - 2871 - } else if v == "2872" { - 2872 - } else if v == "2873" { - 2873 - } else if v == "2874" { - 2874 - } else if v == "2875" { - 2875 - } else if v == "2876" { - 2876 - } else if v == "2877" { - 2877 - } else if v == "2878" { - 2878 - } else if v == "2879" { - 2879 - } else if v == "2880" { - 2880 - } else if v == "2881" { - 2881 - } else if v == "2882" { - 2882 - } else if v == "2883" { - 2883 - } else if v == "2884" { - 2884 - } else if v == "2885" { - 2885 - } else if v == "2886" { - 2886 - } else if v == "2887" { - 2887 - } else if v == "2888" { - 2888 - } else if v == "2889" { - 2889 - } else if v == "2890" { - 2890 - } else if v == "2891" { - 2891 - } else if v == "2892" { - 2892 - } else if v == "2893" { - 2893 - } else if v == "2894" { - 2894 - } else if v == "2895" { - 2895 - } else if v == "2896" { - 2896 - } else if v == "2897" { - 2897 - } else if v == "2898" { - 2898 - } else if v == "2899" { - 2899 - } else if v == "2900" { - 2900 - } else if v == "2901" { - 2901 - } else if v == "2902" { - 2902 - } else if v == "2903" { - 2903 - } else if v == "2904" { - 2904 - } else if v == "2905" { - 2905 - } else if v == "2906" { - 2906 - } else if v == "2907" { - 2907 - } else if v == "2908" { - 2908 - } else if v == "2909" { - 2909 - } else if v == "2910" { - 2910 - } else if v == "2911" { - 2911 - } else if v == "2912" { - 2912 - } else if v == "2913" { - 2913 - } else if v == "2914" { - 2914 - } else if v == "2915" { - 2915 - } else if v == "2916" { - 2916 - } else if v == "2917" { - 2917 - } else if v == "2918" { - 2918 - } else if v == "2919" { - 2919 - } else if v == "2920" { - 2920 - } else if v == "2921" { - 2921 - } else if v == "2922" { - 2922 - } else if v == "2923" { - 2923 - } else if v == "2924" { - 2924 - } else if v == "2925" { - 2925 - } else if v == "2926" { - 2926 - } else if v == "2927" { - 2927 - } else if v == "2928" { - 2928 - } else if v == "2929" { - 2929 - } else if v == "2930" { - 2930 - } else if v == "2931" { - 2931 - } else if v == "2932" { - 2932 - } else if v == "2933" { - 2933 - } else if v == "2934" { - 2934 - } else if v == "2935" { - 2935 - } else if v == "2936" { - 2936 - } else if v == "2937" { - 2937 - } else if v == "2938" { - 2938 - } else if v == "2939" { - 2939 - } else if v == "2940" { - 2940 - } else if v == "2941" { - 2941 - } else if v == "2942" { - 2942 - } else if v == "2943" { - 2943 - } else if v == "2944" { - 2944 - } else if v == "2945" { - 2945 - } else if v == "2946" { - 2946 - } else if v == "2947" { - 2947 - } else if v == "2948" { - 2948 - } else if v == "2949" { - 2949 - } else if v == "2950" { - 2950 - } else if v == "2951" { - 2951 - } else if v == "2952" { - 2952 - } else if v == "2953" { - 2953 - } else if v == "2954" { - 2954 - } else if v == "2955" { - 2955 - } else if v == "2956" { - 2956 - } else if v == "2957" { - 2957 - } else if v == "2958" { - 2958 - } else if v == "2959" { - 2959 - } else if v == "2960" { - 2960 - } else if v == "2961" { - 2961 - } else if v == "2962" { - 2962 - } else if v == "2963" { - 2963 - } else if v == "2964" { - 2964 - } else if v == "2965" { - 2965 - } else if v == "2966" { - 2966 - } else if v == "2967" { - 2967 - } else if v == "2968" { - 2968 - } else if v == "2969" { - 2969 - } else if v == "2970" { - 2970 - } else if v == "2971" { - 2971 - } else if v == "2972" { - 2972 - } else if v == "2973" { - 2973 - } else if v == "2974" { - 2974 - } else if v == "2975" { - 2975 - } else if v == "2976" { - 2976 - } else if v == "2977" { - 2977 - } else if v == "2978" { - 2978 - } else if v == "2979" { - 2979 - } else if v == "2980" { - 2980 - } else if v == "2981" { - 2981 - } else if v == "2982" { - 2982 - } else if v == "2983" { - 2983 - } else if v == "2984" { - 2984 - } else if v == "2985" { - 2985 - } else if v == "2986" { - 2986 - } else if v == "2987" { - 2987 - } else if v == "2988" { - 2988 - } else if v == "2989" { - 2989 - } else if v == "2990" { - 2990 - } else if v == "2991" { - 2991 - } else if v == "2992" { - 2992 - } else if v == "2993" { - 2993 - } else if v == "2994" { - 2994 - } else if v == "2995" { - 2995 - } else if v == "2996" { - 2996 - } else if v == "2997" { - 2997 - } else if v == "2998" { - 2998 - } else if v == "2999" { - 2999 - } else if v == "3000" { - 3000 - } else if v == "3001" { - 3001 - } else if v == "3002" { - 3002 - } else if v == "3003" { - 3003 - } else if v == "3004" { - 3004 - } else if v == "3005" { - 3005 - } else if v == "3006" { - 3006 - } else if v == "3007" { - 3007 - } else if v == "3008" { - 3008 - } else if v == "3009" { - 3009 - } else if v == "3010" { - 3010 - } else if v == "3011" { - 3011 - } else if v == "3012" { - 3012 - } else if v == "3013" { - 3013 - } else if v == "3014" { - 3014 - } else if v == "3015" { - 3015 - } else if v == "3016" { - 3016 - } else if v == "3017" { - 3017 - } else if v == "3018" { - 3018 - } else if v == "3019" { - 3019 - } else if v == "3020" { - 3020 - } else if v == "3021" { - 3021 - } else if v == "3022" { - 3022 - } else if v == "3023" { - 3023 - } else if v == "3024" { - 3024 - } else if v == "3025" { - 3025 - } else if v == "3026" { - 3026 - } else if v == "3027" { - 3027 - } else if v == "3028" { - 3028 - } else if v == "3029" { - 3029 - } else if v == "3030" { - 3030 - } else if v == "3031" { - 3031 - } else if v == "3032" { - 3032 - } else if v == "3033" { - 3033 - } else if v == "3034" { - 3034 - } else if v == "3035" { - 3035 - } else if v == "3036" { - 3036 - } else if v == "3037" { - 3037 - } else if v == "3038" { - 3038 - } else if v == "3039" { - 3039 - } else if v == "3040" { - 3040 - } else if v == "3041" { - 3041 - } else if v == "3042" { - 3042 - } else if v == "3043" { - 3043 - } else if v == "3044" { - 3044 - } else if v == "3045" { - 3045 - } else if v == "3046" { - 3046 - } else if v == "3047" { - 3047 - } else if v == "3048" { - 3048 - } else if v == "3049" { - 3049 - } else if v == "3050" { - 3050 - } else if v == "3051" { - 3051 - } else if v == "3052" { - 3052 - } else if v == "3053" { - 3053 - } else if v == "3054" { - 3054 - } else if v == "3055" { - 3055 - } else if v == "3056" { - 3056 - } else if v == "3057" { - 3057 - } else if v == "3058" { - 3058 - } else if v == "3059" { - 3059 - } else if v == "3060" { - 3060 - } else if v == "3061" { - 3061 - } else if v == "3062" { - 3062 - } else if v == "3063" { - 3063 - } else if v == "3064" { - 3064 - } else if v == "3065" { - 3065 - } else if v == "3066" { - 3066 - } else if v == "3067" { - 3067 - } else if v == "3068" { - 3068 - } else if v == "3069" { - 3069 - } else if v == "3070" { - 3070 - } else if v == "3071" { - 3071 - } else if v == "3072" { - 3072 - } else if v == "3073" { - 3073 - } else if v == "3074" { - 3074 - } else if v == "3075" { - 3075 - } else if v == "3076" { - 3076 - } else if v == "3077" { - 3077 - } else if v == "3078" { - 3078 - } else if v == "3079" { - 3079 - } else if v == "3080" { - 3080 - } else if v == "3081" { - 3081 - } else if v == "3082" { - 3082 - } else if v == "3083" { - 3083 - } else if v == "3084" { - 3084 - } else if v == "3085" { - 3085 - } else if v == "3086" { - 3086 - } else if v == "3087" { - 3087 - } else if v == "3088" { - 3088 - } else if v == "3089" { - 3089 - } else if v == "3090" { - 3090 - } else if v == "3091" { - 3091 - } else if v == "3092" { - 3092 - } else if v == "3093" { - 3093 - } else if v == "3094" { - 3094 - } else if v == "3095" { - 3095 - } else if v == "3096" { - 3096 - } else if v == "3097" { - 3097 - } else if v == "3098" { - 3098 - } else if v == "3099" { - 3099 - } else if v == "3100" { - 3100 - } else if v == "3101" { - 3101 - } else if v == "3102" { - 3102 - } else if v == "3103" { - 3103 - } else if v == "3104" { - 3104 - } else if v == "3105" { - 3105 - } else if v == "3106" { - 3106 - } else if v == "3107" { - 3107 - } else if v == "3108" { - 3108 - } else if v == "3109" { - 3109 - } else if v == "3110" { - 3110 - } else if v == "3111" { - 3111 - } else if v == "3112" { - 3112 - } else if v == "3113" { - 3113 - } else if v == "3114" { - 3114 - } else if v == "3115" { - 3115 - } else if v == "3116" { - 3116 - } else if v == "3117" { - 3117 - } else if v == "3118" { - 3118 - } else if v == "3119" { - 3119 - } else if v == "3120" { - 3120 - } else if v == "3121" { - 3121 - } else if v == "3122" { - 3122 - } else if v == "3123" { - 3123 - } else if v == "3124" { - 3124 - } else if v == "3125" { - 3125 - } else if v == "3126" { - 3126 - } else if v == "3127" { - 3127 - } else if v == "3128" { - 3128 - } else if v == "3129" { - 3129 - } else if v == "3130" { - 3130 - } else if v == "3131" { - 3131 - } else if v == "3132" { - 3132 - } else if v == "3133" { - 3133 - } else if v == "3134" { - 3134 - } else if v == "3135" { - 3135 - } else if v == "3136" { - 3136 - } else if v == "3137" { - 3137 - } else if v == "3138" { - 3138 - } else if v == "3139" { - 3139 - } else if v == "3140" { - 3140 - } else if v == "3141" { - 3141 - } else if v == "3142" { - 3142 - } else if v == "3143" { - 3143 - } else if v == "3144" { - 3144 - } else if v == "3145" { - 3145 - } else if v == "3146" { - 3146 - } else if v == "3147" { - 3147 - } else if v == "3148" { - 3148 - } else if v == "3149" { - 3149 - } else if v == "3150" { - 3150 - } else if v == "3151" { - 3151 - } else if v == "3152" { - 3152 - } else if v == "3153" { - 3153 - } else if v == "3154" { - 3154 - } else if v == "3155" { - 3155 - } else if v == "3156" { - 3156 - } else if v == "3157" { - 3157 - } else if v == "3158" { - 3158 - } else if v == "3159" { - 3159 - } else if v == "3160" { - 3160 - } else if v == "3161" { - 3161 - } else if v == "3162" { - 3162 - } else if v == "3163" { - 3163 - } else if v == "3164" { - 3164 - } else if v == "3165" { - 3165 - } else if v == "3166" { - 3166 - } else if v == "3167" { - 3167 - } else if v == "3168" { - 3168 - } else if v == "3169" { - 3169 - } else if v == "3170" { - 3170 - } else if v == "3171" { - 3171 - } else if v == "3172" { - 3172 - } else if v == "3173" { - 3173 - } else if v == "3174" { - 3174 - } else if v == "3175" { - 3175 - } else if v == "3176" { - 3176 - } else if v == "3177" { - 3177 - } else if v == "3178" { - 3178 - } else if v == "3179" { - 3179 - } else if v == "3180" { - 3180 - } else if v == "3181" { - 3181 - } else if v == "3182" { - 3182 - } else if v == "3183" { - 3183 - } else if v == "3184" { - 3184 - } else if v == "3185" { - 3185 - } else if v == "3186" { - 3186 - } else if v == "3187" { - 3187 - } else if v == "3188" { - 3188 - } else if v == "3189" { - 3189 - } else if v == "3190" { - 3190 - } else if v == "3191" { - 3191 - } else if v == "3192" { - 3192 - } else if v == "3193" { - 3193 - } else if v == "3194" { - 3194 - } else if v == "3195" { - 3195 - } else if v == "3196" { - 3196 - } else if v == "3197" { - 3197 - } else if v == "3198" { - 3198 - } else if v == "3199" { - 3199 - } else if v == "3200" { - 3200 - } else if v == "3201" { - 3201 - } else if v == "3202" { - 3202 - } else if v == "3203" { - 3203 - } else if v == "3204" { - 3204 - } else if v == "3205" { - 3205 - } else if v == "3206" { - 3206 - } else if v == "3207" { - 3207 - } else if v == "3208" { - 3208 - } else if v == "3209" { - 3209 - } else if v == "3210" { - 3210 - } else if v == "3211" { - 3211 - } else if v == "3212" { - 3212 - } else if v == "3213" { - 3213 - } else if v == "3214" { - 3214 - } else if v == "3215" { - 3215 - } else if v == "3216" { - 3216 - } else if v == "3217" { - 3217 - } else if v == "3218" { - 3218 - } else if v == "3219" { - 3219 - } else if v == "3220" { - 3220 - } else if v == "3221" { - 3221 - } else if v == "3222" { - 3222 - } else if v == "3223" { - 3223 - } else if v == "3224" { - 3224 - } else if v == "3225" { - 3225 - } else if v == "3226" { - 3226 - } else if v == "3227" { - 3227 - } else if v == "3228" { - 3228 - } else if v == "3229" { - 3229 - } else if v == "3230" { - 3230 - } else if v == "3231" { - 3231 - } else if v == "3232" { - 3232 - } else if v == "3233" { - 3233 - } else if v == "3234" { - 3234 - } else if v == "3235" { - 3235 - } else if v == "3236" { - 3236 - } else if v == "3237" { - 3237 - } else if v == "3238" { - 3238 - } else if v == "3239" { - 3239 - } else if v == "3240" { - 3240 - } else if v == "3241" { - 3241 - } else if v == "3242" { - 3242 - } else if v == "3243" { - 3243 - } else if v == "3244" { - 3244 - } else if v == "3245" { - 3245 - } else if v == "3246" { - 3246 - } else if v == "3247" { - 3247 - } else if v == "3248" { - 3248 - } else if v == "3249" { - 3249 - } else if v == "3250" { - 3250 - } else if v == "3251" { - 3251 - } else if v == "3252" { - 3252 - } else if v == "3253" { - 3253 - } else if v == "3254" { - 3254 - } else if v == "3255" { - 3255 - } else if v == "3256" { - 3256 - } else if v == "3257" { - 3257 - } else if v == "3258" { - 3258 - } else if v == "3259" { - 3259 - } else if v == "3260" { - 3260 - } else if v == "3261" { - 3261 - } else if v == "3262" { - 3262 - } else if v == "3263" { - 3263 - } else if v == "3264" { - 3264 - } else if v == "3265" { - 3265 - } else if v == "3266" { - 3266 - } else if v == "3267" { - 3267 - } else if v == "3268" { - 3268 - } else if v == "3269" { - 3269 - } else if v == "3270" { - 3270 - } else if v == "3271" { - 3271 - } else if v == "3272" { - 3272 - } else if v == "3273" { - 3273 - } else if v == "3274" { - 3274 - } else if v == "3275" { - 3275 - } else if v == "3276" { - 3276 - } else if v == "3277" { - 3277 - } else if v == "3278" { - 3278 - } else if v == "3279" { - 3279 - } else if v == "3280" { - 3280 - } else if v == "3281" { - 3281 - } else if v == "3282" { - 3282 - } else if v == "3283" { - 3283 - } else if v == "3284" { - 3284 - } else if v == "3285" { - 3285 - } else if v == "3286" { - 3286 - } else if v == "3287" { - 3287 - } else if v == "3288" { - 3288 - } else if v == "3289" { - 3289 - } else if v == "3290" { - 3290 - } else if v == "3291" { - 3291 - } else if v == "3292" { - 3292 - } else if v == "3293" { - 3293 - } else if v == "3294" { - 3294 - } else if v == "3295" { - 3295 - } else if v == "3296" { - 3296 - } else if v == "3297" { - 3297 - } else if v == "3298" { - 3298 - } else if v == "3299" { - 3299 - } else if v == "3300" { - 3300 - } else if v == "3301" { - 3301 - } else if v == "3302" { - 3302 - } else if v == "3303" { - 3303 - } else if v == "3304" { - 3304 - } else if v == "3305" { - 3305 - } else if v == "3306" { - 3306 - } else if v == "3307" { - 3307 - } else if v == "3308" { - 3308 - } else if v == "3309" { - 3309 - } else if v == "3310" { - 3310 - } else if v == "3311" { - 3311 - } else if v == "3312" { - 3312 - } else if v == "3313" { - 3313 - } else if v == "3314" { - 3314 - } else if v == "3315" { - 3315 - } else if v == "3316" { - 3316 - } else if v == "3317" { - 3317 - } else if v == "3318" { - 3318 - } else if v == "3319" { - 3319 - } else if v == "3320" { - 3320 - } else if v == "3321" { - 3321 - } else if v == "3322" { - 3322 - } else if v == "3323" { - 3323 - } else if v == "3324" { - 3324 - } else if v == "3325" { - 3325 - } else if v == "3326" { - 3326 - } else if v == "3327" { - 3327 - } else if v == "3328" { - 3328 - } else if v == "3329" { - 3329 - } else if v == "3330" { - 3330 - } else if v == "3331" { - 3331 - } else if v == "3332" { - 3332 - } else if v == "3333" { - 3333 - } else if v == "3334" { - 3334 - } else if v == "3335" { - 3335 - } else if v == "3336" { - 3336 - } else if v == "3337" { - 3337 - } else if v == "3338" { - 3338 - } else if v == "3339" { - 3339 - } else if v == "3340" { - 3340 - } else if v == "3341" { - 3341 - } else if v == "3342" { - 3342 - } else if v == "3343" { - 3343 - } else if v == "3344" { - 3344 - } else if v == "3345" { - 3345 - } else if v == "3346" { - 3346 - } else if v == "3347" { - 3347 - } else if v == "3348" { - 3348 - } else if v == "3349" { - 3349 - } else if v == "3350" { - 3350 - } else if v == "3351" { - 3351 - } else if v == "3352" { - 3352 - } else if v == "3353" { - 3353 - } else if v == "3354" { - 3354 - } else if v == "3355" { - 3355 - } else if v == "3356" { - 3356 - } else if v == "3357" { - 3357 - } else if v == "3358" { - 3358 - } else if v == "3359" { - 3359 - } else if v == "3360" { - 3360 - } else if v == "3361" { - 3361 - } else if v == "3362" { - 3362 - } else if v == "3363" { - 3363 - } else if v == "3364" { - 3364 - } else if v == "3365" { - 3365 - } else if v == "3366" { - 3366 - } else if v == "3367" { - 3367 - } else if v == "3368" { - 3368 - } else if v == "3369" { - 3369 - } else if v == "3370" { - 3370 - } else if v == "3371" { - 3371 - } else if v == "3372" { - 3372 - } else if v == "3373" { - 3373 - } else if v == "3374" { - 3374 - } else if v == "3375" { - 3375 - } else if v == "3376" { - 3376 - } else if v == "3377" { - 3377 - } else if v == "3378" { - 3378 - } else if v == "3379" { - 3379 - } else if v == "3380" { - 3380 - } else if v == "3381" { - 3381 - } else if v == "3382" { - 3382 - } else if v == "3383" { - 3383 - } else if v == "3384" { - 3384 - } else if v == "3385" { - 3385 - } else if v == "3386" { - 3386 - } else if v == "3387" { - 3387 - } else if v == "3388" { - 3388 - } else if v == "3389" { - 3389 - } else if v == "3390" { - 3390 - } else if v == "3391" { - 3391 - } else if v == "3392" { - 3392 - } else if v == "3393" { - 3393 - } else if v == "3394" { - 3394 - } else if v == "3395" { - 3395 - } else if v == "3396" { - 3396 - } else if v == "3397" { - 3397 - } else if v == "3398" { - 3398 - } else if v == "3399" { - 3399 - } else if v == "3400" { - 3400 - } else if v == "3401" { - 3401 - } else if v == "3402" { - 3402 - } else if v == "3403" { - 3403 - } else if v == "3404" { - 3404 - } else if v == "3405" { - 3405 - } else if v == "3406" { - 3406 - } else if v == "3407" { - 3407 - } else if v == "3408" { - 3408 - } else if v == "3409" { - 3409 - } else if v == "3410" { - 3410 - } else if v == "3411" { - 3411 - } else if v == "3412" { - 3412 - } else if v == "3413" { - 3413 - } else if v == "3414" { - 3414 - } else if v == "3415" { - 3415 - } else if v == "3416" { - 3416 - } else if v == "3417" { - 3417 - } else if v == "3418" { - 3418 - } else if v == "3419" { - 3419 - } else if v == "3420" { - 3420 - } else if v == "3421" { - 3421 - } else if v == "3422" { - 3422 - } else if v == "3423" { - 3423 - } else if v == "3424" { - 3424 - } else if v == "3425" { - 3425 - } else if v == "3426" { - 3426 - } else if v == "3427" { - 3427 - } else if v == "3428" { - 3428 - } else if v == "3429" { - 3429 - } else if v == "3430" { - 3430 - } else if v == "3431" { - 3431 - } else if v == "3432" { - 3432 - } else if v == "3433" { - 3433 - } else if v == "3434" { - 3434 - } else if v == "3435" { - 3435 - } else if v == "3436" { - 3436 - } else if v == "3437" { - 3437 - } else if v == "3438" { - 3438 - } else if v == "3439" { - 3439 - } else if v == "3440" { - 3440 - } else if v == "3441" { - 3441 - } else if v == "3442" { - 3442 - } else if v == "3443" { - 3443 - } else if v == "3444" { - 3444 - } else if v == "3445" { - 3445 - } else if v == "3446" { - 3446 - } else if v == "3447" { - 3447 - } else if v == "3448" { - 3448 - } else if v == "3449" { - 3449 - } else if v == "3450" { - 3450 - } else if v == "3451" { - 3451 - } else if v == "3452" { - 3452 - } else if v == "3453" { - 3453 - } else if v == "3454" { - 3454 - } else if v == "3455" { - 3455 - } else if v == "3456" { - 3456 - } else if v == "3457" { - 3457 - } else if v == "3458" { - 3458 - } else if v == "3459" { - 3459 - } else if v == "3460" { - 3460 - } else if v == "3461" { - 3461 - } else if v == "3462" { - 3462 - } else if v == "3463" { - 3463 - } else if v == "3464" { - 3464 - } else if v == "3465" { - 3465 - } else if v == "3466" { - 3466 - } else if v == "3467" { - 3467 - } else if v == "3468" { - 3468 - } else if v == "3469" { - 3469 - } else if v == "3470" { - 3470 - } else if v == "3471" { - 3471 - } else if v == "3472" { - 3472 - } else if v == "3473" { - 3473 - } else if v == "3474" { - 3474 - } else if v == "3475" { - 3475 - } else if v == "3476" { - 3476 - } else if v == "3477" { - 3477 - } else if v == "3478" { - 3478 - } else if v == "3479" { - 3479 - } else if v == "3480" { - 3480 - } else if v == "3481" { - 3481 - } else if v == "3482" { - 3482 - } else if v == "3483" { - 3483 - } else if v == "3484" { - 3484 - } else if v == "3485" { - 3485 - } else if v == "3486" { - 3486 - } else if v == "3487" { - 3487 - } else if v == "3488" { - 3488 - } else if v == "3489" { - 3489 - } else if v == "3490" { - 3490 - } else if v == "3491" { - 3491 - } else if v == "3492" { - 3492 - } else if v == "3493" { - 3493 - } else if v == "3494" { - 3494 - } else if v == "3495" { - 3495 - } else if v == "3496" { - 3496 - } else if v == "3497" { - 3497 - } else if v == "3498" { - 3498 - } else if v == "3499" { - 3499 - } else if v == "3500" { - 3500 - } else if v == "3501" { - 3501 - } else if v == "3502" { - 3502 - } else if v == "3503" { - 3503 - } else if v == "3504" { - 3504 - } else if v == "3505" { - 3505 - } else if v == "3506" { - 3506 - } else if v == "3507" { - 3507 - } else if v == "3508" { - 3508 - } else if v == "3509" { - 3509 - } else if v == "3510" { - 3510 - } else if v == "3511" { - 3511 - } else if v == "3512" { - 3512 - } else if v == "3513" { - 3513 - } else if v == "3514" { - 3514 - } else if v == "3515" { - 3515 - } else if v == "3516" { - 3516 - } else if v == "3517" { - 3517 - } else if v == "3518" { - 3518 - } else if v == "3519" { - 3519 - } else if v == "3520" { - 3520 - } else if v == "3521" { - 3521 - } else if v == "3522" { - 3522 - } else if v == "3523" { - 3523 - } else if v == "3524" { - 3524 - } else if v == "3525" { - 3525 - } else if v == "3526" { - 3526 - } else if v == "3527" { - 3527 - } else if v == "3528" { - 3528 - } else if v == "3529" { - 3529 - } else if v == "3530" { - 3530 - } else if v == "3531" { - 3531 - } else if v == "3532" { - 3532 - } else if v == "3533" { - 3533 - } else if v == "3534" { - 3534 - } else if v == "3535" { - 3535 - } else if v == "3536" { - 3536 - } else if v == "3537" { - 3537 - } else if v == "3538" { - 3538 - } else if v == "3539" { - 3539 - } else if v == "3540" { - 3540 - } else if v == "3541" { - 3541 - } else if v == "3542" { - 3542 - } else if v == "3543" { - 3543 - } else if v == "3544" { - 3544 - } else if v == "3545" { - 3545 - } else if v == "3546" { - 3546 - } else if v == "3547" { - 3547 - } else if v == "3548" { - 3548 - } else if v == "3549" { - 3549 - } else if v == "3550" { - 3550 - } else if v == "3551" { - 3551 - } else if v == "3552" { - 3552 - } else if v == "3553" { - 3553 - } else if v == "3554" { - 3554 - } else if v == "3555" { - 3555 - } else if v == "3556" { - 3556 - } else if v == "3557" { - 3557 - } else if v == "3558" { - 3558 - } else if v == "3559" { - 3559 - } else if v == "3560" { - 3560 - } else if v == "3561" { - 3561 - } else if v == "3562" { - 3562 - } else if v == "3563" { - 3563 - } else if v == "3564" { - 3564 - } else if v == "3565" { - 3565 - } else if v == "3566" { - 3566 - } else if v == "3567" { - 3567 - } else if v == "3568" { - 3568 - } else if v == "3569" { - 3569 - } else if v == "3570" { - 3570 - } else if v == "3571" { - 3571 - } else if v == "3572" { - 3572 - } else if v == "3573" { - 3573 - } else if v == "3574" { - 3574 - } else if v == "3575" { - 3575 - } else if v == "3576" { - 3576 - } else if v == "3577" { - 3577 - } else if v == "3578" { - 3578 - } else if v == "3579" { - 3579 - } else if v == "3580" { - 3580 - } else if v == "3581" { - 3581 - } else if v == "3582" { - 3582 - } else if v == "3583" { - 3583 - } else if v == "3584" { - 3584 - } else if v == "3585" { - 3585 - } else if v == "3586" { - 3586 - } else if v == "3587" { - 3587 - } else if v == "3588" { - 3588 - } else if v == "3589" { - 3589 - } else if v == "3590" { - 3590 - } else if v == "3591" { - 3591 - } else if v == "3592" { - 3592 - } else if v == "3593" { - 3593 - } else if v == "3594" { - 3594 - } else if v == "3595" { - 3595 - } else if v == "3596" { - 3596 - } else if v == "3597" { - 3597 - } else if v == "3598" { - 3598 - } else if v == "3599" { - 3599 - } else if v == "3600" { - 3600 - } else if v == "3601" { - 3601 - } else if v == "3602" { - 3602 - } else if v == "3603" { - 3603 - } else if v == "3604" { - 3604 - } else if v == "3605" { - 3605 - } else if v == "3606" { - 3606 - } else if v == "3607" { - 3607 - } else if v == "3608" { - 3608 - } else if v == "3609" { - 3609 - } else if v == "3610" { - 3610 - } else if v == "3611" { - 3611 - } else if v == "3612" { - 3612 - } else if v == "3613" { - 3613 - } else if v == "3614" { - 3614 - } else if v == "3615" { - 3615 - } else if v == "3616" { - 3616 - } else if v == "3617" { - 3617 - } else if v == "3618" { - 3618 - } else if v == "3619" { - 3619 - } else if v == "3620" { - 3620 - } else if v == "3621" { - 3621 - } else if v == "3622" { - 3622 - } else if v == "3623" { - 3623 - } else if v == "3624" { - 3624 - } else if v == "3625" { - 3625 - } else if v == "3626" { - 3626 - } else if v == "3627" { - 3627 - } else if v == "3628" { - 3628 - } else if v == "3629" { - 3629 - } else if v == "3630" { - 3630 - } else if v == "3631" { - 3631 - } else if v == "3632" { - 3632 - } else if v == "3633" { - 3633 - } else if v == "3634" { - 3634 - } else if v == "3635" { - 3635 - } else if v == "3636" { - 3636 - } else if v == "3637" { - 3637 - } else if v == "3638" { - 3638 - } else if v == "3639" { - 3639 - } else if v == "3640" { - 3640 - } else if v == "3641" { - 3641 - } else if v == "3642" { - 3642 - } else if v == "3643" { - 3643 - } else if v == "3644" { - 3644 - } else if v == "3645" { - 3645 - } else if v == "3646" { - 3646 - } else if v == "3647" { - 3647 - } else if v == "3648" { - 3648 - } else if v == "3649" { - 3649 - } else if v == "3650" { - 3650 - } else if v == "3651" { - 3651 - } else if v == "3652" { - 3652 - } else if v == "3653" { - 3653 - } else if v == "3654" { - 3654 - } else if v == "3655" { - 3655 - } else if v == "3656" { - 3656 - } else if v == "3657" { - 3657 - } else if v == "3658" { - 3658 - } else if v == "3659" { - 3659 - } else if v == "3660" { - 3660 - } else if v == "3661" { - 3661 - } else if v == "3662" { - 3662 - } else if v == "3663" { - 3663 - } else if v == "3664" { - 3664 - } else if v == "3665" { - 3665 - } else if v == "3666" { - 3666 - } else if v == "3667" { - 3667 - } else if v == "3668" { - 3668 - } else if v == "3669" { - 3669 - } else if v == "3670" { - 3670 - } else if v == "3671" { - 3671 - } else if v == "3672" { - 3672 - } else if v == "3673" { - 3673 - } else if v == "3674" { - 3674 - } else if v == "3675" { - 3675 - } else if v == "3676" { - 3676 - } else if v == "3677" { - 3677 - } else if v == "3678" { - 3678 - } else if v == "3679" { - 3679 - } else if v == "3680" { - 3680 - } else if v == "3681" { - 3681 - } else if v == "3682" { - 3682 - } else if v == "3683" { - 3683 - } else if v == "3684" { - 3684 - } else if v == "3685" { - 3685 - } else if v == "3686" { - 3686 - } else if v == "3687" { - 3687 - } else if v == "3688" { - 3688 - } else if v == "3689" { - 3689 - } else if v == "3690" { - 3690 - } else if v == "3691" { - 3691 - } else if v == "3692" { - 3692 - } else if v == "3693" { - 3693 - } else if v == "3694" { - 3694 - } else if v == "3695" { - 3695 - } else if v == "3696" { - 3696 - } else if v == "3697" { - 3697 - } else if v == "3698" { - 3698 - } else if v == "3699" { - 3699 - } else if v == "3700" { - 3700 - } else if v == "3701" { - 3701 - } else if v == "3702" { - 3702 - } else if v == "3703" { - 3703 - } else if v == "3704" { - 3704 - } else if v == "3705" { - 3705 - } else if v == "3706" { - 3706 - } else if v == "3707" { - 3707 - } else if v == "3708" { - 3708 - } else if v == "3709" { - 3709 - } else if v == "3710" { - 3710 - } else if v == "3711" { - 3711 - } else if v == "3712" { - 3712 - } else if v == "3713" { - 3713 - } else if v == "3714" { - 3714 - } else if v == "3715" { - 3715 - } else if v == "3716" { - 3716 - } else if v == "3717" { - 3717 - } else if v == "3718" { - 3718 - } else if v == "3719" { - 3719 - } else if v == "3720" { - 3720 - } else if v == "3721" { - 3721 - } else if v == "3722" { - 3722 - } else if v == "3723" { - 3723 - } else if v == "3724" { - 3724 - } else if v == "3725" { - 3725 - } else if v == "3726" { - 3726 - } else if v == "3727" { - 3727 - } else if v == "3728" { - 3728 - } else if v == "3729" { - 3729 - } else if v == "3730" { - 3730 - } else if v == "3731" { - 3731 - } else if v == "3732" { - 3732 - } else if v == "3733" { - 3733 - } else if v == "3734" { - 3734 - } else if v == "3735" { - 3735 - } else if v == "3736" { - 3736 - } else if v == "3737" { - 3737 - } else if v == "3738" { - 3738 - } else if v == "3739" { - 3739 - } else if v == "3740" { - 3740 - } else if v == "3741" { - 3741 - } else if v == "3742" { - 3742 - } else if v == "3743" { - 3743 - } else if v == "3744" { - 3744 - } else if v == "3745" { - 3745 - } else if v == "3746" { - 3746 - } else if v == "3747" { - 3747 - } else if v == "3748" { - 3748 - } else if v == "3749" { - 3749 - } else if v == "3750" { - 3750 - } else if v == "3751" { - 3751 - } else if v == "3752" { - 3752 - } else if v == "3753" { - 3753 - } else if v == "3754" { - 3754 - } else if v == "3755" { - 3755 - } else if v == "3756" { - 3756 - } else if v == "3757" { - 3757 - } else if v == "3758" { - 3758 - } else if v == "3759" { - 3759 - } else if v == "3760" { - 3760 - } else if v == "3761" { - 3761 - } else if v == "3762" { - 3762 - } else if v == "3763" { - 3763 - } else if v == "3764" { - 3764 - } else if v == "3765" { - 3765 - } else if v == "3766" { - 3766 - } else if v == "3767" { - 3767 - } else if v == "3768" { - 3768 - } else if v == "3769" { - 3769 - } else if v == "3770" { - 3770 - } else if v == "3771" { - 3771 - } else if v == "3772" { - 3772 - } else if v == "3773" { - 3773 - } else if v == "3774" { - 3774 - } else if v == "3775" { - 3775 - } else if v == "3776" { - 3776 - } else if v == "3777" { - 3777 - } else if v == "3778" { - 3778 - } else if v == "3779" { - 3779 - } else if v == "3780" { - 3780 - } else if v == "3781" { - 3781 - } else if v == "3782" { - 3782 - } else if v == "3783" { - 3783 - } else if v == "3784" { - 3784 - } else if v == "3785" { - 3785 - } else if v == "3786" { - 3786 - } else if v == "3787" { - 3787 - } else if v == "3788" { - 3788 - } else if v == "3789" { - 3789 - } else if v == "3790" { - 3790 - } else if v == "3791" { - 3791 - } else if v == "3792" { - 3792 - } else if v == "3793" { - 3793 - } else if v == "3794" { - 3794 - } else if v == "3795" { - 3795 - } else if v == "3796" { - 3796 - } else if v == "3797" { - 3797 - } else if v == "3798" { - 3798 - } else if v == "3799" { - 3799 - } else if v == "3800" { - 3800 - } else if v == "3801" { - 3801 - } else if v == "3802" { - 3802 - } else if v == "3803" { - 3803 - } else if v == "3804" { - 3804 - } else if v == "3805" { - 3805 - } else if v == "3806" { - 3806 - } else if v == "3807" { - 3807 - } else if v == "3808" { - 3808 - } else if v == "3809" { - 3809 - } else if v == "3810" { - 3810 - } else if v == "3811" { - 3811 - } else if v == "3812" { - 3812 - } else if v == "3813" { - 3813 - } else if v == "3814" { - 3814 - } else if v == "3815" { - 3815 - } else if v == "3816" { - 3816 - } else if v == "3817" { - 3817 - } else if v == "3818" { - 3818 - } else if v == "3819" { - 3819 - } else if v == "3820" { - 3820 - } else if v == "3821" { - 3821 - } else if v == "3822" { - 3822 - } else if v == "3823" { - 3823 - } else if v == "3824" { - 3824 - } else if v == "3825" { - 3825 - } else if v == "3826" { - 3826 - } else if v == "3827" { - 3827 - } else if v == "3828" { - 3828 - } else if v == "3829" { - 3829 - } else if v == "3830" { - 3830 - } else if v == "3831" { - 3831 - } else if v == "3832" { - 3832 - } else if v == "3833" { - 3833 - } else if v == "3834" { - 3834 - } else if v == "3835" { - 3835 - } else if v == "3836" { - 3836 - } else if v == "3837" { - 3837 - } else if v == "3838" { - 3838 - } else if v == "3839" { - 3839 - } else if v == "3840" { - 3840 - } else if v == "3841" { - 3841 - } else if v == "3842" { - 3842 - } else if v == "3843" { - 3843 - } else if v == "3844" { - 3844 - } else if v == "3845" { - 3845 - } else if v == "3846" { - 3846 - } else if v == "3847" { - 3847 - } else if v == "3848" { - 3848 - } else if v == "3849" { - 3849 - } else if v == "3850" { - 3850 - } else if v == "3851" { - 3851 - } else if v == "3852" { - 3852 - } else if v == "3853" { - 3853 - } else if v == "3854" { - 3854 - } else if v == "3855" { - 3855 - } else if v == "3856" { - 3856 - } else if v == "3857" { - 3857 - } else if v == "3858" { - 3858 - } else if v == "3859" { - 3859 - } else if v == "3860" { - 3860 - } else if v == "3861" { - 3861 - } else if v == "3862" { - 3862 - } else if v == "3863" { - 3863 - } else if v == "3864" { - 3864 - } else if v == "3865" { - 3865 - } else if v == "3866" { - 3866 - } else if v == "3867" { - 3867 - } else if v == "3868" { - 3868 - } else if v == "3869" { - 3869 - } else if v == "3870" { - 3870 - } else if v == "3871" { - 3871 - } else if v == "3872" { - 3872 - } else if v == "3873" { - 3873 - } else if v == "3874" { - 3874 - } else if v == "3875" { - 3875 - } else if v == "3876" { - 3876 - } else if v == "3877" { - 3877 - } else if v == "3878" { - 3878 - } else if v == "3879" { - 3879 - } else if v == "3880" { - 3880 - } else if v == "3881" { - 3881 - } else if v == "3882" { - 3882 - } else if v == "3883" { - 3883 - } else if v == "3884" { - 3884 - } else if v == "3885" { - 3885 - } else if v == "3886" { - 3886 - } else if v == "3887" { - 3887 - } else if v == "3888" { - 3888 - } else if v == "3889" { - 3889 - } else if v == "3890" { - 3890 - } else if v == "3891" { - 3891 - } else if v == "3892" { - 3892 - } else if v == "3893" { - 3893 - } else if v == "3894" { - 3894 - } else if v == "3895" { - 3895 - } else if v == "3896" { - 3896 - } else if v == "3897" { - 3897 - } else if v == "3898" { - 3898 - } else if v == "3899" { - 3899 - } else if v == "3900" { - 3900 - } else if v == "3901" { - 3901 - } else if v == "3902" { - 3902 - } else if v == "3903" { - 3903 - } else if v == "3904" { - 3904 - } else if v == "3905" { - 3905 - } else if v == "3906" { - 3906 - } else if v == "3907" { - 3907 - } else if v == "3908" { - 3908 - } else if v == "3909" { - 3909 - } else if v == "3910" { - 3910 - } else if v == "3911" { - 3911 - } else if v == "3912" { - 3912 - } else if v == "3913" { - 3913 - } else if v == "3914" { - 3914 - } else if v == "3915" { - 3915 - } else if v == "3916" { - 3916 - } else if v == "3917" { - 3917 - } else if v == "3918" { - 3918 - } else if v == "3919" { - 3919 - } else if v == "3920" { - 3920 - } else if v == "3921" { - 3921 - } else if v == "3922" { - 3922 - } else if v == "3923" { - 3923 - } else if v == "3924" { - 3924 - } else if v == "3925" { - 3925 - } else if v == "3926" { - 3926 - } else if v == "3927" { - 3927 - } else if v == "3928" { - 3928 - } else if v == "3929" { - 3929 - } else if v == "3930" { - 3930 - } else if v == "3931" { - 3931 - } else if v == "3932" { - 3932 - } else if v == "3933" { - 3933 - } else if v == "3934" { - 3934 - } else if v == "3935" { - 3935 - } else if v == "3936" { - 3936 - } else if v == "3937" { - 3937 - } else if v == "3938" { - 3938 - } else if v == "3939" { - 3939 - } else if v == "3940" { - 3940 - } else if v == "3941" { - 3941 - } else if v == "3942" { - 3942 - } else if v == "3943" { - 3943 - } else if v == "3944" { - 3944 - } else if v == "3945" { - 3945 - } else if v == "3946" { - 3946 - } else if v == "3947" { - 3947 - } else if v == "3948" { - 3948 - } else if v == "3949" { - 3949 - } else if v == "3950" { - 3950 - } else if v == "3951" { - 3951 - } else if v == "3952" { - 3952 - } else if v == "3953" { - 3953 - } else if v == "3954" { - 3954 - } else if v == "3955" { - 3955 - } else if v == "3956" { - 3956 - } else if v == "3957" { - 3957 - } else if v == "3958" { - 3958 - } else if v == "3959" { - 3959 - } else if v == "3960" { - 3960 - } else if v == "3961" { - 3961 - } else if v == "3962" { - 3962 - } else if v == "3963" { - 3963 - } else if v == "3964" { - 3964 - } else if v == "3965" { - 3965 - } else if v == "3966" { - 3966 - } else if v == "3967" { - 3967 - } else if v == "3968" { - 3968 - } else if v == "3969" { - 3969 - } else if v == "3970" { - 3970 - } else if v == "3971" { - 3971 - } else if v == "3972" { - 3972 - } else if v == "3973" { - 3973 - } else if v == "3974" { - 3974 - } else if v == "3975" { - 3975 - } else if v == "3976" { - 3976 - } else if v == "3977" { - 3977 - } else if v == "3978" { - 3978 - } else if v == "3979" { - 3979 - } else if v == "3980" { - 3980 - } else if v == "3981" { - 3981 - } else if v == "3982" { - 3982 - } else if v == "3983" { - 3983 - } else if v == "3984" { - 3984 - } else if v == "3985" { - 3985 - } else if v == "3986" { - 3986 - } else if v == "3987" { - 3987 - } else if v == "3988" { - 3988 - } else if v == "3989" { - 3989 - } else if v == "3990" { - 3990 - } else if v == "3991" { - 3991 - } else if v == "3992" { - 3992 - } else if v == "3993" { - 3993 - } else if v == "3994" { - 3994 - } else if v == "3995" { - 3995 - } else if v == "3996" { - 3996 - } else if v == "3997" { - 3997 - } else if v == "3998" { - 3998 - } else if v == "3999" { - 3999 - } else if v == "4000" { - 4000 - } else if v == "4001" { - 4001 - } else if v == "4002" { - 4002 - } else if v == "4003" { - 4003 - } else if v == "4004" { - 4004 - } else if v == "4005" { - 4005 - } else if v == "4006" { - 4006 - } else if v == "4007" { - 4007 - } else if v == "4008" { - 4008 - } else if v == "4009" { - 4009 - } else if v == "4010" { - 4010 - } else if v == "4011" { - 4011 - } else if v == "4012" { - 4012 - } else if v == "4013" { - 4013 - } else if v == "4014" { - 4014 - } else if v == "4015" { - 4015 - } else if v == "4016" { - 4016 - } else if v == "4017" { - 4017 - } else if v == "4018" { - 4018 - } else if v == "4019" { - 4019 - } else if v == "4020" { - 4020 - } else if v == "4021" { - 4021 - } else if v == "4022" { - 4022 - } else if v == "4023" { - 4023 - } else if v == "4024" { - 4024 - } else if v == "4025" { - 4025 - } else if v == "4026" { - 4026 - } else if v == "4027" { - 4027 - } else if v == "4028" { - 4028 - } else if v == "4029" { - 4029 - } else if v == "4030" { - 4030 - } else if v == "4031" { - 4031 - } else if v == "4032" { - 4032 - } else if v == "4033" { - 4033 - } else if v == "4034" { - 4034 - } else if v == "4035" { - 4035 - } else if v == "4036" { - 4036 - } else if v == "4037" { - 4037 - } else if v == "4038" { - 4038 - } else if v == "4039" { - 4039 - } else if v == "4040" { - 4040 - } else if v == "4041" { - 4041 - } else if v == "4042" { - 4042 - } else if v == "4043" { - 4043 - } else if v == "4044" { - 4044 - } else if v == "4045" { - 4045 - } else if v == "4046" { - 4046 - } else if v == "4047" { - 4047 - } else if v == "4048" { - 4048 - } else if v == "4049" { - 4049 - } else if v == "4050" { - 4050 - } else if v == "4051" { - 4051 - } else if v == "4052" { - 4052 - } else if v == "4053" { - 4053 - } else if v == "4054" { - 4054 - } else if v == "4055" { - 4055 - } else if v == "4056" { - 4056 - } else if v == "4057" { - 4057 - } else if v == "4058" { - 4058 - } else if v == "4059" { - 4059 - } else if v == "4060" { - 4060 - } else if v == "4061" { - 4061 - } else if v == "4062" { - 4062 - } else if v == "4063" { - 4063 - } else if v == "4064" { - 4064 - } else if v == "4065" { - 4065 - } else if v == "4066" { - 4066 - } else if v == "4067" { - 4067 - } else if v == "4068" { - 4068 - } else if v == "4069" { - 4069 - } else if v == "4070" { - 4070 - } else if v == "4071" { - 4071 - } else if v == "4072" { - 4072 - } else if v == "4073" { - 4073 - } else if v == "4074" { - 4074 - } else if v == "4075" { - 4075 - } else if v == "4076" { - 4076 - } else if v == "4077" { - 4077 - } else if v == "4078" { - 4078 - } else if v == "4079" { - 4079 - } else if v == "4080" { - 4080 - } else if v == "4081" { - 4081 - } else if v == "4082" { - 4082 - } else if v == "4083" { - 4083 - } else if v == "4084" { - 4084 - } else if v == "4085" { - 4085 - } else if v == "4086" { - 4086 - } else if v == "4087" { - 4087 - } else if v == "4088" { - 4088 - } else if v == "4089" { - 4089 - } else if v == "4090" { - 4090 - } else if v == "4091" { - 4091 - } else if v == "4092" { - 4092 - } else if v == "4093" { - 4093 - } else if v == "4094" { - 4094 - } else if v == "4095" { - 4095 - } else if v == "4096" { - 4096 - } else if v == "4097" { - 4097 - } else if v == "4098" { - 4098 - } else if v == "4099" { - 4099 - } else if v == "4100" { - 4100 - } else if v == "4101" { - 4101 - } else if v == "4102" { - 4102 - } else if v == "4103" { - 4103 - } else if v == "4104" { - 4104 - } else if v == "4105" { - 4105 - } else if v == "4106" { - 4106 - } else if v == "4107" { - 4107 - } else if v == "4108" { - 4108 - } else if v == "4109" { - 4109 - } else if v == "4110" { - 4110 - } else if v == "4111" { - 4111 - } else if v == "4112" { - 4112 - } else if v == "4113" { - 4113 - } else if v == "4114" { - 4114 - } else if v == "4115" { - 4115 - } else if v == "4116" { - 4116 - } else if v == "4117" { - 4117 - } else if v == "4118" { - 4118 - } else if v == "4119" { - 4119 - } else if v == "4120" { - 4120 - } else if v == "4121" { - 4121 - } else if v == "4122" { - 4122 - } else if v == "4123" { - 4123 - } else if v == "4124" { - 4124 - } else if v == "4125" { - 4125 - } else if v == "4126" { - 4126 - } else if v == "4127" { - 4127 - } else if v == "4128" { - 4128 - } else if v == "4129" { - 4129 - } else if v == "4130" { - 4130 - } else if v == "4131" { - 4131 - } else if v == "4132" { - 4132 - } else if v == "4133" { - 4133 - } else if v == "4134" { - 4134 - } else if v == "4135" { - 4135 - } else if v == "4136" { - 4136 - } else if v == "4137" { - 4137 - } else if v == "4138" { - 4138 - } else if v == "4139" { - 4139 - } else if v == "4140" { - 4140 - } else if v == "4141" { - 4141 - } else if v == "4142" { - 4142 - } else if v == "4143" { - 4143 - } else if v == "4144" { - 4144 - } else if v == "4145" { - 4145 - } else if v == "4146" { - 4146 - } else if v == "4147" { - 4147 - } else if v == "4148" { - 4148 - } else if v == "4149" { - 4149 - } else if v == "4150" { - 4150 - } else if v == "4151" { - 4151 - } else if v == "4152" { - 4152 - } else if v == "4153" { - 4153 - } else if v == "4154" { - 4154 - } else if v == "4155" { - 4155 - } else if v == "4156" { - 4156 - } else if v == "4157" { - 4157 - } else if v == "4158" { - 4158 - } else if v == "4159" { - 4159 - } else if v == "4160" { - 4160 - } else if v == "4161" { - 4161 - } else if v == "4162" { - 4162 - } else if v == "4163" { - 4163 - } else if v == "4164" { - 4164 - } else if v == "4165" { - 4165 - } else if v == "4166" { - 4166 - } else if v == "4167" { - 4167 - } else if v == "4168" { - 4168 - } else if v == "4169" { - 4169 - } else if v == "4170" { - 4170 - } else if v == "4171" { - 4171 - } else if v == "4172" { - 4172 - } else if v == "4173" { - 4173 - } else if v == "4174" { - 4174 - } else if v == "4175" { - 4175 - } else if v == "4176" { - 4176 - } else if v == "4177" { - 4177 - } else if v == "4178" { - 4178 - } else if v == "4179" { - 4179 - } else if v == "4180" { - 4180 - } else if v == "4181" { - 4181 - } else if v == "4182" { - 4182 - } else if v == "4183" { - 4183 - } else if v == "4184" { - 4184 - } else if v == "4185" { - 4185 - } else if v == "4186" { - 4186 - } else if v == "4187" { - 4187 - } else if v == "4188" { - 4188 - } else if v == "4189" { - 4189 - } else if v == "4190" { - 4190 - } else if v == "4191" { - 4191 - } else if v == "4192" { - 4192 - } else if v == "4193" { - 4193 - } else if v == "4194" { - 4194 - } else if v == "4195" { - 4195 - } else if v == "4196" { - 4196 - } else if v == "4197" { - 4197 - } else if v == "4198" { - 4198 - } else if v == "4199" { - 4199 - } else if v == "4200" { - 4200 - } else if v == "4201" { - 4201 - } else if v == "4202" { - 4202 - } else if v == "4203" { - 4203 - } else if v == "4204" { - 4204 - } else if v == "4205" { - 4205 - } else if v == "4206" { - 4206 - } else if v == "4207" { - 4207 - } else if v == "4208" { - 4208 - } else if v == "4209" { - 4209 - } else if v == "4210" { - 4210 - } else if v == "4211" { - 4211 - } else if v == "4212" { - 4212 - } else if v == "4213" { - 4213 - } else if v == "4214" { - 4214 - } else if v == "4215" { - 4215 - } else if v == "4216" { - 4216 - } else if v == "4217" { - 4217 - } else if v == "4218" { - 4218 - } else if v == "4219" { - 4219 - } else if v == "4220" { - 4220 - } else if v == "4221" { - 4221 - } else if v == "4222" { - 4222 - } else if v == "4223" { - 4223 - } else if v == "4224" { - 4224 - } else if v == "4225" { - 4225 - } else if v == "4226" { - 4226 - } else if v == "4227" { - 4227 - } else if v == "4228" { - 4228 - } else if v == "4229" { - 4229 - } else if v == "4230" { - 4230 - } else if v == "4231" { - 4231 - } else if v == "4232" { - 4232 - } else if v == "4233" { - 4233 - } else if v == "4234" { - 4234 - } else if v == "4235" { - 4235 - } else if v == "4236" { - 4236 - } else if v == "4237" { - 4237 - } else if v == "4238" { - 4238 - } else if v == "4239" { - 4239 - } else if v == "4240" { - 4240 - } else if v == "4241" { - 4241 - } else if v == "4242" { - 4242 - } else if v == "4243" { - 4243 - } else if v == "4244" { - 4244 - } else if v == "4245" { - 4245 - } else if v == "4246" { - 4246 - } else if v == "4247" { - 4247 - } else if v == "4248" { - 4248 - } else if v == "4249" { - 4249 - } else if v == "4250" { - 4250 - } else if v == "4251" { - 4251 - } else if v == "4252" { - 4252 - } else if v == "4253" { - 4253 - } else if v == "4254" { - 4254 - } else if v == "4255" { - 4255 - } else if v == "4256" { - 4256 - } else if v == "4257" { - 4257 - } else if v == "4258" { - 4258 - } else if v == "4259" { - 4259 - } else if v == "4260" { - 4260 - } else if v == "4261" { - 4261 - } else if v == "4262" { - 4262 - } else if v == "4263" { - 4263 - } else if v == "4264" { - 4264 - } else if v == "4265" { - 4265 - } else if v == "4266" { - 4266 - } else if v == "4267" { - 4267 - } else if v == "4268" { - 4268 - } else if v == "4269" { - 4269 - } else if v == "4270" { - 4270 - } else if v == "4271" { - 4271 - } else if v == "4272" { - 4272 - } else if v == "4273" { - 4273 - } else if v == "4274" { - 4274 - } else if v == "4275" { - 4275 - } else if v == "4276" { - 4276 - } else if v == "4277" { - 4277 - } else if v == "4278" { - 4278 - } else if v == "4279" { - 4279 - } else if v == "4280" { - 4280 - } else if v == "4281" { - 4281 - } else if v == "4282" { - 4282 - } else if v == "4283" { - 4283 - } else if v == "4284" { - 4284 - } else if v == "4285" { - 4285 - } else if v == "4286" { - 4286 - } else if v == "4287" { - 4287 - } else if v == "4288" { - 4288 - } else if v == "4289" { - 4289 - } else if v == "4290" { - 4290 - } else if v == "4291" { - 4291 - } else if v == "4292" { - 4292 - } else if v == "4293" { - 4293 - } else if v == "4294" { - 4294 - } else if v == "4295" { - 4295 - } else if v == "4296" { - 4296 - } else if v == "4297" { - 4297 - } else if v == "4298" { - 4298 - } else if v == "4299" { - 4299 - } else if v == "4300" { - 4300 - } else if v == "4301" { - 4301 - } else if v == "4302" { - 4302 - } else if v == "4303" { - 4303 - } else if v == "4304" { - 4304 - } else if v == "4305" { - 4305 - } else if v == "4306" { - 4306 - } else if v == "4307" { - 4307 - } else if v == "4308" { - 4308 - } else if v == "4309" { - 4309 - } else if v == "4310" { - 4310 - } else if v == "4311" { - 4311 - } else if v == "4312" { - 4312 - } else if v == "4313" { - 4313 - } else if v == "4314" { - 4314 - } else if v == "4315" { - 4315 - } else if v == "4316" { - 4316 - } else if v == "4317" { - 4317 - } else if v == "4318" { - 4318 - } else if v == "4319" { - 4319 - } else if v == "4320" { - 4320 - } else if v == "4321" { - 4321 - } else if v == "4322" { - 4322 - } else if v == "4323" { - 4323 - } else if v == "4324" { - 4324 - } else if v == "4325" { - 4325 - } else if v == "4326" { - 4326 - } else if v == "4327" { - 4327 - } else if v == "4328" { - 4328 - } else if v == "4329" { - 4329 - } else if v == "4330" { - 4330 - } else if v == "4331" { - 4331 - } else if v == "4332" { - 4332 - } else if v == "4333" { - 4333 - } else if v == "4334" { - 4334 - } else if v == "4335" { - 4335 - } else if v == "4336" { - 4336 - } else if v == "4337" { - 4337 - } else if v == "4338" { - 4338 - } else if v == "4339" { - 4339 - } else if v == "4340" { - 4340 - } else if v == "4341" { - 4341 - } else if v == "4342" { - 4342 - } else if v == "4343" { - 4343 - } else if v == "4344" { - 4344 - } else if v == "4345" { - 4345 - } else if v == "4346" { - 4346 - } else if v == "4347" { - 4347 - } else if v == "4348" { - 4348 - } else if v == "4349" { - 4349 - } else if v == "4350" { - 4350 - } else if v == "4351" { - 4351 - } else if v == "4352" { - 4352 - } else if v == "4353" { - 4353 - } else if v == "4354" { - 4354 - } else if v == "4355" { - 4355 - } else if v == "4356" { - 4356 - } else if v == "4357" { - 4357 - } else if v == "4358" { - 4358 - } else if v == "4359" { - 4359 - } else if v == "4360" { - 4360 - } else if v == "4361" { - 4361 - } else if v == "4362" { - 4362 - } else if v == "4363" { - 4363 - } else if v == "4364" { - 4364 - } else if v == "4365" { - 4365 - } else if v == "4366" { - 4366 - } else if v == "4367" { - 4367 - } else if v == "4368" { - 4368 - } else if v == "4369" { - 4369 - } else if v == "4370" { - 4370 - } else if v == "4371" { - 4371 - } else if v == "4372" { - 4372 - } else if v == "4373" { - 4373 - } else if v == "4374" { - 4374 - } else if v == "4375" { - 4375 - } else if v == "4376" { - 4376 - } else if v == "4377" { - 4377 - } else if v == "4378" { - 4378 - } else if v == "4379" { - 4379 - } else if v == "4380" { - 4380 - } else if v == "4381" { - 4381 - } else if v == "4382" { - 4382 - } else if v == "4383" { - 4383 - } else if v == "4384" { - 4384 - } else if v == "4385" { - 4385 - } else if v == "4386" { - 4386 - } else if v == "4387" { - 4387 - } else if v == "4388" { - 4388 - } else if v == "4389" { - 4389 - } else if v == "4390" { - 4390 - } else if v == "4391" { - 4391 - } else if v == "4392" { - 4392 - } else if v == "4393" { - 4393 - } else if v == "4394" { - 4394 - } else if v == "4395" { - 4395 - } else if v == "4396" { - 4396 - } else if v == "4397" { - 4397 - } else if v == "4398" { - 4398 - } else if v == "4399" { - 4399 - } else if v == "4400" { - 4400 - } else if v == "4401" { - 4401 - } else if v == "4402" { - 4402 - } else if v == "4403" { - 4403 - } else if v == "4404" { - 4404 - } else if v == "4405" { - 4405 - } else if v == "4406" { - 4406 - } else if v == "4407" { - 4407 - } else if v == "4408" { - 4408 - } else if v == "4409" { - 4409 - } else if v == "4410" { - 4410 - } else if v == "4411" { - 4411 - } else if v == "4412" { - 4412 - } else if v == "4413" { - 4413 - } else if v == "4414" { - 4414 - } else if v == "4415" { - 4415 - } else if v == "4416" { - 4416 - } else if v == "4417" { - 4417 - } else if v == "4418" { - 4418 - } else if v == "4419" { - 4419 - } else if v == "4420" { - 4420 - } else if v == "4421" { - 4421 - } else if v == "4422" { - 4422 - } else if v == "4423" { - 4423 - } else if v == "4424" { - 4424 - } else if v == "4425" { - 4425 - } else if v == "4426" { - 4426 - } else if v == "4427" { - 4427 - } else if v == "4428" { - 4428 - } else if v == "4429" { - 4429 - } else if v == "4430" { - 4430 - } else if v == "4431" { - 4431 - } else if v == "4432" { - 4432 - } else if v == "4433" { - 4433 - } else if v == "4434" { - 4434 - } else if v == "4435" { - 4435 - } else if v == "4436" { - 4436 - } else if v == "4437" { - 4437 - } else if v == "4438" { - 4438 - } else if v == "4439" { - 4439 - } else if v == "4440" { - 4440 - } else if v == "4441" { - 4441 - } else if v == "4442" { - 4442 - } else if v == "4443" { - 4443 - } else if v == "4444" { - 4444 - } else if v == "4445" { - 4445 - } else if v == "4446" { - 4446 - } else if v == "4447" { - 4447 - } else if v == "4448" { - 4448 - } else if v == "4449" { - 4449 - } else if v == "4450" { - 4450 - } else if v == "4451" { - 4451 - } else if v == "4452" { - 4452 - } else if v == "4453" { - 4453 - } else if v == "4454" { - 4454 - } else if v == "4455" { - 4455 - } else if v == "4456" { - 4456 - } else if v == "4457" { - 4457 - } else if v == "4458" { - 4458 - } else if v == "4459" { - 4459 - } else if v == "4460" { - 4460 - } else if v == "4461" { - 4461 - } else if v == "4462" { - 4462 - } else if v == "4463" { - 4463 - } else if v == "4464" { - 4464 - } else if v == "4465" { - 4465 - } else if v == "4466" { - 4466 - } else if v == "4467" { - 4467 - } else if v == "4468" { - 4468 - } else if v == "4469" { - 4469 - } else if v == "4470" { - 4470 - } else if v == "4471" { - 4471 - } else if v == "4472" { - 4472 - } else if v == "4473" { - 4473 - } else if v == "4474" { - 4474 - } else if v == "4475" { - 4475 - } else if v == "4476" { - 4476 - } else if v == "4477" { - 4477 - } else if v == "4478" { - 4478 - } else if v == "4479" { - 4479 - } else if v == "4480" { - 4480 - } else if v == "4481" { - 4481 - } else if v == "4482" { - 4482 - } else if v == "4483" { - 4483 - } else if v == "4484" { - 4484 - } else if v == "4485" { - 4485 - } else if v == "4486" { - 4486 - } else if v == "4487" { - 4487 - } else if v == "4488" { - 4488 - } else if v == "4489" { - 4489 - } else if v == "4490" { - 4490 - } else if v == "4491" { - 4491 - } else if v == "4492" { - 4492 - } else if v == "4493" { - 4493 - } else if v == "4494" { - 4494 - } else if v == "4495" { - 4495 - } else if v == "4496" { - 4496 - } else if v == "4497" { - 4497 - } else if v == "4498" { - 4498 - } else if v == "4499" { - 4499 - } else if v == "4500" { - 4500 - } else if v == "4501" { - 4501 - } else if v == "4502" { - 4502 - } else if v == "4503" { - 4503 - } else if v == "4504" { - 4504 - } else if v == "4505" { - 4505 - } else if v == "4506" { - 4506 - } else if v == "4507" { - 4507 - } else if v == "4508" { - 4508 - } else if v == "4509" { - 4509 - } else if v == "4510" { - 4510 - } else if v == "4511" { - 4511 - } else if v == "4512" { - 4512 - } else if v == "4513" { - 4513 - } else if v == "4514" { - 4514 - } else if v == "4515" { - 4515 - } else if v == "4516" { - 4516 - } else if v == "4517" { - 4517 - } else if v == "4518" { - 4518 - } else if v == "4519" { - 4519 - } else if v == "4520" { - 4520 - } else if v == "4521" { - 4521 - } else if v == "4522" { - 4522 - } else if v == "4523" { - 4523 - } else if v == "4524" { - 4524 - } else if v == "4525" { - 4525 - } else if v == "4526" { - 4526 - } else if v == "4527" { - 4527 - } else if v == "4528" { - 4528 - } else if v == "4529" { - 4529 - } else if v == "4530" { - 4530 - } else if v == "4531" { - 4531 - } else if v == "4532" { - 4532 - } else if v == "4533" { - 4533 - } else if v == "4534" { - 4534 - } else if v == "4535" { - 4535 - } else if v == "4536" { - 4536 - } else if v == "4537" { - 4537 - } else if v == "4538" { - 4538 - } else if v == "4539" { - 4539 - } else if v == "4540" { - 4540 - } else if v == "4541" { - 4541 - } else if v == "4542" { - 4542 - } else if v == "4543" { - 4543 - } else if v == "4544" { - 4544 - } else if v == "4545" { - 4545 - } else if v == "4546" { - 4546 - } else if v == "4547" { - 4547 - } else if v == "4548" { - 4548 - } else if v == "4549" { - 4549 - } else if v == "4550" { - 4550 - } else if v == "4551" { - 4551 - } else if v == "4552" { - 4552 - } else if v == "4553" { - 4553 - } else if v == "4554" { - 4554 - } else if v == "4555" { - 4555 - } else if v == "4556" { - 4556 - } else if v == "4557" { - 4557 - } else if v == "4558" { - 4558 - } else if v == "4559" { - 4559 - } else if v == "4560" { - 4560 - } else if v == "4561" { - 4561 - } else if v == "4562" { - 4562 - } else if v == "4563" { - 4563 - } else if v == "4564" { - 4564 - } else if v == "4565" { - 4565 - } else if v == "4566" { - 4566 - } else if v == "4567" { - 4567 - } else if v == "4568" { - 4568 - } else if v == "4569" { - 4569 - } else if v == "4570" { - 4570 - } else if v == "4571" { - 4571 - } else if v == "4572" { - 4572 - } else if v == "4573" { - 4573 - } else if v == "4574" { - 4574 - } else if v == "4575" { - 4575 - } else if v == "4576" { - 4576 - } else if v == "4577" { - 4577 - } else if v == "4578" { - 4578 - } else if v == "4579" { - 4579 - } else if v == "4580" { - 4580 - } else if v == "4581" { - 4581 - } else if v == "4582" { - 4582 - } else if v == "4583" { - 4583 - } else if v == "4584" { - 4584 - } else if v == "4585" { - 4585 - } else if v == "4586" { - 4586 - } else if v == "4587" { - 4587 - } else if v == "4588" { - 4588 - } else if v == "4589" { - 4589 - } else if v == "4590" { - 4590 - } else if v == "4591" { - 4591 - } else if v == "4592" { - 4592 - } else if v == "4593" { - 4593 - } else if v == "4594" { - 4594 - } else if v == "4595" { - 4595 - } else if v == "4596" { - 4596 - } else if v == "4597" { - 4597 - } else if v == "4598" { - 4598 - } else if v == "4599" { - 4599 - } else if v == "4600" { - 4600 - } else if v == "4601" { - 4601 - } else if v == "4602" { - 4602 - } else if v == "4603" { - 4603 - } else if v == "4604" { - 4604 - } else if v == "4605" { - 4605 - } else if v == "4606" { - 4606 - } else if v == "4607" { - 4607 - } else if v == "4608" { - 4608 - } else if v == "4609" { - 4609 - } else if v == "4610" { - 4610 - } else if v == "4611" { - 4611 - } else if v == "4612" { - 4612 - } else if v == "4613" { - 4613 - } else if v == "4614" { - 4614 - } else if v == "4615" { - 4615 - } else if v == "4616" { - 4616 - } else if v == "4617" { - 4617 - } else if v == "4618" { - 4618 - } else if v == "4619" { - 4619 - } else if v == "4620" { - 4620 - } else if v == "4621" { - 4621 - } else if v == "4622" { - 4622 - } else if v == "4623" { - 4623 - } else if v == "4624" { - 4624 - } else if v == "4625" { - 4625 - } else if v == "4626" { - 4626 - } else if v == "4627" { - 4627 - } else if v == "4628" { - 4628 - } else if v == "4629" { - 4629 - } else if v == "4630" { - 4630 - } else if v == "4631" { - 4631 - } else if v == "4632" { - 4632 - } else if v == "4633" { - 4633 - } else if v == "4634" { - 4634 - } else if v == "4635" { - 4635 - } else if v == "4636" { - 4636 - } else if v == "4637" { - 4637 - } else if v == "4638" { - 4638 - } else if v == "4639" { - 4639 - } else if v == "4640" { - 4640 - } else if v == "4641" { - 4641 - } else if v == "4642" { - 4642 - } else if v == "4643" { - 4643 - } else if v == "4644" { - 4644 - } else if v == "4645" { - 4645 - } else if v == "4646" { - 4646 - } else if v == "4647" { - 4647 - } else if v == "4648" { - 4648 - } else if v == "4649" { - 4649 - } else if v == "4650" { - 4650 - } else if v == "4651" { - 4651 - } else if v == "4652" { - 4652 - } else if v == "4653" { - 4653 - } else if v == "4654" { - 4654 - } else if v == "4655" { - 4655 - } else if v == "4656" { - 4656 - } else if v == "4657" { - 4657 - } else if v == "4658" { - 4658 - } else if v == "4659" { - 4659 - } else if v == "4660" { - 4660 - } else if v == "4661" { - 4661 - } else if v == "4662" { - 4662 - } else if v == "4663" { - 4663 - } else if v == "4664" { - 4664 - } else if v == "4665" { - 4665 - } else if v == "4666" { - 4666 - } else if v == "4667" { - 4667 - } else if v == "4668" { - 4668 - } else if v == "4669" { - 4669 - } else if v == "4670" { - 4670 - } else if v == "4671" { - 4671 - } else if v == "4672" { - 4672 - } else if v == "4673" { - 4673 - } else if v == "4674" { - 4674 - } else if v == "4675" { - 4675 - } else if v == "4676" { - 4676 - } else if v == "4677" { - 4677 - } else if v == "4678" { - 4678 - } else if v == "4679" { - 4679 - } else if v == "4680" { - 4680 - } else if v == "4681" { - 4681 - } else if v == "4682" { - 4682 - } else if v == "4683" { - 4683 - } else if v == "4684" { - 4684 - } else if v == "4685" { - 4685 - } else if v == "4686" { - 4686 - } else if v == "4687" { - 4687 - } else if v == "4688" { - 4688 - } else if v == "4689" { - 4689 - } else if v == "4690" { - 4690 - } else if v == "4691" { - 4691 - } else if v == "4692" { - 4692 - } else if v == "4693" { - 4693 - } else if v == "4694" { - 4694 - } else if v == "4695" { - 4695 - } else if v == "4696" { - 4696 - } else if v == "4697" { - 4697 - } else if v == "4698" { - 4698 - } else if v == "4699" { - 4699 - } else if v == "4700" { - 4700 - } else if v == "4701" { - 4701 - } else if v == "4702" { - 4702 - } else if v == "4703" { - 4703 - } else if v == "4704" { - 4704 - } else if v == "4705" { - 4705 - } else if v == "4706" { - 4706 - } else if v == "4707" { - 4707 - } else if v == "4708" { - 4708 - } else if v == "4709" { - 4709 - } else if v == "4710" { - 4710 - } else if v == "4711" { - 4711 - } else if v == "4712" { - 4712 - } else if v == "4713" { - 4713 - } else if v == "4714" { - 4714 - } else if v == "4715" { - 4715 - } else if v == "4716" { - 4716 - } else if v == "4717" { - 4717 - } else if v == "4718" { - 4718 - } else if v == "4719" { - 4719 - } else if v == "4720" { - 4720 - } else if v == "4721" { - 4721 - } else if v == "4722" { - 4722 - } else if v == "4723" { - 4723 - } else if v == "4724" { - 4724 - } else if v == "4725" { - 4725 - } else if v == "4726" { - 4726 - } else if v == "4727" { - 4727 - } else if v == "4728" { - 4728 - } else if v == "4729" { - 4729 - } else if v == "4730" { - 4730 - } else if v == "4731" { - 4731 - } else if v == "4732" { - 4732 - } else if v == "4733" { - 4733 - } else if v == "4734" { - 4734 - } else if v == "4735" { - 4735 - } else if v == "4736" { - 4736 - } else if v == "4737" { - 4737 - } else if v == "4738" { - 4738 - } else if v == "4739" { - 4739 - } else if v == "4740" { - 4740 - } else if v == "4741" { - 4741 - } else if v == "4742" { - 4742 - } else if v == "4743" { - 4743 - } else if v == "4744" { - 4744 - } else if v == "4745" { - 4745 - } else if v == "4746" { - 4746 - } else if v == "4747" { - 4747 - } else if v == "4748" { - 4748 - } else if v == "4749" { - 4749 - } else if v == "4750" { - 4750 - } else if v == "4751" { - 4751 - } else if v == "4752" { - 4752 - } else if v == "4753" { - 4753 - } else if v == "4754" { - 4754 - } else if v == "4755" { - 4755 - } else if v == "4756" { - 4756 - } else if v == "4757" { - 4757 - } else if v == "4758" { - 4758 - } else if v == "4759" { - 4759 - } else if v == "4760" { - 4760 - } else if v == "4761" { - 4761 - } else if v == "4762" { - 4762 - } else if v == "4763" { - 4763 - } else if v == "4764" { - 4764 - } else if v == "4765" { - 4765 - } else if v == "4766" { - 4766 - } else if v == "4767" { - 4767 - } else if v == "4768" { - 4768 - } else if v == "4769" { - 4769 - } else if v == "4770" { - 4770 - } else if v == "4771" { - 4771 - } else if v == "4772" { - 4772 - } else if v == "4773" { - 4773 - } else if v == "4774" { - 4774 - } else if v == "4775" { - 4775 - } else if v == "4776" { - 4776 - } else if v == "4777" { - 4777 - } else if v == "4778" { - 4778 - } else if v == "4779" { - 4779 - } else if v == "4780" { - 4780 - } else if v == "4781" { - 4781 - } else if v == "4782" { - 4782 - } else if v == "4783" { - 4783 - } else if v == "4784" { - 4784 - } else if v == "4785" { - 4785 - } else if v == "4786" { - 4786 - } else if v == "4787" { - 4787 - } else if v == "4788" { - 4788 - } else if v == "4789" { - 4789 - } else if v == "4790" { - 4790 - } else if v == "4791" { - 4791 - } else if v == "4792" { - 4792 - } else if v == "4793" { - 4793 - } else if v == "4794" { - 4794 - } else if v == "4795" { - 4795 - } else if v == "4796" { - 4796 - } else if v == "4797" { - 4797 - } else if v == "4798" { - 4798 - } else if v == "4799" { - 4799 - } else if v == "4800" { - 4800 - } else if v == "4801" { - 4801 - } else if v == "4802" { - 4802 - } else if v == "4803" { - 4803 - } else if v == "4804" { - 4804 - } else if v == "4805" { - 4805 - } else if v == "4806" { - 4806 - } else if v == "4807" { - 4807 - } else if v == "4808" { - 4808 - } else if v == "4809" { - 4809 - } else if v == "4810" { - 4810 - } else if v == "4811" { - 4811 - } else if v == "4812" { - 4812 - } else if v == "4813" { - 4813 - } else if v == "4814" { - 4814 - } else if v == "4815" { - 4815 - } else if v == "4816" { - 4816 - } else if v == "4817" { - 4817 - } else if v == "4818" { - 4818 - } else if v == "4819" { - 4819 - } else if v == "4820" { - 4820 - } else if v == "4821" { - 4821 - } else if v == "4822" { - 4822 - } else if v == "4823" { - 4823 - } else if v == "4824" { - 4824 - } else if v == "4825" { - 4825 - } else if v == "4826" { - 4826 - } else if v == "4827" { - 4827 - } else if v == "4828" { - 4828 - } else if v == "4829" { - 4829 - } else if v == "4830" { - 4830 - } else if v == "4831" { - 4831 - } else if v == "4832" { - 4832 - } else if v == "4833" { - 4833 - } else if v == "4834" { - 4834 - } else if v == "4835" { - 4835 - } else if v == "4836" { - 4836 - } else if v == "4837" { - 4837 - } else if v == "4838" { - 4838 - } else if v == "4839" { - 4839 - } else if v == "4840" { - 4840 - } else if v == "4841" { - 4841 - } else if v == "4842" { - 4842 - } else if v == "4843" { - 4843 - } else if v == "4844" { - 4844 - } else if v == "4845" { - 4845 - } else if v == "4846" { - 4846 - } else if v == "4847" { - 4847 - } else if v == "4848" { - 4848 - } else if v == "4849" { - 4849 - } else if v == "4850" { - 4850 - } else if v == "4851" { - 4851 - } else if v == "4852" { - 4852 - } else if v == "4853" { - 4853 - } else if v == "4854" { - 4854 - } else if v == "4855" { - 4855 - } else if v == "4856" { - 4856 - } else if v == "4857" { - 4857 - } else if v == "4858" { - 4858 - } else if v == "4859" { - 4859 - } else if v == "4860" { - 4860 - } else if v == "4861" { - 4861 - } else if v == "4862" { - 4862 - } else if v == "4863" { - 4863 - } else if v == "4864" { - 4864 - } else if v == "4865" { - 4865 - } else if v == "4866" { - 4866 - } else if v == "4867" { - 4867 - } else if v == "4868" { - 4868 - } else if v == "4869" { - 4869 - } else if v == "4870" { - 4870 - } else if v == "4871" { - 4871 - } else if v == "4872" { - 4872 - } else if v == "4873" { - 4873 - } else if v == "4874" { - 4874 - } else if v == "4875" { - 4875 - } else if v == "4876" { - 4876 - } else if v == "4877" { - 4877 - } else if v == "4878" { - 4878 - } else if v == "4879" { - 4879 - } else if v == "4880" { - 4880 - } else if v == "4881" { - 4881 - } else if v == "4882" { - 4882 - } else if v == "4883" { - 4883 - } else if v == "4884" { - 4884 - } else if v == "4885" { - 4885 - } else if v == "4886" { - 4886 - } else if v == "4887" { - 4887 - } else if v == "4888" { - 4888 - } else if v == "4889" { - 4889 - } else if v == "4890" { - 4890 - } else if v == "4891" { - 4891 - } else if v == "4892" { - 4892 - } else if v == "4893" { - 4893 - } else if v == "4894" { - 4894 - } else if v == "4895" { - 4895 - } else if v == "4896" { - 4896 - } else if v == "4897" { - 4897 - } else if v == "4898" { - 4898 - } else if v == "4899" { - 4899 - } else if v == "4900" { - 4900 - } else if v == "4901" { - 4901 - } else if v == "4902" { - 4902 - } else if v == "4903" { - 4903 - } else if v == "4904" { - 4904 - } else if v == "4905" { - 4905 - } else if v == "4906" { - 4906 - } else if v == "4907" { - 4907 - } else if v == "4908" { - 4908 - } else if v == "4909" { - 4909 - } else if v == "4910" { - 4910 - } else if v == "4911" { - 4911 - } else if v == "4912" { - 4912 - } else if v == "4913" { - 4913 - } else if v == "4914" { - 4914 - } else if v == "4915" { - 4915 - } else if v == "4916" { - 4916 - } else if v == "4917" { - 4917 - } else if v == "4918" { - 4918 - } else if v == "4919" { - 4919 - } else if v == "4920" { - 4920 - } else if v == "4921" { - 4921 - } else if v == "4922" { - 4922 - } else if v == "4923" { - 4923 - } else if v == "4924" { - 4924 - } else if v == "4925" { - 4925 - } else if v == "4926" { - 4926 - } else if v == "4927" { - 4927 - } else if v == "4928" { - 4928 - } else if v == "4929" { - 4929 - } else if v == "4930" { - 4930 - } else if v == "4931" { - 4931 - } else if v == "4932" { - 4932 - } else if v == "4933" { - 4933 - } else if v == "4934" { - 4934 - } else if v == "4935" { - 4935 - } else if v == "4936" { - 4936 - } else if v == "4937" { - 4937 - } else if v == "4938" { - 4938 - } else if v == "4939" { - 4939 - } else if v == "4940" { - 4940 - } else if v == "4941" { - 4941 - } else if v == "4942" { - 4942 - } else if v == "4943" { - 4943 - } else if v == "4944" { - 4944 - } else if v == "4945" { - 4945 - } else if v == "4946" { - 4946 - } else if v == "4947" { - 4947 - } else if v == "4948" { - 4948 - } else if v == "4949" { - 4949 - } else if v == "4950" { - 4950 - } else if v == "4951" { - 4951 - } else if v == "4952" { - 4952 - } else if v == "4953" { - 4953 - } else if v == "4954" { - 4954 - } else if v == "4955" { - 4955 - } else if v == "4956" { - 4956 - } else if v == "4957" { - 4957 - } else if v == "4958" { - 4958 - } else if v == "4959" { - 4959 - } else if v == "4960" { - 4960 - } else if v == "4961" { - 4961 - } else if v == "4962" { - 4962 - } else if v == "4963" { - 4963 - } else if v == "4964" { - 4964 - } else if v == "4965" { - 4965 - } else if v == "4966" { - 4966 - } else if v == "4967" { - 4967 - } else if v == "4968" { - 4968 - } else if v == "4969" { - 4969 - } else if v == "4970" { - 4970 - } else if v == "4971" { - 4971 - } else if v == "4972" { - 4972 - } else if v == "4973" { - 4973 - } else if v == "4974" { - 4974 - } else if v == "4975" { - 4975 - } else if v == "4976" { - 4976 - } else if v == "4977" { - 4977 - } else if v == "4978" { - 4978 - } else if v == "4979" { - 4979 - } else if v == "4980" { - 4980 - } else if v == "4981" { - 4981 - } else if v == "4982" { - 4982 - } else if v == "4983" { - 4983 - } else if v == "4984" { - 4984 - } else if v == "4985" { - 4985 - } else if v == "4986" { - 4986 - } else if v == "4987" { - 4987 - } else if v == "4988" { - 4988 - } else if v == "4989" { - 4989 - } else if v == "4990" { - 4990 - } else if v == "4991" { - 4991 - } else if v == "4992" { - 4992 - } else if v == "4993" { - 4993 - } else if v == "4994" { - 4994 - } else if v == "4995" { - 4995 - } else if v == "4996" { - 4996 - } else if v == "4997" { - 4997 - } else if v == "4998" { - 4998 - } else if v == "4999" { - 4999 - } else if v == "5000" { - 5000 - } else if v == "5001" { - 5001 - } else if v == "5002" { - 5002 - } else if v == "5003" { - 5003 - } else if v == "5004" { - 5004 - } else if v == "5005" { - 5005 - } else if v == "5006" { - 5006 - } else if v == "5007" { - 5007 - } else if v == "5008" { - 5008 - } else if v == "5009" { - 5009 - } else if v == "5010" { - 5010 - } else if v == "5011" { - 5011 - } else if v == "5012" { - 5012 - } else if v == "5013" { - 5013 - } else if v == "5014" { - 5014 - } else if v == "5015" { - 5015 - } else if v == "5016" { - 5016 - } else if v == "5017" { - 5017 - } else if v == "5018" { - 5018 - } else if v == "5019" { - 5019 - } else if v == "5020" { - 5020 - } else if v == "5021" { - 5021 - } else if v == "5022" { - 5022 - } else if v == "5023" { - 5023 - } else if v == "5024" { - 5024 - } else if v == "5025" { - 5025 - } else if v == "5026" { - 5026 - } else if v == "5027" { - 5027 - } else if v == "5028" { - 5028 - } else if v == "5029" { - 5029 - } else if v == "5030" { - 5030 - } else if v == "5031" { - 5031 - } else if v == "5032" { - 5032 - } else if v == "5033" { - 5033 - } else if v == "5034" { - 5034 - } else if v == "5035" { - 5035 - } else if v == "5036" { - 5036 - } else if v == "5037" { - 5037 - } else if v == "5038" { - 5038 - } else if v == "5039" { - 5039 - } else if v == "5040" { - 5040 - } else if v == "5041" { - 5041 - } else if v == "5042" { - 5042 - } else if v == "5043" { - 5043 - } else if v == "5044" { - 5044 - } else if v == "5045" { - 5045 - } else if v == "5046" { - 5046 - } else if v == "5047" { - 5047 - } else if v == "5048" { - 5048 - } else if v == "5049" { - 5049 - } else if v == "5050" { - 5050 - } else if v == "5051" { - 5051 - } else if v == "5052" { - 5052 - } else if v == "5053" { - 5053 - } else if v == "5054" { - 5054 - } else if v == "5055" { - 5055 - } else if v == "5056" { - 5056 - } else if v == "5057" { - 5057 - } else if v == "5058" { - 5058 - } else if v == "5059" { - 5059 - } else if v == "5060" { - 5060 - } else if v == "5061" { - 5061 - } else if v == "5062" { - 5062 - } else if v == "5063" { - 5063 - } else if v == "5064" { - 5064 - } else if v == "5065" { - 5065 - } else if v == "5066" { - 5066 - } else if v == "5067" { - 5067 - } else if v == "5068" { - 5068 - } else if v == "5069" { - 5069 - } else if v == "5070" { - 5070 - } else if v == "5071" { - 5071 - } else if v == "5072" { - 5072 - } else if v == "5073" { - 5073 - } else if v == "5074" { - 5074 - } else if v == "5075" { - 5075 - } else if v == "5076" { - 5076 - } else if v == "5077" { - 5077 - } else if v == "5078" { - 5078 - } else if v == "5079" { - 5079 - } else if v == "5080" { - 5080 - } else if v == "5081" { - 5081 - } else if v == "5082" { - 5082 - } else if v == "5083" { - 5083 - } else if v == "5084" { - 5084 - } else if v == "5085" { - 5085 - } else if v == "5086" { - 5086 - } else if v == "5087" { - 5087 - } else if v == "5088" { - 5088 - } else if v == "5089" { - 5089 - } else if v == "5090" { - 5090 - } else if v == "5091" { - 5091 - } else if v == "5092" { - 5092 - } else if v == "5093" { - 5093 - } else if v == "5094" { - 5094 - } else if v == "5095" { - 5095 - } else if v == "5096" { - 5096 - } else if v == "5097" { - 5097 - } else if v == "5098" { - 5098 - } else if v == "5099" { - 5099 - } else if v == "5100" { - 5100 - } else if v == "5101" { - 5101 - } else if v == "5102" { - 5102 - } else if v == "5103" { - 5103 - } else if v == "5104" { - 5104 - } else if v == "5105" { - 5105 - } else if v == "5106" { - 5106 - } else if v == "5107" { - 5107 - } else if v == "5108" { - 5108 - } else if v == "5109" { - 5109 - } else if v == "5110" { - 5110 - } else if v == "5111" { - 5111 - } else if v == "5112" { - 5112 - } else if v == "5113" { - 5113 - } else if v == "5114" { - 5114 - } else if v == "5115" { - 5115 - } else if v == "5116" { - 5116 - } else if v == "5117" { - 5117 - } else if v == "5118" { - 5118 - } else if v == "5119" { - 5119 - } else if v == "5120" { - 5120 - } else if v == "5121" { - 5121 - } else if v == "5122" { - 5122 - } else if v == "5123" { - 5123 - } else if v == "5124" { - 5124 - } else if v == "5125" { - 5125 - } else if v == "5126" { - 5126 - } else if v == "5127" { - 5127 - } else if v == "5128" { - 5128 - } else if v == "5129" { - 5129 - } else if v == "5130" { - 5130 - } else if v == "5131" { - 5131 - } else if v == "5132" { - 5132 - } else if v == "5133" { - 5133 - } else if v == "5134" { - 5134 - } else if v == "5135" { - 5135 - } else if v == "5136" { - 5136 - } else if v == "5137" { - 5137 - } else if v == "5138" { - 5138 - } else if v == "5139" { - 5139 - } else if v == "5140" { - 5140 - } else if v == "5141" { - 5141 - } else if v == "5142" { - 5142 - } else if v == "5143" { - 5143 - } else if v == "5144" { - 5144 - } else if v == "5145" { - 5145 - } else if v == "5146" { - 5146 - } else if v == "5147" { - 5147 - } else if v == "5148" { - 5148 - } else if v == "5149" { - 5149 - } else if v == "5150" { - 5150 - } else if v == "5151" { - 5151 - } else if v == "5152" { - 5152 - } else if v == "5153" { - 5153 - } else if v == "5154" { - 5154 - } else if v == "5155" { - 5155 - } else if v == "5156" { - 5156 - } else if v == "5157" { - 5157 - } else if v == "5158" { - 5158 - } else if v == "5159" { - 5159 - } else if v == "5160" { - 5160 - } else if v == "5161" { - 5161 - } else if v == "5162" { - 5162 - } else if v == "5163" { - 5163 - } else if v == "5164" { - 5164 - } else if v == "5165" { - 5165 - } else if v == "5166" { - 5166 - } else if v == "5167" { - 5167 - } else if v == "5168" { - 5168 - } else if v == "5169" { - 5169 - } else if v == "5170" { - 5170 - } else if v == "5171" { - 5171 - } else if v == "5172" { - 5172 - } else if v == "5173" { - 5173 - } else if v == "5174" { - 5174 - } else if v == "5175" { - 5175 - } else if v == "5176" { - 5176 - } else if v == "5177" { - 5177 - } else if v == "5178" { - 5178 - } else if v == "5179" { - 5179 - } else if v == "5180" { - 5180 - } else if v == "5181" { - 5181 - } else if v == "5182" { - 5182 - } else if v == "5183" { - 5183 - } else if v == "5184" { - 5184 - } else if v == "5185" { - 5185 - } else if v == "5186" { - 5186 - } else if v == "5187" { - 5187 - } else if v == "5188" { - 5188 - } else if v == "5189" { - 5189 - } else if v == "5190" { - 5190 - } else if v == "5191" { - 5191 - } else if v == "5192" { - 5192 - } else if v == "5193" { - 5193 - } else if v == "5194" { - 5194 - } else if v == "5195" { - 5195 - } else if v == "5196" { - 5196 - } else if v == "5197" { - 5197 - } else if v == "5198" { - 5198 - } else if v == "5199" { - 5199 - } else if v == "5200" { - 5200 - } else if v == "5201" { - 5201 - } else if v == "5202" { - 5202 - } else if v == "5203" { - 5203 - } else if v == "5204" { - 5204 - } else if v == "5205" { - 5205 - } else { - 5206 - } -} diff --git a/tests/ui/iterators/into_iter-when-iter-was-intended.fixed b/tests/ui/iterators/into_iter-when-iter-was-intended.fixed new file mode 100644 index 000000000000..e841b1605f11 --- /dev/null +++ b/tests/ui/iterators/into_iter-when-iter-was-intended.fixed @@ -0,0 +1,10 @@ +//@ run-rustfix +//@ edition:2021 +// Suggest using the right `IntoIterator` method. #68095 +fn main() { + let _a = [0, 1, 2].iter().chain([3, 4, 5].iter()); //~ ERROR E0271 + let _b = [0, 1, 2].into_iter().chain([3, 4, 5].into_iter()); //~ ERROR E0271 + // These don't have appropriate suggestions yet. + // let c = [0, 1, 2].iter().chain([3, 4, 5]); + // let d = [0, 1, 2].iter().chain(vec![3, 4, 5]); +} diff --git a/tests/ui/iterators/into_iter-when-iter-was-intended.rs b/tests/ui/iterators/into_iter-when-iter-was-intended.rs new file mode 100644 index 000000000000..8d4376aa0ae6 --- /dev/null +++ b/tests/ui/iterators/into_iter-when-iter-was-intended.rs @@ -0,0 +1,10 @@ +//@ run-rustfix +//@ edition:2021 +// Suggest using the right `IntoIterator` method. #68095 +fn main() { + let _a = [0, 1, 2].iter().chain([3, 4, 5].into_iter()); //~ ERROR E0271 + let _b = [0, 1, 2].into_iter().chain([3, 4, 5].iter()); //~ ERROR E0271 + // These don't have appropriate suggestions yet. + // let c = [0, 1, 2].iter().chain([3, 4, 5]); + // let d = [0, 1, 2].iter().chain(vec![3, 4, 5]); +} diff --git a/tests/ui/iterators/into_iter-when-iter-was-intended.stderr b/tests/ui/iterators/into_iter-when-iter-was-intended.stderr new file mode 100644 index 000000000000..f26db9781b13 --- /dev/null +++ b/tests/ui/iterators/into_iter-when-iter-was-intended.stderr @@ -0,0 +1,48 @@ +error[E0271]: type mismatch resolving ` as IntoIterator>::Item == &{integer}` + --> $DIR/into_iter-when-iter-was-intended.rs:5:37 + | +LL | let _a = [0, 1, 2].iter().chain([3, 4, 5].into_iter()); + | ----- ^^^^^^^^^^^^^^^^^^^^^ expected `&{integer}`, found integer + | | + | required by a bound introduced by this call + | +note: the method call chain might not have had the expected associated types + --> $DIR/into_iter-when-iter-was-intended.rs:5:47 + | +LL | let _a = [0, 1, 2].iter().chain([3, 4, 5].into_iter()); + | --------- ^^^^^^^^^^^ `IntoIterator::Item` is `{integer}` here + | | + | this expression has type `[{integer}; 3]` +note: required by a bound in `std::iter::Iterator::chain` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL +help: consider not consuming the `[{integer}; 3]` to construct the `Iterator` + | +LL - let _a = [0, 1, 2].iter().chain([3, 4, 5].into_iter()); +LL + let _a = [0, 1, 2].iter().chain([3, 4, 5].iter()); + | + +error[E0271]: type mismatch resolving ` as IntoIterator>::Item == {integer}` + --> $DIR/into_iter-when-iter-was-intended.rs:6:42 + | +LL | let _b = [0, 1, 2].into_iter().chain([3, 4, 5].iter()); + | ----- ^^^^^^^^^^^^^^^^ expected integer, found `&{integer}` + | | + | required by a bound introduced by this call + | +note: the method call chain might not have had the expected associated types + --> $DIR/into_iter-when-iter-was-intended.rs:6:52 + | +LL | let _b = [0, 1, 2].into_iter().chain([3, 4, 5].iter()); + | --------- ^^^^^^ `IntoIterator::Item` is `&{integer}` here + | | + | this expression has type `[{integer}; 3]` +note: required by a bound in `std::iter::Iterator::chain` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL +help: consider consuming the `&[{integer}]` to construct the `Iterator` + | +LL | let _b = [0, 1, 2].into_iter().chain([3, 4, 5].into_iter()); + | +++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr index bef4cb6b0a1b..99bff6b450b5 100644 --- a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr @@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:14:10 | @@ -72,10 +76,14 @@ LL | .sum::(), = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:23:14 | @@ -109,10 +117,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:27:38 | diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr index 638287ed1c64..c94b716e3131 100644 --- a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr @@ -9,10 +9,14 @@ LL | let x = Some(()).iter().map(|()| 1).sum::(); = help: the trait `Sum<{integer}>` is not implemented for `f32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `f32` implements `Sum<&f32>` | = note: `f32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `f32` implements `Sum<&f32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 0fd9d3999966..7f0c154e255a 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -35,10 +35,14 @@ LL | println!("{}", scores.sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:12:10 | @@ -71,10 +75,14 @@ LL | .sum::(), = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:25:14 | @@ -114,10 +122,14 @@ LL | .sum::(), = help: the trait `Sum` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:33:14 | @@ -148,10 +160,14 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::()); = help: the trait `Sum<()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:38:38 | @@ -180,10 +196,14 @@ LL | println!("{}", vec![(), ()].iter().sum::()); = help: the trait `Sum<&()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:39:33 | diff --git a/tests/ui/iterators/iter-cloned-type-inference.rs b/tests/ui/iterators/iter-cloned-type-inference.rs index 10f955881188..3957c99cea32 100644 --- a/tests/ui/iterators/iter-cloned-type-inference.rs +++ b/tests/ui/iterators/iter-cloned-type-inference.rs @@ -1,11 +1,7 @@ //@ run-pass -#![allow(stable_features)] - // Test to see that the element type of .cloned() can be inferred // properly. Previously this would fail to deduce the type of `sum`. -#![feature(iter_arith)] - fn square_sum(v: &[i64]) -> i64 { let sum: i64 = v.iter().cloned().sum(); sum * sum diff --git a/tests/ui/iterators/iter-filter-count-debug-check.rs b/tests/ui/iterators/iter-filter-count-debug-check.rs new file mode 100644 index 000000000000..6e3a3f73920e --- /dev/null +++ b/tests/ui/iterators/iter-filter-count-debug-check.rs @@ -0,0 +1,34 @@ +//@ run-pass +//@ needs-unwind +//@ ignore-backends: gcc +//@ compile-flags: -C overflow-checks + +use std::panic; + +struct Lies(usize); + +impl Iterator for Lies { + type Item = usize; + + fn next(&mut self) -> Option { + if self.0 == 0 { + None + } else { + self.0 -= 1; + Some(self.0) + } + } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(2)) + } +} + +fn main() { + let r = panic::catch_unwind(|| { + // This returns more items than its `size_hint` said was possible, + // which `Filter::count` detects via `overflow-checks`. + let _ = Lies(10).filter(|&x| x > 3).count(); + }); + assert!(r.is_err()); +} diff --git a/tests/ui/iterators/iter-macro-not-async-closure.stderr b/tests/ui/iterators/iter-macro-not-async-closure.stderr index 2f0343a2d0d6..906ebd482fb6 100644 --- a/tests/ui/iterators/iter-macro-not-async-closure.stderr +++ b/tests/ui/iterators/iter-macro-not-async-closure.stderr @@ -35,7 +35,6 @@ note: required by a bound in `call_async_once` | LL | async fn call_async_once(f: impl AsyncFnOnce()) { | ^^^^^^^^^^^^^ required by this bound in `call_async_once` - = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `{gen closure@$DIR/iter-macro-not-async-closure.rs:19:21: 19:28}: AsyncFnOnce()` is not satisfied --> $DIR/iter-macro-not-async-closure.rs:25:13 @@ -48,7 +47,6 @@ note: required by a bound in `call_async_once` | LL | async fn call_async_once(f: impl AsyncFnOnce()) { | ^^^^^^^^^^^^^ required by this bound in `call_async_once` - = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `{gen closure@$DIR/iter-macro-not-async-closure.rs:19:21: 19:28}: AsyncFnOnce()` is not satisfied --> $DIR/iter-macro-not-async-closure.rs:30:5 diff --git a/tests/ui/iterators/iterator-type-inference-sum-15673.rs b/tests/ui/iterators/iterator-type-inference-sum-15673.rs index aee027927f2f..4b75503df10e 100644 --- a/tests/ui/iterators/iterator-type-inference-sum-15673.rs +++ b/tests/ui/iterators/iterator-type-inference-sum-15673.rs @@ -1,8 +1,5 @@ // https://github.com/rust-lang/rust/issues/15673 //@ run-pass -#![allow(stable_features)] - -#![feature(iter_arith)] fn main() { let x: [u64; 3] = [1, 2, 3]; diff --git a/tests/ui/keyword/keyword-super-as-identifier.rs b/tests/ui/keyword/keyword-super-as-identifier.rs index 02c1b27b08a9..0aeb224e183b 100644 --- a/tests/ui/keyword/keyword-super-as-identifier.rs +++ b/tests/ui/keyword/keyword-super-as-identifier.rs @@ -1,3 +1,3 @@ fn main() { - let super = 22; //~ ERROR failed to resolve: there are too many leading `super` keywords + let super = 22; //~ ERROR too many leading `super` keywords } diff --git a/tests/ui/keyword/keyword-super-as-identifier.stderr b/tests/ui/keyword/keyword-super-as-identifier.stderr index bfb27c143ff7..d8609c6bcbe8 100644 --- a/tests/ui/keyword/keyword-super-as-identifier.stderr +++ b/tests/ui/keyword/keyword-super-as-identifier.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: too many leading `super` keywords --> $DIR/keyword-super-as-identifier.rs:2:9 | LL | let super = 22; diff --git a/tests/ui/keyword/keyword-super.rs b/tests/ui/keyword/keyword-super.rs index c121a6c1050e..c21149a846fe 100644 --- a/tests/ui/keyword/keyword-super.rs +++ b/tests/ui/keyword/keyword-super.rs @@ -1,3 +1,3 @@ fn main() { - let super: isize; //~ ERROR failed to resolve: there are too many leading `super` keywords + let super: isize; //~ ERROR: too many leading `super` keywords } diff --git a/tests/ui/keyword/keyword-super.stderr b/tests/ui/keyword/keyword-super.stderr index bf595442c3b8..69af7da09376 100644 --- a/tests/ui/keyword/keyword-super.stderr +++ b/tests/ui/keyword/keyword-super.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: too many leading `super` keywords --> $DIR/keyword-super.rs:2:9 | LL | let super: isize; diff --git a/tests/ui/kindck/kindck-send-object.stderr b/tests/ui/kindck/kindck-send-object.stderr index 0e2ff1730c8d..b71d4029350e 100644 --- a/tests/ui/kindck/kindck-send-object.stderr +++ b/tests/ui/kindck/kindck-send-object.stderr @@ -19,7 +19,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` - = note: required for `Unique` to implement `Send` + = note: required for `std::ptr::Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr index e3ff2eb9ff4c..2184ae704673 100644 --- a/tests/ui/kindck/kindck-send-object1.stderr +++ b/tests/ui/kindck/kindck-send-object1.stderr @@ -19,7 +19,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `(dyn Dummy + 'a)` - = note: required for `Unique<(dyn Dummy + 'a)>` to implement `Send` + = note: required for `std::ptr::Unique<(dyn Dummy + 'a)>` to implement `Send` note: required because it appears within the type `Box<(dyn Dummy + 'a)>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/kindck/kindck-send-object2.stderr b/tests/ui/kindck/kindck-send-object2.stderr index 8898bf5b3fab..52a7055b4229 100644 --- a/tests/ui/kindck/kindck-send-object2.stderr +++ b/tests/ui/kindck/kindck-send-object2.stderr @@ -19,7 +19,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `dyn Dummy` - = note: required for `Unique` to implement `Send` + = note: required for `std::ptr::Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/kindck/kindck-send-owned.stderr b/tests/ui/kindck/kindck-send-owned.stderr index 860a9391bbb0..c433d80cf140 100644 --- a/tests/ui/kindck/kindck-send-owned.stderr +++ b/tests/ui/kindck/kindck-send-owned.stderr @@ -5,7 +5,7 @@ LL | assert_send::>(); | ^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely | = help: the trait `Send` is not implemented for `*mut u8` - = note: required for `Unique<*mut u8>` to implement `Send` + = note: required for `std::ptr::Unique<*mut u8>` to implement `Send` note: required because it appears within the type `Box<*mut u8>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `assert_send` diff --git a/tests/ui/label/undeclared-label-span.rs b/tests/ui/label/undeclared-label-span.rs new file mode 100644 index 000000000000..c6f38c067192 --- /dev/null +++ b/tests/ui/label/undeclared-label-span.rs @@ -0,0 +1,13 @@ +//! regression test for +//! Make sure that label for continue and break is spanned correctly. + +fn main() { + loop { + continue + 'b //~ ERROR use of undeclared label + ; + break + 'c //~ ERROR use of undeclared label + ; + } +} diff --git a/tests/ui/label/undeclared-label-span.stderr b/tests/ui/label/undeclared-label-span.stderr new file mode 100644 index 000000000000..e5451b4655d8 --- /dev/null +++ b/tests/ui/label/undeclared-label-span.stderr @@ -0,0 +1,15 @@ +error[E0426]: use of undeclared label `'b` + --> $DIR/undeclared-label-span.rs:7:9 + | +LL | 'b + | ^^ undeclared label `'b` + +error[E0426]: use of undeclared label `'c` + --> $DIR/undeclared-label-span.rs:10:9 + | +LL | 'c + | ^^ undeclared label `'c` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0426`. diff --git a/tests/ui/lang-items/duplicate.rs b/tests/ui/lang-items/duplicate.rs index 4594e9456a4c..bab952fc9ad1 100644 --- a/tests/ui/lang-items/duplicate.rs +++ b/tests/ui/lang-items/duplicate.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" +//@ normalize-stderr: "loaded from .*libcore-.*.rmeta" -> "loaded from SYSROOT/libcore-*.rmeta" #![feature(lang_items)] #[lang = "sized"] diff --git a/tests/ui/lang-items/duplicate.stderr b/tests/ui/lang-items/duplicate.stderr index aaa8f5e605af..5639bcc838d8 100644 --- a/tests/ui/lang-items/duplicate.stderr +++ b/tests/ui/lang-items/duplicate.stderr @@ -5,7 +5,7 @@ LL | trait Sized {} | ^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `core` (which `std` depends on) - = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib + = note: first definition in `core` loaded from SYSROOT/libcore-*.rmeta = note: second definition in the local crate (`duplicate`) error: aborting due to 1 previous error diff --git a/tests/ui/lang-items/issue-83471.stderr b/tests/ui/lang-items/issue-83471.stderr index 0c2b403902e2..1d5b1c4cd3ed 100644 --- a/tests/ui/lang-items/issue-83471.stderr +++ b/tests/ui/lang-items/issue-83471.stderr @@ -47,7 +47,7 @@ LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0718]: `fn` lang item must be applied to a trait with 1 generic argument diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs index 90e3c58dad71..60415911d38e 100644 --- a/tests/ui/layout/debug.rs +++ b/tests/ui/layout/debug.rs @@ -68,12 +68,12 @@ union P5 { zst: [u16; 0], byte: u8 } //~ ERROR: layout_of #[rustc_layout(debug)] type X = std::mem::MaybeUninit; //~ ERROR: layout_of -#[rustc_layout(debug)] -const C: () = (); //~ ERROR: can only be applied to +#[rustc_layout(debug)] //~ ERROR: cannot be used on constants +const C: () = (); impl S { - #[rustc_layout(debug)] - const C: () = (); //~ ERROR: can only be applied to + #[rustc_layout(debug)] //~ ERROR: cannot be used on associated consts + const C: () = (); } #[rustc_layout(debug)] diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index b2ce6385ab65..c92f876fa5a1 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -4,6 +4,22 @@ error: unions cannot have zero fields LL | union EmptyUnion {} | ^^^^^^^^^^^^^^^^^^^ +error: `#[rustc_layout]` attribute cannot be used on constants + --> $DIR/debug.rs:71:1 + | +LL | #[rustc_layout(debug)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_layout]` can be applied to data types and type aliases + +error: `#[rustc_layout]` attribute cannot be used on associated consts + --> $DIR/debug.rs:75:5 + | +LL | #[rustc_layout(debug)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_layout]` can be applied to data types and type aliases + error: layout_of(E) = Layout { size: Size(12 bytes), align: AbiAlign { @@ -16,7 +32,7 @@ error: layout_of(E) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +68,7 @@ error: layout_of(E) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -77,7 +93,7 @@ error: layout_of(E) = Layout { Size(4 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, 2, @@ -130,7 +146,7 @@ error: layout_of(S) = Layout { Size(8 bytes), Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, 2, 1, @@ -200,7 +216,7 @@ error: layout_of(Result) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -251,7 +267,7 @@ error: layout_of(Result) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -289,7 +305,7 @@ error: layout_of(Result) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -577,12 +593,6 @@ error: layout_of(MaybeUninit) = Layout { LL | type X = std::mem::MaybeUninit; | ^^^^^^ -error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:72:1 - | -LL | const C: () = (); - | ^^^^^^^^^^^ - error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/debug.rs:80:19 | @@ -604,12 +614,6 @@ error: the type `T` does not have a fixed layout LL | type TooGeneric = T; | ^^^^^^^^^^^^^^^^^^ -error: `#[rustc_layout]` can only be applied to `struct`/`enum`/`union` declarations and type aliases - --> $DIR/debug.rs:76:5 - | -LL | const C: () = (); - | ^^^^^^^^^^^ - error: aborting due to 20 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 659013c8a6f1..20e0a8642a66 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -16,7 +16,7 @@ error: layout_of(A) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +52,7 @@ error: layout_of(A) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -92,7 +92,7 @@ error: layout_of(B) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -128,7 +128,7 @@ error: layout_of(B) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -168,7 +168,7 @@ error: layout_of(C) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -204,7 +204,7 @@ error: layout_of(C) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -244,7 +244,7 @@ error: layout_of(P) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -280,7 +280,7 @@ error: layout_of(P) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -320,7 +320,7 @@ error: layout_of(T) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -356,7 +356,7 @@ error: layout_of(T) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 2087fedeb19b..61cfcbdc07f7 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -22,7 +22,7 @@ error: layout_of(MissingPayloadField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -72,7 +72,7 @@ error: layout_of(MissingPayloadField) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -95,7 +95,7 @@ error: layout_of(MissingPayloadField) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -142,7 +142,7 @@ error: layout_of(CommonPayloadField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -193,7 +193,7 @@ error: layout_of(CommonPayloadField) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(CommonPayloadField) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -279,7 +279,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -329,7 +329,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -366,7 +366,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -414,7 +414,7 @@ error: layout_of(NicheFirst) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -470,7 +470,7 @@ error: layout_of(NicheFirst) = Layout { Size(0 bytes), Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -503,7 +503,7 @@ error: layout_of(NicheFirst) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -524,7 +524,7 @@ error: layout_of(NicheFirst) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -570,7 +570,7 @@ error: layout_of(NicheSecond) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -626,7 +626,7 @@ error: layout_of(NicheSecond) = Layout { Size(1 bytes), Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 1, 0, ], @@ -659,7 +659,7 @@ error: layout_of(NicheSecond) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -680,7 +680,7 @@ error: layout_of(NicheSecond) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 6bcc5b4906b5..64e2f42c042f 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -10,7 +10,7 @@ error: layout_of(Aligned1) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -46,7 +46,7 @@ error: layout_of(Aligned1) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -69,7 +69,7 @@ error: layout_of(Aligned1) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -113,7 +113,7 @@ error: layout_of(Aligned2) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -149,7 +149,7 @@ error: layout_of(Aligned2) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -172,7 +172,7 @@ error: layout_of(Aligned2) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/rigid-alias-due-to-broken-impl.rs b/tests/ui/layout/rigid-alias-due-to-broken-impl.rs new file mode 100644 index 000000000000..912c660cb7ca --- /dev/null +++ b/tests/ui/layout/rigid-alias-due-to-broken-impl.rs @@ -0,0 +1,17 @@ +// Make sure we don't ICE if `layout_of` encounters an alias +// which is rigid due to a malformed program. A regression test +// for #152545. +// +// This specific ICE happens in the `KnownPanicsLint` visitor. + +//@ compile-flags: --crate-type=rlib +trait Foo { + type Assoc; +} + +// The trait solver only treats missng associated items +// as rigid if the self-type is known to be unsized. +impl Foo for str {} +//~^ ERROR not all trait items implemented + +fn foo(_: [u32; std::mem::size_of::<::Assoc>()]) {} diff --git a/tests/ui/layout/rigid-alias-due-to-broken-impl.stderr b/tests/ui/layout/rigid-alias-due-to-broken-impl.stderr new file mode 100644 index 000000000000..e9ba6df2fdc7 --- /dev/null +++ b/tests/ui/layout/rigid-alias-due-to-broken-impl.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `Assoc` + --> $DIR/rigid-alias-due-to-broken-impl.rs:14:1 + | +LL | type Assoc; + | ---------- `Assoc` from trait +... +LL | impl Foo for str {} + | ^^^^^^^^^^^^^^^^ missing `Assoc` in implementation + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/layout/rigid-alias-no-params.rs b/tests/ui/layout/rigid-alias-no-params.rs new file mode 100644 index 000000000000..bc2622eb7ca6 --- /dev/null +++ b/tests/ui/layout/rigid-alias-no-params.rs @@ -0,0 +1,30 @@ +//@ compile-flags: -O -Cdebug-assertions=on +//@ build-pass + +// A regression test for #151791. Computing the layout of +// `>::Archived` fails as the alias +// is still rigid as the where-bound in scope shadows the impl. +// +// This previously caused an incorrect error during MIR optimizations. + +struct ArchivedString; + +pub trait ArchiveWith<'a> { + type Archived; +} + +struct AsOwned; +impl ArchiveWith<'_> for AsOwned { + type Archived = ArchivedString; +} + +fn foo<'a>() +where + AsOwned: ArchiveWith<'a>, +{ + let _ = unsafe { &*std::ptr::dangling::<>::Archived>() }; +} + +fn main() { + foo(); +} diff --git a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr index 75ee936d9e8b..6d7f46fae805 100644 --- a/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr +++ b/tests/ui/layout/rust-call-abi-not-a-tuple-ice-81974.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5 | LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -15,7 +15,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:24:12 | LL | impl FnOnce for CachedFun - | ^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -28,7 +28,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5 | LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -41,7 +41,7 @@ error[E0059]: type parameter to bare `FnMut` trait must be a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:39:12 | LL | impl FnMut for CachedFun - | ^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A` | note: required by a bound in `FnMut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -54,7 +54,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:31:5 | LL | extern "rust-call" fn call_once(mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A` | help: consider further restricting type parameter `A` with unstable trait `Tuple` | @@ -65,7 +65,7 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:45:5 | LL | extern "rust-call" fn call_mut(&mut self, a: A) -> Self::Output { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `A` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A` | help: consider further restricting type parameter `A` with unstable trait `Tuple` | @@ -76,7 +76,7 @@ error[E0277]: `A` is not a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:34:19 | LL | self.call_mut(a) - | -------- ^ the trait `Tuple` is not implemented for `A` + | -------- ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `A` | | | required by a bound introduced by this call | @@ -91,7 +91,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/rust-call-abi-not-a-tuple-ice-81974.rs:59:26 | LL | cachedcoso.call_once(1); - | --------- ^ the trait `Tuple` is not implemented for `i32` + | --------- ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` | | | required by a bound introduced by this call | diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 1ef22daf2a9d..a6e603652123 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -16,7 +16,7 @@ error: layout_of(A) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +52,7 @@ error: layout_of(A) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -92,7 +92,7 @@ error: layout_of(B) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -128,7 +128,7 @@ error: layout_of(B) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -168,7 +168,7 @@ error: layout_of(C) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -204,7 +204,7 @@ error: layout_of(C) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -244,7 +244,7 @@ error: layout_of(P) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -280,7 +280,7 @@ error: layout_of(P) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -320,7 +320,7 @@ error: layout_of(T) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -356,7 +356,7 @@ error: layout_of(T) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/layout/valid_range_oob.stderr b/tests/ui/layout/valid_range_oob.stderr index 1a0c38412503..fc6ebcf1692f 100644 --- a/tests/ui/layout/valid_range_oob.stderr +++ b/tests/ui/layout/valid_range_oob.stderr @@ -1,6 +1,6 @@ 257 > 255 -error: the compiler unexpectedly panicked. this is a bug. +error: the compiler unexpectedly panicked. This is a bug query stack during panic: #0 [layout_of] computing layout of `Foo` diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index 1707b8aff81c..23f909277808 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -10,7 +10,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -48,7 +48,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -73,7 +73,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -118,7 +118,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -156,7 +156,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(2 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -181,7 +181,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -206,7 +206,7 @@ error: layout_of(MultipleAlignments) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -251,7 +251,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -289,7 +289,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -314,7 +314,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -359,7 +359,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -401,7 +401,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -426,7 +426,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/let-else/let-else-break-help-issue-142602.rs b/tests/ui/let-else/let-else-break-help-issue-142602.rs new file mode 100644 index 000000000000..b57c7f757150 --- /dev/null +++ b/tests/ui/let-else/let-else-break-help-issue-142602.rs @@ -0,0 +1,23 @@ +// testcase from https://github.com/rust-lang/rust/issues/142602 + +pub fn main() { + // Case 1: break before let-else + let _a = loop { + if true { + break; + } + let Some(_) = Some(5) else { + break 3; //~ ERROR mismatched types + }; + }; + + // Case 2: two let-else statements + let _b = loop { + let Some(_) = Some(5) else { + break; + }; + let Some(_) = Some(4) else { + break 3; //~ ERROR mismatched types + }; + }; +} diff --git a/tests/ui/let-else/let-else-break-help-issue-142602.stderr b/tests/ui/let-else/let-else-break-help-issue-142602.stderr new file mode 100644 index 000000000000..aafbaa158ab1 --- /dev/null +++ b/tests/ui/let-else/let-else-break-help-issue-142602.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/let-else-break-help-issue-142602.rs:10:19 + | +LL | break; + | ----- expected because of this `break` +... +LL | break 3; + | ^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/let-else-break-help-issue-142602.rs:20:19 + | +LL | break; + | ----- expected because of this `break` +... +LL | break 3; + | ^ expected `()`, found integer + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/lexer/ident_normalization.rs b/tests/ui/lexer/ident_normalization.rs new file mode 100644 index 000000000000..a16c52171106 --- /dev/null +++ b/tests/ui/lexer/ident_normalization.rs @@ -0,0 +1,20 @@ +//@check-pass +//@edition:2021 + +#![allow(non_snake_case)] + +// Tests that identifiers are NFC-normalized as per +// https://rust-lang.github.io/rfcs/2457-non-ascii-idents.html + +// Note that in the first argument of each function `K` is LATIN CAPITAL LETTER K +// and in the second it is K (KELVIN SIGN). + +fn ident_nfc(_p1: K, _p2: K) {} + +fn raw_ident_nfc(_p1: r#K, _p2: r#K) {} + +fn lifetime_nfc<'K>(_p1: &'K str, _p2: &'K str) {} + +fn raw_lifetime_nfc<'K>(_p1: &'r#K str, _p2: &'r#K str) {} + +fn main() {} diff --git a/tests/ui/lexer/lex-invisible-characters.rs b/tests/ui/lexer/lex-invisible-characters.rs new file mode 100644 index 000000000000..2db72b8475dc --- /dev/null +++ b/tests/ui/lexer/lex-invisible-characters.rs @@ -0,0 +1,6 @@ +// Provide extra help when a user has an invisible character in their code + +fn main​() { + //~^ ERROR unknown start of token: \u{200b} + //~| HELP invisible characters like '\u{200b}' are not usually visible in text editors +} diff --git a/tests/ui/lexer/lex-invisible-characters.stderr b/tests/ui/lexer/lex-invisible-characters.stderr new file mode 100644 index 000000000000..ddac0f4e9325 --- /dev/null +++ b/tests/ui/lexer/lex-invisible-characters.stderr @@ -0,0 +1,10 @@ +error: unknown start of token: \u{200b} + --> $DIR/lex-invisible-characters.rs:3:8 + | +LL | fn main​() { + | ^ + | + = help: invisible characters like '\u{200b}' are not usually visible in text editors + +error: aborting due to 1 previous error + diff --git a/tests/ui/lifetimes/auxiliary/lifetime-inference-across-mods.rs b/tests/ui/lifetimes/auxiliary/lifetime-inference-across-mods.rs new file mode 100644 index 000000000000..efc2798d916a --- /dev/null +++ b/tests/ui/lifetimes/auxiliary/lifetime-inference-across-mods.rs @@ -0,0 +1,2 @@ +//! auxiliary crate for +pub struct A<'a>(pub &'a isize); diff --git a/tests/ui/lifetimes/borrowck-let-suggestion.stderr b/tests/ui/lifetimes/borrowck-let-suggestion.stderr index 4703d7f10dc2..6a35f61708d2 100644 --- a/tests/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/tests/ui/lifetimes/borrowck-let-suggestion.stderr @@ -9,7 +9,6 @@ LL | LL | x.use_mut(); | - borrow later used here | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider consuming the `Vec` when turning it into an `Iterator` | LL | let mut x = vec![1].into_iter(); diff --git a/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs new file mode 100644 index 000000000000..5ac39c6f5d9b --- /dev/null +++ b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.rs @@ -0,0 +1,10 @@ +//! regression test for +trait T<'a> { + fn a(&'a self) -> &'a bool; + fn b(&self) { + self.a(); + //~^ ERROR lifetime may not live long enough + } +} + +fn main() {} diff --git a/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr new file mode 100644 index 000000000000..383afaf782f9 --- /dev/null +++ b/tests/ui/lifetimes/elided-self-lifetime-in-trait-fn.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/elided-self-lifetime-in-trait-fn.rs:5:9 + | +LL | trait T<'a> { + | -- lifetime `'a` defined here +LL | fn a(&'a self) -> &'a bool; +LL | fn b(&self) { + | - let's call the lifetime of this reference `'1` +LL | self.a(); + | ^^^^^^^^ argument requires that `'1` must outlive `'a` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lifetimes/for-loop-region-links.rs b/tests/ui/lifetimes/for-loop-region-links.rs new file mode 100644 index 000000000000..0c86c211a00b --- /dev/null +++ b/tests/ui/lifetimes/for-loop-region-links.rs @@ -0,0 +1,13 @@ +//! regression test for +//@ run-pass +// Test that regionck creates the right region links in the pattern +// binding of a for loop + +fn foo<'a>(v: &'a [usize]) -> &'a usize { + for &ref x in v { return x; } + unreachable!() +} + +fn main() { + assert_eq!(foo(&[0]), &0); +} diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs index d6fda129e363..85eeb5d4c901 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs @@ -10,9 +10,6 @@ async fn wrapper(f: F) where F:, for<'a> >::Output: Future + 'a, -//~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` -//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` -//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` { //~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` let mut i = 41; diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index 945d38d17f63..6da9f7380d59 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -10,54 +10,24 @@ LL | | for<'a> >::Output: Future + 'a = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:12:50 + --> $DIR/issue-76168-hr-outlives-3.rs:6:26 | -LL | for<'a> >::Output: Future + 'a, - | ^^^^^^^^^^^^^^^^^^^ expected an `FnOnce(&'a mut i32)` closure, found `i32` +LL | async fn wrapper(f: F) + | ^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:12:57 + --> $DIR/issue-76168-hr-outlives-3.rs:6:26 | -LL | for<'a> >::Output: Future + 'a, - | ^^^^^^^^^^^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - -error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:12:72 - | -LL | for<'a> >::Output: Future + 'a, - | ^^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - -error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:6:1 - | -LL | / async fn wrapper(f: F) -... | -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` - | - = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` - -error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:6:1 - | -LL | / async fn wrapper(f: F) -... | -LL | | F:, -LL | | for<'a> >::Output: Future + 'a, - | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` +LL | async fn wrapper(f: F) + | ^ expected an `FnOnce(&'a mut i32)` closure, found `i32` | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:16:1 + --> $DIR/issue-76168-hr-outlives-3.rs:13:1 | LL | / { LL | | @@ -68,6 +38,6 @@ LL | | } | = help: the trait `for<'a> FnOnce(&'a mut i32)` is not implemented for `i32` -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/lifetimes/issue-97194.rs b/tests/ui/lifetimes/issue-97194.rs index 5f3560dbe946..5e7c3683d209 100644 --- a/tests/ui/lifetimes/issue-97194.rs +++ b/tests/ui/lifetimes/issue-97194.rs @@ -1,8 +1,8 @@ extern "C" { fn bget(&self, index: [usize; Self::DIM]) -> bool { - //~^ ERROR incorrect function inside `extern` block - //~| ERROR `self` parameter is only allowed in associated functions - //~| ERROR failed to resolve: `Self` + //~^ ERROR: incorrect function inside `extern` block + //~| ERROR: `self` parameter is only allowed in associated functions + //~| ERROR: cannot find `Self` type T<'a> = &'a str; } } diff --git a/tests/ui/lifetimes/issue-97194.stderr b/tests/ui/lifetimes/issue-97194.stderr index 345e21cb2507..c7e318f7390a 100644 --- a/tests/ui/lifetimes/issue-97194.stderr +++ b/tests/ui/lifetimes/issue-97194.stderr @@ -22,7 +22,7 @@ LL | fn bget(&self, index: [usize; Self::DIM]) -> bool { | = note: associated functions are those in `impl` or `trait` definitions -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find `Self` in this scope --> $DIR/issue-97194.rs:2:35 | LL | fn bget(&self, index: [usize; Self::DIM]) -> bool { diff --git a/tests/ui/lifetimes/lifetime-inference-across-mods.rs b/tests/ui/lifetimes/lifetime-inference-across-mods.rs new file mode 100644 index 000000000000..224d2193d08c --- /dev/null +++ b/tests/ui/lifetimes/lifetime-inference-across-mods.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ run-pass +//@ aux-build:lifetime-inference-across-mods.rs + + +extern crate lifetime_inference_across_mods as a; + +fn main() { + let one = 1; + let _a = a::A(&one); +} diff --git a/tests/ui/lifetimes/mut-ref-owned-suggestion.rs b/tests/ui/lifetimes/mut-ref-owned-suggestion.rs new file mode 100644 index 000000000000..ae5e8f6658b6 --- /dev/null +++ b/tests/ui/lifetimes/mut-ref-owned-suggestion.rs @@ -0,0 +1,29 @@ +//! Regression test for +//! Tests that `&mut T` suggests `T`, not `mut T`, `&mut str` suggests `String`, not `str`, +//! when recommending an owned value. +fn with_fn(_f: impl Fn() -> &mut ()) {} +//~^ ERROR: missing lifetime specifier + +fn with_ref_mut_str(_f: impl Fn() -> &mut str) {} +//~^ ERROR: missing lifetime specifier + +fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { + //~^ ERROR: missing lifetime specifier + 2 +} + +fn with_dyn(_f: Box &mut i32>) {} +//~^ ERROR: missing lifetime specifier + +fn trait_bound &mut i32>(_f: F) {} +//~^ ERROR: missing lifetime specifier + +fn nested_result(_f: impl Fn() -> Result<&mut i32, ()>) {} +//~^ ERROR: missing lifetime specifier + +struct Holder &mut i32> { + //~^ ERROR: missing lifetime specifier + f: F, +} + +fn main() {} diff --git a/tests/ui/lifetimes/mut-ref-owned-suggestion.stderr b/tests/ui/lifetimes/mut-ref-owned-suggestion.stderr new file mode 100644 index 000000000000..a3e58331342a --- /dev/null +++ b/tests/ui/lifetimes/mut-ref-owned-suggestion.stderr @@ -0,0 +1,137 @@ +error[E0106]: missing lifetime specifier + --> $DIR/mut-ref-owned-suggestion.rs:4:29 + | +LL | fn with_fn(_f: impl Fn() -> &mut ()) {} + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn with_fn(_f: impl Fn() -> &'static mut ()) {} + | +++++++ +help: instead, you are more likely to want to return an owned value + | +LL - fn with_fn(_f: impl Fn() -> &mut ()) {} +LL + fn with_fn(_f: impl Fn() -> ()) {} + | + +error[E0106]: missing lifetime specifier + --> $DIR/mut-ref-owned-suggestion.rs:7:38 + | +LL | fn with_ref_mut_str(_f: impl Fn() -> &mut str) {} + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn with_ref_mut_str(_f: impl Fn() -> &'static mut str) {} + | +++++++ +help: instead, you are more likely to want to return an owned value + | +LL - fn with_ref_mut_str(_f: impl Fn() -> &mut str) {} +LL + fn with_ref_mut_str(_f: impl Fn() -> String) {} + | + +error[E0106]: missing lifetime specifier + --> $DIR/mut-ref-owned-suggestion.rs:10:40 + | +LL | fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn with_fn_has_return(_f: impl Fn() -> &'static mut ()) -> i32 { + | +++++++ +help: consider making the bound lifetime-generic with a new `'a` lifetime + | +LL - fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { +LL + fn with_fn_has_return(_f: impl for<'a> Fn() -> &'a ()) -> i32 { + | +help: consider introducing a named lifetime parameter + | +LL - fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { +LL + fn with_fn_has_return<'a>(_f: impl Fn() -> &'a ()) -> i32 { + | +help: alternatively, you might want to return an owned value + | +LL - fn with_fn_has_return(_f: impl Fn() -> &mut ()) -> i32 { +LL + fn with_fn_has_return(_f: impl Fn() -> ()) -> i32 { + | + +error[E0106]: missing lifetime specifier + --> $DIR/mut-ref-owned-suggestion.rs:15:33 + | +LL | fn with_dyn(_f: Box &mut i32>) {} + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn with_dyn(_f: Box &'static mut i32>) {} + | +++++++ +help: instead, you are more likely to want to return an owned value + | +LL - fn with_dyn(_f: Box &mut i32>) {} +LL + fn with_dyn(_f: Box i32>) {} + | + +error[E0106]: missing lifetime specifier + --> $DIR/mut-ref-owned-suggestion.rs:18:27 + | +LL | fn trait_bound &mut i32>(_f: F) {} + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn trait_bound &'static mut i32>(_f: F) {} + | +++++++ +help: instead, you are more likely to want to change the argument to be borrowed... + | +LL | fn trait_bound &mut i32>(_f: &F) {} + | + +help: ...or alternatively, you might want to return an owned value + | +LL - fn trait_bound &mut i32>(_f: F) {} +LL + fn trait_bound i32>(_f: F) {} + | + +error[E0106]: missing lifetime specifier + --> $DIR/mut-ref-owned-suggestion.rs:21:42 + | +LL | fn nested_result(_f: impl Fn() -> Result<&mut i32, ()>) {} + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | fn nested_result(_f: impl Fn() -> Result<&'static mut i32, ()>) {} + | +++++++ +help: instead, you are more likely to want to return an owned value + | +LL - fn nested_result(_f: impl Fn() -> Result<&mut i32, ()>) {} +LL + fn nested_result(_f: impl Fn() -> Result) {} + | + +error[E0106]: missing lifetime specifier + --> $DIR/mut-ref-owned-suggestion.rs:24:26 + | +LL | struct Holder &mut i32> { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` + | +LL | struct Holder &'static mut i32> { + | +++++++ +help: instead, you are more likely to want to return an owned value + | +LL - struct Holder &mut i32> { +LL + struct Holder i32> { + | + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs new file mode 100644 index 000000000000..acce49b1af72 --- /dev/null +++ b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.rs @@ -0,0 +1,11 @@ +// Regression test for #135845. + +use std::marker::PhantomData; + +fn b<'a>() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121] + let _: PhantomData<&'a ()> = PhantomData; + 0 +} + +fn main() {} diff --git a/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr new file mode 100644 index 000000000000..9f3695e88f82 --- /dev/null +++ b/tests/ui/lifetimes/recover-infer-ret-ty-issue-135845.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/recover-infer-ret-ty-issue-135845.rs:5:15 + | +LL | fn b<'a>() -> _ { + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn b<'a>() -> _ { +LL + fn b<'a>() -> i32 { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.rs b/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.rs new file mode 100644 index 000000000000..4bf92a2c1c18 --- /dev/null +++ b/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.rs @@ -0,0 +1,49 @@ +// Regression test for https://github.com/rust-lang/rust/issues/65866. + +mod plain { + struct Foo; + + struct Re<'a> { + _data: &'a u16, + } + + trait Bar { + fn bar(&self, r: &mut Re); + //~^ NOTE expected + //~| NOTE `Re` here is elided as `Re<'_>` + } + + impl Bar for Foo { + fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a>) {} + //~^ ERROR `impl` item signature doesn't match `trait` item signature + //~| NOTE expected signature + //~| NOTE found + //~| HELP the lifetime requirements + //~| HELP verify the lifetime relationships + } +} + +mod with_type_args { + struct Foo; + + struct Re<'a, T> { + _data: (&'a u16, T), + } + + trait Bar { + fn bar(&self, r: &mut Re); + //~^ NOTE expected + //~| NOTE `Re` here is elided as `Re<'_, u8>` + } + + impl Bar for Foo { + fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a, u8>) {} + //~^ ERROR `impl` item signature doesn't match `trait` item signature + //~| NOTE expected signature + //~| NOTE found + //~| HELP the lifetime requirements + //~| HELP verify the lifetime relationships + } +} + +fn main() {} diff --git a/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.stderr b/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.stderr new file mode 100644 index 000000000000..db69b4f3656e --- /dev/null +++ b/tests/ui/lifetimes/trait-impl-mismatch-elided-lifetime-issue-65866.stderr @@ -0,0 +1,40 @@ +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:17:9 + | +LL | fn bar(&self, r: &mut Re); + | -------------------------- expected `fn(&'1 plain::Foo, &'2 mut plain::Re<'3>)` +... +LL | fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 plain::Foo, &'2 mut plain::Re<'1>)` + | + = note: expected signature `fn(&'1 plain::Foo, &'2 mut plain::Re<'3>)` + found signature `fn(&'1 plain::Foo, &'2 mut plain::Re<'1>)` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output +note: `Re` here is elided as `Re<'_>` + --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:11:31 + | +LL | fn bar(&self, r: &mut Re); + | ^^ + +error: `impl` item signature doesn't match `trait` item signature + --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:40:9 + | +LL | fn bar(&self, r: &mut Re); + | ------------------------------ expected `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'3, u8>)` +... +LL | fn bar<'a, 'b>(&'a self, _r: &'b mut Re<'a, u8>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'1, u8>)` + | + = note: expected signature `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'3, u8>)` + found signature `fn(&'1 with_type_args::Foo, &'2 mut with_type_args::Re<'1, u8>)` + = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait` + = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output +note: `Re` here is elided as `Re<'_, u8>` + --> $DIR/trait-impl-mismatch-elided-lifetime-issue-65866.rs:34:31 + | +LL | fn bar(&self, r: &mut Re); + | ^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs new file mode 100644 index 000000000000..39cf4ae64185 --- /dev/null +++ b/tests/ui/lifetimes/trait-method-lifetime-suggestion.rs @@ -0,0 +1,13 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17758 +//! Test that regionck suggestions in a provided method of a trait +//! don't ICE + +trait Foo<'a> { + fn foo(&'a self); + fn bar(&self) { + self.foo(); + //~^ ERROR lifetime may not live long enough + } +} + +fn main() {} diff --git a/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr new file mode 100644 index 000000000000..64347577d070 --- /dev/null +++ b/tests/ui/lifetimes/trait-method-lifetime-suggestion.stderr @@ -0,0 +1,13 @@ +error: lifetime may not live long enough + --> $DIR/trait-method-lifetime-suggestion.rs:8:9 + | +LL | trait Foo<'a> { + | -- lifetime `'a` defined here +LL | fn foo(&'a self); +LL | fn bar(&self) { + | - let's call the lifetime of this reference `'1` +LL | self.foo(); + | ^^^^^^^^^^ argument requires that `'1` must outlive `'a` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lifetimes/unit-struct-as-rvalue.rs b/tests/ui/lifetimes/unit-struct-as-rvalue.rs new file mode 100644 index 000000000000..10c1d2517064 --- /dev/null +++ b/tests/ui/lifetimes/unit-struct-as-rvalue.rs @@ -0,0 +1,20 @@ +//! regression test for +// This tests verifies that unary structs and enum variants +// are treated as rvalues and their lifetime is not bounded to +// the static scope. + +struct Test; + +impl Drop for Test { + fn drop (&mut self) {} +} + +fn createTest<'a>() -> &'a Test { + let testValue = &Test; + return testValue; //~ ERROR cannot return value referencing temporary value +} + + +pub fn main() { + createTest(); +} diff --git a/tests/ui/lifetimes/unit-struct-as-rvalue.stderr b/tests/ui/lifetimes/unit-struct-as-rvalue.stderr new file mode 100644 index 000000000000..afb80331f356 --- /dev/null +++ b/tests/ui/lifetimes/unit-struct-as-rvalue.stderr @@ -0,0 +1,11 @@ +error[E0515]: cannot return value referencing temporary value + --> $DIR/unit-struct-as-rvalue.rs:14:10 + | +LL | let testValue = &Test; + | ---- temporary value created here +LL | return testValue; + | ^^^^^^^^^ returns a value referencing data owned by the current function + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/limits/limit-huge-struct-derive-debug.rs b/tests/ui/limits/limit-huge-struct-derive-debug.rs new file mode 100644 index 000000000000..eb793aadd8c6 --- /dev/null +++ b/tests/ui/limits/limit-huge-struct-derive-debug.rs @@ -0,0 +1,493 @@ +//! regression test for +//@ build-pass +#[derive(Debug)] +pub struct Config { + pub name: String, + pub cluster: String, + pub debug_none: String, + pub debug_lockdep: String, + pub debug_context: String, + pub debug_crush: String, + pub debug_mds: String, + pub debug_mds_balancer: String, + pub debug_mds_locker: String, + pub debug_mds_log: String, + pub debug_mds_log_expire: String, + pub debug_mds_migrator: String, + pub debug_buffer: String, + pub debug_timer: String, + pub debug_filer: String, + pub debug_striper: String, + pub debug_objecter: String, + pub debug_rados: String, + pub debug_rbd: String, + pub debug_journaler: String, + pub debug_objectcacher: String, + pub debug_client: String, + pub debug_osd: String, + pub debug_optracker: String, + pub debug_objclass: String, + pub debug_filestore: String, + pub debug_keyvaluestore: String, + pub debug_journal: String, + pub debug_ms: String, + pub debug_mon: String, + pub debug_monc: String, + pub debug_paxos: String, + pub debug_tp: String, + pub debug_auth: String, + pub debug_crypto: String, + pub debug_finisher: String, + pub debug_heartbeatmap: String, + pub debug_perfcounter: String, + pub debug_rgw: String, + pub debug_civetweb: String, + pub debug_javaclient: String, + pub debug_asok: String, + pub debug_throttle: String, + pub host: String, + pub fsid: String, + pub public_addr: String, + pub cluster_addr: String, + pub public_network: String, + pub cluster_network: String, + pub num_client: String, + pub monmap: String, + pub mon_host: String, + pub lockdep: String, + pub run_dir: String, + pub admin_socket: String, + pub daemonize: String, + pub pid_file: String, + pub chdir: String, + pub max_open_files: String, + pub restapi_log_level: String, + pub restapi_base_url: String, + pub fatal_signal_handlers: String, + pub log_file: String, + pub log_max_new: String, + pub log_max_recent: String, + pub log_to_stderr: String, + pub err_to_stderr: String, + pub log_to_syslog: String, + pub err_to_syslog: String, + pub log_flush_on_exit: String, + pub log_stop_at_utilization: String, + pub clog_to_monitors: String, + pub clog_to_syslog: String, + pub clog_to_syslog_level: String, + pub clog_to_syslog_facility: String, + pub mon_cluster_log_to_syslog: String, + pub mon_cluster_log_to_syslog_level: String, + pub mon_cluster_log_to_syslog_facility: String, + pub mon_cluster_log_file: String, + pub mon_cluster_log_file_level: String, + pub key: String, + pub keyfile: String, + pub keyring: String, + pub heartbeat_interval: String, + pub heartbeat_file: String, + pub heartbeat_inject_failure: String, + pub perf: String, + pub ms_tcp_nodelay: String, + pub ms_tcp_rcvbuf: String, + pub ms_initial_backoff: String, + pub ms_max_backoff: String, + pub ms_nocrc: String, + pub ms_die_on_bad_msg: String, + pub ms_die_on_unhandled_msg: String, + pub ms_die_on_old_message: String, + pub ms_dispatch_throttle_bytes: String, + pub ms_bind_ipv6: String, + pub ms_bind_port_min: String, + pub ms_bind_port_max: String, + pub ms_rwthread_stack_bytes: String, + pub ms_tcp_read_timeout: String, + pub ms_pq_max_tokens_per_priority: String, + pub ms_pq_min_cost: String, + pub ms_inject_socket_failures: String, + pub ms_inject_delay_type: String, + pub ms_inject_delay_msg_type: String, + pub ms_inject_delay_max: String, + pub ms_inject_delay_probability: String, + pub ms_inject_internal_delays: String, + pub ms_dump_on_send: String, + pub inject_early_sigterm: String, + pub mon_data: String, + pub mon_initial_members: String, + pub mon_sync_fs_threshold: String, + pub mon_compact_on_start: String, + pub mon_compact_on_bootstrap: String, + pub mon_compact_on_trim: String, + pub mon_tick_interval: String, + pub mon_subscribe_interval: String, + pub mon_delta_reset_interval: String, + pub mon_osd_laggy_halflife: String, + pub mon_osd_laggy_weight: String, + pub mon_osd_adjust_heartbeat_grace: String, + pub mon_osd_adjust_down_out_interval: String, + pub mon_osd_auto_mark_in: String, + pub mon_osd_auto_mark_auto_out_in: String, + pub mon_osd_auto_mark_new_in: String, + pub mon_osd_down_out_interval: String, + pub mon_osd_down_out_subtree_limit: String, + pub mon_osd_min_up_ratio: String, + pub mon_osd_min_in_ratio: String, + pub mon_osd_max_op_age: String, + pub mon_osd_max_split_count: String, + pub mon_osd_allow_primary_temp: String, + pub mon_osd_allow_primary_affinity: String, + pub mon_stat_smooth_intervals: String, + pub mon_lease: String, + pub mon_lease_renew_interval: String, + pub mon_lease_ack_timeout: String, + pub mon_clock_drift_allowed: String, + pub mon_clock_drift_warn_backoff: String, + pub mon_timecheck_interval: String, + pub mon_accept_timeout: String, + pub mon_pg_create_interval: String, + pub mon_pg_stuck_threshold: String, + pub mon_pg_warn_min_per_osd: String, + pub mon_pg_warn_max_object_skew: String, + pub mon_pg_warn_min_objects: String, + pub mon_pg_warn_min_pool_objects: String, + pub mon_cache_target_full_warn_ratio: String, + pub mon_osd_full_ratio: String, + pub mon_osd_nearfull_ratio: String, + pub mon_globalid_prealloc: String, + pub mon_osd_report_timeout: String, + pub mon_force_standby_active: String, + pub mon_warn_on_old_mons: String, + pub mon_warn_on_legacy_crush_tunables: String, + pub mon_warn_on_osd_down_out_interval_zero: String, + pub mon_warn_on_cache_pools_without_hit_sets: String, + pub mon_min_osdmap_epochs: String, + pub mon_max_pgmap_epochs: String, + pub mon_max_log_epochs: String, + pub mon_max_mdsmap_epochs: String, + pub mon_max_osd: String, + pub mon_probe_timeout: String, + pub mon_slurp_timeout: String, + pub mon_slurp_bytes: String, + pub mon_client_bytes: String, + pub mon_daemon_bytes: String, + pub mon_max_log_entries_per_event: String, + pub mon_health_data_update_interval: String, + pub mon_data_avail_crit: String, + pub mon_data_avail_warn: String, + pub mon_config_key_max_entry_size: String, + pub mon_sync_timeout: String, + pub mon_sync_max_payload_size: String, + pub mon_sync_debug: String, + pub mon_sync_debug_leader: String, + pub mon_sync_debug_provider: String, + pub mon_sync_debug_provider_fallback: String, + pub mon_inject_sync_get_chunk_delay: String, + pub mon_osd_min_down_reporters: String, + pub mon_osd_min_down_reports: String, + pub mon_osd_force_trim_to: String, + pub mon_mds_force_trim_to: String, + pub mon_advanced_debug_mode: String, + pub mon_debug_dump_transactions: String, + pub mon_debug_dump_location: String, + pub mon_sync_provider_kill_at: String, + pub mon_sync_requester_kill_at: String, + pub mon_leveldb_write_buffer_size: String, + pub mon_leveldb_cache_size: String, + pub mon_leveldb_block_size: String, + pub mon_leveldb_bloom_size: String, + pub mon_leveldb_max_open_files: String, + pub mon_leveldb_compression: String, + pub mon_leveldb_paranoid: String, + pub mon_leveldb_log: String, + pub mon_leveldb_size_warn: String, + pub mon_force_quorum_join: String, + pub paxos_stash_full_interval: String, + pub paxos_max_join_drift: String, + pub paxos_propose_interval: String, + pub paxos_min_wait: String, + pub paxos_min: String, + pub paxos_trim_min: String, + pub paxos_trim_max: String, + pub paxos_service_trim_min: String, + pub paxos_service_trim_max: String, + pub paxos_kill_at: String, + pub clock_offset: String, + pub auth_cluster_required: String, + pub auth_service_required: String, + pub auth_client_required: String, + pub auth_supported: String, + pub cephx_require_signatures: String, + pub cephx_cluster_require_signatures: String, + pub cephx_service_require_signatures: String, + pub cephx_sign_messages: String, + pub auth_mon_ticket_ttl: String, + pub auth_service_ticket_ttl: String, + pub auth_debug: String, + pub mon_client_hunt_interval: String, + pub mon_client_ping_interval: String, + pub mon_client_ping_timeout: String, + pub mon_client_hunt_interval_backoff: String, + pub mon_client_hunt_interval_max_multiple: String, + pub mon_client_max_log_entries_per_message: String, + pub mon_max_pool_pg_num: String, + pub mon_pool_quota_warn_threshold: String, + pub mon_pool_quota_crit_threshold: String, + pub client_cache_size: String, + pub client_cache_mid: String, + pub client_use_random_mds: String, + pub client_mount_timeout: String, + pub client_tick_interval: String, + pub client_trace: String, + pub client_readahead_min: String, + pub client_readahead_max_bytes: String, + pub client_readahead_max_periods: String, + pub client_snapdir: String, + pub client_mountpoint: String, + pub client_notify_timeout: String, + pub osd_client_watch_timeout: String, + pub client_caps_release_delay: String, + pub client_oc: String, + pub client_oc_size: String, + pub client_oc_max_dirty: String, + pub client_oc_target_dirty: String, + pub client_oc_max_dirty_age: String, + pub client_oc_max_objects: String, + pub client_debug_force_sync_read: String, + pub client_debug_inject_tick_delay: String, + pub client_max_inline_size: String, + pub fuse_use_invalidate_cb: String, + pub fuse_allow_other: String, + pub fuse_default_permissions: String, + pub fuse_big_writes: String, + pub fuse_atomic_o_trunc: String, + pub fuse_debug: String, + pub fuse_multithreaded: String, + pub crush_location: String, + pub objecter_tick_interval: String, + pub objecter_timeout: String, + pub objecter_inflight_op_bytes: String, + pub objecter_inflight_ops: String, + pub journaler_allow_split_entries: String, + pub journaler_write_head_interval: String, + pub journaler_prefetch_periods: String, + pub journaler_prezero_periods: String, + pub journaler_batch_interval: String, + pub journaler_batch_max: String, + pub mds_data: String, + pub mds_max_file_size: String, + pub mds_cache_size: String, + pub mds_cache_mid: String, + pub mds_mem_max: String, + pub mds_dir_max_commit_size: String, + pub mds_decay_halflife: String, + pub mds_beacon_interval: String, + pub mds_beacon_grace: String, + pub mds_enforce_unique_name: String, + pub mds_interval: String, + pub mds_session_timeout: String, + pub mds_freeze_tree_timeout: String, + pub mds_session_autoclose: String, + pub mds_reconnect_timeout: String, + pub mds_tick_interval: String, + pub mds_dirstat_min_interval: String, + pub mds_scatter_nudge_interval: String, + pub mds_client_prealloc_inos: String, + pub mds_early_reply: String, + pub mds_default_dir_hash: String, + pub mds_log: String, + pub mds_log_skip_corrupt_events: String, + pub mds_log_max_events: String, + pub mds_log_segment_size: String, + pub mds_log_max_segments: String, + pub mds_log_max_expiring: String, + pub mds_bal_sample_interval: String, + pub mds_bal_replicate_threshold: String, + pub mds_bal_unreplicate_threshold: String, + pub mds_bal_frag: String, + pub mds_bal_split_size: String, + pub mds_bal_split_rd: String, + pub mds_bal_split_wr: String, + pub mds_bal_split_bits: String, + pub mds_bal_merge_size: String, + pub mds_bal_merge_rd: String, + pub mds_bal_merge_wr: String, + pub mds_bal_interval: String, + pub mds_bal_fragment_interval: String, + pub mds_bal_idle_threshold: String, + pub mds_bal_max: String, + pub mds_bal_max_until: String, + pub mds_bal_mode: String, + pub mds_bal_min_rebalance: String, + pub mds_bal_min_start: String, + pub mds_bal_need_min: String, + pub mds_bal_need_max: String, + pub mds_bal_midchunk: String, + pub mds_bal_minchunk: String, + pub mds_bal_target_removal_min: String, + pub mds_bal_target_removal_max: String, + pub mds_replay_interval: String, + pub mds_shutdown_check: String, + pub mds_thrash_exports: String, + pub mds_thrash_fragments: String, + pub mds_dump_cache_on_map: String, + pub mds_dump_cache_after_rejoin: String, + pub mds_verify_scatter: String, + pub mds_debug_scatterstat: String, + pub mds_debug_frag: String, + pub mds_debug_auth_pins: String, + pub mds_debug_subtrees: String, + pub mds_kill_mdstable_at: String, + pub mds_kill_export_at: String, + pub mds_kill_import_at: String, + pub mds_kill_link_at: String, + pub mds_kill_rename_at: String, + pub mds_kill_openc_at: String, + pub mds_kill_journal_at: String, + pub mds_kill_journal_expire_at: String, + pub mds_kill_journal_replay_at: String, + pub mds_kill_create_at: String, + pub mds_open_remote_link_mode: String, + pub mds_inject_traceless_reply_probability: String, + pub mds_wipe_sessions: String, + pub mds_wipe_ino_prealloc: String, + pub mds_skip_ino: String, + pub max_mds: String, + pub mds_standby_for_name: String, + pub mds_standby_for_rank: String, + pub mds_standby_replay: String, + pub osd_compact_leveldb_on_mount: String, + pub osd_max_backfills: String, + pub osd_backfill_full_ratio: String, + pub osd_backfill_retry_interval: String, + pub osd_agent_max_ops: String, + pub osd_agent_min_evict_effort: String, + pub osd_agent_quantize_effort: String, + pub osd_agent_delay_time: String, + pub osd_agent_hist_halflife: String, + pub osd_agent_slop: String, + pub osd_uuid: String, + pub osd_data: String, + pub osd_journal: String, + pub osd_journal_size: String, + pub osd_max_write_size: String, + pub osd_max_pgls: String, + pub osd_client_message_size_cap: String, + pub osd_client_message_cap: String, + pub osd_pg_bits: String, + pub osd_pgp_bits: String, + pub osd_crush_chooseleaf_type: String, + pub osd_pool_default_crush_rule: String, + pub osd_pool_default_crush_replicated_ruleset: String, + pub osd_pool_erasure_code_stripe_width: String, + pub osd_pool_default_size: String, + pub osd_pool_default_min_size: String, + pub osd_pool_default_pg_num: String, + pub osd_pool_default_pgp_num: String, + pub osd_pool_default_erasure_code_directory: String, + pub osd_pool_default_erasure_code_profile: String, + pub osd_erasure_code_plugins: String, + pub osd_pool_default_flags: String, + pub osd_pool_default_flag_hashpspool: String, + pub osd_pool_default_hit_set_bloom_fpp: String, + pub osd_pool_default_cache_target_dirty_ratio: String, + pub osd_pool_default_cache_target_full_ratio: String, + pub osd_pool_default_cache_min_flush_age: String, + pub osd_pool_default_cache_min_evict_age: String, + pub osd_hit_set_min_size: String, + pub osd_hit_set_max_size: String, + pub osd_hit_set_namespace: String, + pub osd_tier_default_cache_mode: String, + pub osd_tier_default_cache_hit_set_count: String, + pub osd_tier_default_cache_hit_set_period: String, + pub osd_tier_default_cache_hit_set_type: String, + pub osd_map_dedup: String, + pub osd_map_max_advance: String, + pub osd_map_cache_size: String, + pub osd_map_message_max: String, + pub osd_map_share_max_epochs: String, + pub osd_op_threads: String, + pub osd_peering_wq_batch_size: String, + pub osd_op_pq_max_tokens_per_priority: String, + pub osd_op_pq_min_cost: String, + pub osd_disk_threads: String, + pub osd_disk_thread_ioprio_class: String, + pub osd_disk_thread_ioprio_priority: String, + pub osd_recovery_threads: String, + pub osd_recover_clone_overlap: String, + pub osd_recover_clone_overlap_limit: String, + pub osd_backfill_scan_min: String, + pub osd_backfill_scan_max: String, + pub osd_op_thread_timeout: String, + pub osd_recovery_thread_timeout: String, + pub osd_snap_trim_thread_timeout: String, + pub osd_snap_trim_sleep: String, + pub osd_scrub_thread_timeout: String, + pub osd_scrub_finalize_thread_timeout: String, + pub osd_scrub_invalid_stats: String, + pub osd_remove_thread_timeout: String, + pub osd_command_thread_timeout: String, + pub osd_age: String, + pub osd_age_time: String, + pub osd_heartbeat_addr: String, + pub osd_heartbeat_interval: String, + pub osd_heartbeat_grace: String, + pub osd_heartbeat_min_peers: String, + pub osd_pg_max_concurrent_snap_trims: String, + pub osd_heartbeat_min_healthy_ratio: String, + pub osd_mon_heartbeat_interval: String, + pub osd_mon_report_interval_max: String, + pub osd_mon_report_interval_min: String, + pub osd_pg_stat_report_interval_max: String, + pub osd_mon_ack_timeout: String, + pub osd_default_data_pool_replay_window: String, + pub osd_preserve_trimmed_log: String, + pub osd_auto_mark_unfound_lost: String, + pub osd_recovery_delay_start: String, + pub osd_recovery_max_active: String, + pub osd_recovery_max_single_start: String, + pub osd_recovery_max_chunk: String, + pub osd_copyfrom_max_chunk: String, + pub osd_push_per_object_cost: String, + pub osd_max_push_cost: String, + pub osd_max_push_objects: String, + pub osd_recovery_forget_lost_objects: String, + pub osd_max_scrubs: String, + pub osd_scrub_load_threshold: String, + pub osd_scrub_min_interval: String, + pub osd_scrub_max_interval: String, + pub osd_scrub_chunk_min: String, + pub osd_scrub_chunk_max: String, + pub osd_scrub_sleep: String, + pub osd_deep_scrub_interval: String, + pub osd_deep_scrub_stride: String, + pub osd_scan_list_ping_tp_interval: String, + pub osd_auto_weight: String, + pub osd_class_dir: String, + pub osd_open_classes_on_start: String, + pub osd_check_for_log_corruption: String, + pub osd_use_stale_snap: String, + pub osd_rollback_to_cluster_snap: String, + pub osd_default_notify_timeout: String, + pub osd_kill_backfill_at: String, + pub osd_pg_epoch_persisted_max_stale: String, + pub osd_min_pg_log_entries: String, + pub osd_max_pg_log_entries: String, + pub osd_op_complaint_time: String, + pub osd_command_max_records: String, + pub osd_op_log_threshold: String, + pub osd_verify_sparse_read_holes: String, + pub osd_debug_drop_ping_probability: String, + pub osd_debug_drop_ping_duration: String, + pub osd_debug_drop_pg_create_probability: String, + pub osd_debug_drop_pg_create_duration: String, + pub osd_debug_drop_op_probability: String, + pub osd_debug_op_order: String, + pub osd_debug_verify_snaps_on_info: String, + pub osd_debug_verify_stray_on_activate: String, + pub osd_debug_skip_full_check_in_backfill_reservation: String, + pub osd_debug_reject_backfill_probability: String, + pub osd_enable_op_tracker: String, +} + +fn main() {} diff --git a/tests/ui/limits/type-length-limit-enforcement.stderr b/tests/ui/limits/type-length-limit-enforcement.stderr index bfea0b5a4482..82855bd75528 100644 --- a/tests/ui/limits/type-length-limit-enforcement.stderr +++ b/tests/ui/limits/type-length-limit-enforcement.stderr @@ -8,9 +8,11 @@ LL | drop::>(None); = note: the full name for the type has been written to '$TEST_BUILD_DIR/type-length-limit-enforcement.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console -error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut` +error: reached the type-length limit while instantiating `<{closure@...} as FnMut<()>>::call_mut` | = help: consider adding a `#![type_length_limit="10"]` attribute to your crate + = note: the full name for the type has been written to '$TEST_BUILD_DIR/type-length-limit-enforcement.long-type-$LONG_TYPE_HASH.txt' + = note: consider using `--verbose` to print the full type name to the console error: aborting due to 2 previous errors diff --git a/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr b/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr new file mode 100644 index 000000000000..a3772e509ed6 --- /dev/null +++ b/tests/ui/limits/vtable-try-as-dyn.full-debuginfo.stderr @@ -0,0 +1,4 @@ +error: values of the type `[u8; usize::MAX]` are too big for the target architecture + +error: aborting due to 1 previous error + diff --git a/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr b/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr new file mode 100644 index 000000000000..a3772e509ed6 --- /dev/null +++ b/tests/ui/limits/vtable-try-as-dyn.no-debuginfo.stderr @@ -0,0 +1,4 @@ +error: values of the type `[u8; usize::MAX]` are too big for the target architecture + +error: aborting due to 1 previous error + diff --git a/tests/ui/limits/vtable-try-as-dyn.rs b/tests/ui/limits/vtable-try-as-dyn.rs new file mode 100644 index 000000000000..4df4f92717f9 --- /dev/null +++ b/tests/ui/limits/vtable-try-as-dyn.rs @@ -0,0 +1,15 @@ +// At the time of writing, vtable.rs would ICE only with debuginfo disabled, while this testcase, +// originally reported as #152030, would ICE even with debuginfo enabled. +//@ revisions: no-debuginfo full-debuginfo +//@ compile-flags: --crate-type=lib --emit=mir +//@[no-debuginfo] compile-flags: -C debuginfo=0 +//@[full-debuginfo] compile-flags: -C debuginfo=2 +#![feature(try_as_dyn)] + +trait Trait {} +impl Trait for T {} + +//~? ERROR: values of the type `[u8; usize::MAX]` are too big for the target architecture +pub fn foo(x: &[u8; usize::MAX]) { + let _ = std::any::try_as_dyn::<[u8; usize::MAX], dyn Trait>(x); +} diff --git a/tests/ui/limits/vtable.rs b/tests/ui/limits/vtable.rs new file mode 100644 index 000000000000..570eaaec491c --- /dev/null +++ b/tests/ui/limits/vtable.rs @@ -0,0 +1,8 @@ +//@ compile-flags: --crate-type=lib --emit=mir -C debuginfo=0 +pub trait Trait {} +impl Trait for T {} + +//~? ERROR: values of the type `[u8; usize::MAX]` are too big for the target architecture +pub fn foo(x: &[u8; usize::MAX]) -> &dyn Trait { + x as &dyn Trait +} diff --git a/tests/ui/limits/vtable.stderr b/tests/ui/limits/vtable.stderr new file mode 100644 index 000000000000..a3772e509ed6 --- /dev/null +++ b/tests/ui/limits/vtable.stderr @@ -0,0 +1,4 @@ +error: values of the type `[u8; usize::MAX]` are too big for the target architecture + +error: aborting due to 1 previous error + diff --git a/tests/ui/link-native-libs/issue-43925.stderr b/tests/ui/link-native-libs/issue-43925.stderr index 68a020546c14..fdc644ed6469 100644 --- a/tests/ui/link-native-libs/issue-43925.stderr +++ b/tests/ui/link-native-libs/issue-43925.stderr @@ -16,21 +16,6 @@ LL | #[link(name = "foo", cfg("rlib"))] | expected a valid identifier here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", cfg("rlib"))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 2 previous errors diff --git a/tests/ui/link-native-libs/issue-43926.stderr b/tests/ui/link-native-libs/issue-43926.stderr index 9e3ec21cc945..f7b85788a2a3 100644 --- a/tests/ui/link-native-libs/issue-43926.stderr +++ b/tests/ui/link-native-libs/issue-43926.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", cfg())] | expected a single argument here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", cfg())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/link-native-libs/link-arg-error2.rs b/tests/ui/link-native-libs/link-arg-error2.rs new file mode 100644 index 000000000000..a51dec0614b5 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.rs @@ -0,0 +1,5 @@ +//@ compile-flags: -l link-arg:+export-symbols=arg -Z unstable-options + +fn main() {} + +//~? ERROR linking modifier `export-symbols` is only compatible with `static` linking kind diff --git a/tests/ui/link-native-libs/link-arg-error2.stderr b/tests/ui/link-native-libs/link-arg-error2.stderr new file mode 100644 index 000000000000..61bcf7dba282 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.stderr @@ -0,0 +1,2 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.rs b/tests/ui/link-native-libs/link-arg-from-rs2.rs new file mode 100644 index 000000000000..3074fec6c1c8 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.rs @@ -0,0 +1,7 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] +//~^ ERROR linking modifier `export-symbols` is only compatible with `static` linking kind +extern "C" {} + +pub fn main() {} diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.stderr b/tests/ui/link-native-libs/link-arg-from-rs2.stderr new file mode 100644 index 000000000000..af3b25253e05 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.stderr @@ -0,0 +1,8 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + --> $DIR/link-arg-from-rs2.rs:3:53 + | +LL | #[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/link-native-libs/link-attr-validation-early.stderr b/tests/ui/link-native-libs/link-attr-validation-early.stderr index e4799b1a1618..4bf88e150f45 100644 --- a/tests/ui/link-native-libs/link-attr-validation-early.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-early.stderr @@ -5,40 +5,16 @@ LL | #[link] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | ++++++++++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | +++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-early.rs:3:1 | LL | #[link = "foo"] - | ^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^-------^ + | | + | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link = "foo"] -LL + #[link(name = "...")] - | -LL - #[link = "foo"] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link = "foo"] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link = "foo"] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 2 previous errors diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index 106b7cebc99f..4a4a19375207 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "...", "literal")] | didn't expect a literal here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", "literal")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:5:1 @@ -32,21 +17,6 @@ LL | #[link(name = "...", unknown)] | valid arguments are "name", "kind", "modifiers", "cfg", "wasm_import_module" or "import_name_type" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", unknown)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:9:1 @@ -57,21 +27,6 @@ LL | #[link(name = "foo", name = "bar")] | found `name` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", name = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:10:1 @@ -82,21 +37,6 @@ LL | #[link(name = "...", kind = "dylib", kind = "bar")] | found `kind` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", kind = "dylib", kind = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:11:1 @@ -107,21 +47,6 @@ LL | #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] | found `modifiers` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers = "+verbatim", modifiers = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:12:1 @@ -132,21 +57,6 @@ LL | #[link(name = "...", cfg(false), cfg(false))] | found `cfg` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg(false), cfg(false))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0538]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:13:1 @@ -157,21 +67,6 @@ LL | #[link(wasm_import_module = "foo", wasm_import_module = "bar")] | found `wasm_import_module` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...")] - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(wasm_import_module = "foo", wasm_import_module = "bar")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:17:1 @@ -182,17 +77,6 @@ LL | #[link(name)] | expected this to be of the form `name = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | +++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | ++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:18:1 @@ -203,21 +87,6 @@ LL | #[link(name())] | expected this to be of the form `name = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name())] -LL + #[link(name = "...")] - | -LL - #[link(name())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:19:1 @@ -228,19 +97,6 @@ LL | #[link(name = "...", kind)] | expected this to be of the form `kind = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", kind)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", kind)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL | #[link(name = "...", kind = "dylib|static|...")] - | ++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:20:1 @@ -251,21 +107,6 @@ LL | #[link(name = "...", kind())] | expected this to be of the form `kind = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", kind())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:21:1 @@ -276,21 +117,6 @@ LL | #[link(name = "...", modifiers)] | expected this to be of the form `modifiers = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:22:1 @@ -301,21 +127,6 @@ LL | #[link(name = "...", modifiers())] | expected this to be of the form `modifiers = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:23:1 @@ -326,46 +137,16 @@ LL | #[link(name = "...", cfg)] | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:24:1 | LL | #[link(name = "...", cfg = "literal")] - | ^^^^^^^^^^^^^^^^^^^^^---------------^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^ + | | + | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg = "literal")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:25:1 @@ -376,21 +157,6 @@ LL | #[link(name = "...", cfg("literal"))] | expected a valid identifier here | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", cfg("literal"))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:26:1 @@ -401,21 +167,6 @@ LL | #[link(name = "...", wasm_import_module)] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:27:1 @@ -426,29 +177,14 @@ LL | #[link(name = "...", wasm_import_module())] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:31:34 | LL | #[link(name = "...", modifiers = "")] | ^^ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:32:34 | LL | #[link(name = "...", modifiers = "no-plus-minus")] @@ -460,24 +196,9 @@ error[E0539]: malformed `link` attribute input LL | #[link(name = "...", modifiers = "+unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ | | - | valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed" + | valid arguments are "bundle", "export-symbols", "verbatim", "whole-archive" or "as-needed" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", modifiers = "+unknown")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: multiple `verbatim` modifiers in a single `modifiers` argument --> $DIR/link-attr-validation-late.rs:34:34 diff --git a/tests/ui/link-native-libs/link-cfg-works.rs b/tests/ui/link-native-libs/link-cfg-works.rs index 7b936bc43b1a..0e02933ce01c 100644 --- a/tests/ui/link-native-libs/link-cfg-works.rs +++ b/tests/ui/link-native-libs/link-cfg-works.rs @@ -7,7 +7,7 @@ extern crate link_cfg_works_transitive_dylib; extern crate link_cfg_works_transitive_rlib; -#[link(name = "foo", cfg(foo))] +#[link(name = "foo", cfg(false))] extern "C" {} fn main() {} diff --git a/tests/ui/link-native-libs/modifiers-bad.blank.stderr b/tests/ui/link-native-libs/modifiers-bad.blank.stderr index ea36af0b4cfa..6a1953e008ee 100644 --- a/tests/ui/link-native-libs/modifiers-bad.blank.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.blank.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr index ea36af0b4cfa..6a1953e008ee 100644 --- a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr index 1e701374688f..46720cf0b15e 100644 --- a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr index 75950ad9c64c..d47694a5aeca 100644 --- a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-override-4.stderr b/tests/ui/link-native-libs/modifiers-override-4.stderr index 317e89cb39cc..12b0d89c79a7 100644 --- a/tests/ui/link-native-libs/modifiers-override-4.stderr +++ b/tests/ui/link-native-libs/modifiers-override-4.stderr @@ -12,49 +12,6 @@ LL | | )] | |__^ | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...")] - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link( -LL - -LL - name = "bar", -LL - kind = "static", -LL - modifiers = "+whole-archive,-whole-archive", -LL - -LL - modifiers = "+bundle" -LL - )] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: multiple `whole-archive` modifiers in a single `modifiers` argument --> $DIR/modifiers-override-4.rs:6:17 diff --git a/tests/ui/linkage-attr/linkage3.stderr b/tests/ui/linkage-attr/linkage3.stderr index f1215f09aeaf..564090e9538f 100644 --- a/tests/ui/linkage-attr/linkage3.stderr +++ b/tests/ui/linkage-attr/linkage3.stderr @@ -5,22 +5,6 @@ LL | #[linkage = "foo"] | ^^^^^^^^^^^^-----^ | | | valid arguments are `available_externally`, `common`, `extern_weak`, `external`, `internal`, `linkonce`, `linkonce_odr`, `weak` or `weak_odr` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[linkage = "foo"] -LL + #[linkage = "available_externally"] - | -LL - #[linkage = "foo"] -LL + #[linkage = "common"] - | -LL - #[linkage = "foo"] -LL + #[linkage = "extern_weak"] - | -LL - #[linkage = "foo"] -LL + #[linkage = "external"] - | - = and 5 other candidates error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr index 6b54f3b247d1..86a53a030f50 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] | expected this to be of the form `import_name_type = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr index 35ddb2a7e3d3..ef909ad7278b 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", im | found `import_name_type` used as a key more than once | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr index b0099675dd23..577ec8e7764c 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] | valid arguments are "decorated", "noprefix" or "undecorated" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs index 58f0a74e674d..e8d277e36d28 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target x86_64-pc-windows-msvc //@ compile-flags: --crate-type lib --emit link //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![no_core] #![feature(no_core)] extern crate minicore; diff --git a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr index 8727e55f4cef..5a574636245d 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr @@ -1,5 +1,5 @@ warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported-abi.rs:13:1 + --> $DIR/unsupported-abi.rs:14:1 | LL | / extern "stdcall" { LL | | @@ -15,7 +15,7 @@ LL | | } = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default error: ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture - --> $DIR/unsupported-abi.rs:16:5 + --> $DIR/unsupported-abi.rs:17:5 | LL | fn f(x: i32); | ^^^^^^^^^^^^^ diff --git a/tests/ui/lint/const-item-interior-mutations-const-atomics.fixed b/tests/ui/lint/const-item-interior-mutations-const-atomics.fixed index 17737e5cb8b9..8441d69a309a 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-atomics.fixed +++ b/tests/ui/lint/const-item-interior-mutations-const-atomics.fixed @@ -3,7 +3,6 @@ #![allow(deprecated)] #![allow(dead_code)] -#![feature(atomic_try_update)] use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU32, Ordering}; diff --git a/tests/ui/lint/const-item-interior-mutations-const-atomics.rs b/tests/ui/lint/const-item-interior-mutations-const-atomics.rs index 4180b2340df6..65973fb378e5 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-atomics.rs +++ b/tests/ui/lint/const-item-interior-mutations-const-atomics.rs @@ -3,7 +3,6 @@ #![allow(deprecated)] #![allow(dead_code)] -#![feature(atomic_try_update)] use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU32, Ordering}; diff --git a/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr b/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr index 17823366d406..908a19682899 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr +++ b/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr @@ -1,5 +1,5 @@ warning: mutation of an interior mutable `const` item with call to `store` - --> $DIR/const-item-interior-mutations-const-atomics.rs:13:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:12:14 | LL | let _a = A.store(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-atomics.rs:16:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:15:14 | LL | let _a = A.swap(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `compare_and_swap` - --> $DIR/const-item-interior-mutations-const-atomics.rs:19:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:18:14 | LL | let _a = A.compare_and_swap(false, true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `compare_exchange` - --> $DIR/const-item-interior-mutations-const-atomics.rs:22:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:21:14 | LL | let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` - --> $DIR/const-item-interior-mutations-const-atomics.rs:25:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:24:14 | LL | let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `fetch_and` - --> $DIR/const-item-interior-mutations-const-atomics.rs:28:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:27:14 | LL | let _a = A.fetch_and(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `fetch_nand` - --> $DIR/const-item-interior-mutations-const-atomics.rs:31:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:30:14 | LL | let _a = A.fetch_nand(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `fetch_or` - --> $DIR/const-item-interior-mutations-const-atomics.rs:34:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:33:14 | LL | let _a = A.fetch_or(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `fetch_xor` - --> $DIR/const-item-interior-mutations-const-atomics.rs:37:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:36:14 | LL | let _a = A.fetch_xor(true, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `fetch_not` - --> $DIR/const-item-interior-mutations-const-atomics.rs:40:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:39:14 | LL | let _a = A.fetch_not(Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `fetch_update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:43:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:42:14 | LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `try_update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:46:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:45:14 | LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:49:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:48:14 | LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL + static A: AtomicBool = AtomicBool::new(false); | warning: mutation of an interior mutable `const` item with call to `store` - --> $DIR/const-item-interior-mutations-const-atomics.rs:56:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:55:14 | LL | let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -238,7 +238,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-atomics.rs:59:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:58:14 | LL | let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `compare_and_swap` - --> $DIR/const-item-interior-mutations-const-atomics.rs:62:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:61:14 | LL | let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `compare_exchange` - --> $DIR/const-item-interior-mutations-const-atomics.rs:65:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:64:14 | LL | let _a = A.compare_exchange( | ^ `A` is a interior mutable `const` item of type `AtomicPtr` @@ -296,7 +296,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` - --> $DIR/const-item-interior-mutations-const-atomics.rs:73:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:72:14 | LL | let _a = A.compare_exchange_weak( | ^ `A` is a interior mutable `const` item of type `AtomicPtr` @@ -320,7 +320,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:81:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:80:14 | LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -337,7 +337,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `try_update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:84:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:83:14 | LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -354,7 +354,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:87:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:86:14 | LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -371,7 +371,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_ptr_add` - --> $DIR/const-item-interior-mutations-const-atomics.rs:90:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:89:14 | LL | let _a = A.fetch_ptr_add(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -388,7 +388,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_ptr_sub` - --> $DIR/const-item-interior-mutations-const-atomics.rs:93:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:92:14 | LL | let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +405,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_byte_add` - --> $DIR/const-item-interior-mutations-const-atomics.rs:96:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:95:14 | LL | let _a = A.fetch_byte_add(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -422,7 +422,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_byte_sub` - --> $DIR/const-item-interior-mutations-const-atomics.rs:99:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:98:14 | LL | let _a = A.fetch_byte_sub(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -439,7 +439,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_and` - --> $DIR/const-item-interior-mutations-const-atomics.rs:102:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:101:14 | LL | let _a = A.fetch_and(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -456,7 +456,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_or` - --> $DIR/const-item-interior-mutations-const-atomics.rs:105:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:104:14 | LL | let _a = A.fetch_or(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -473,7 +473,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `fetch_xor` - --> $DIR/const-item-interior-mutations-const-atomics.rs:108:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:107:14 | LL | let _a = A.fetch_xor(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -490,7 +490,7 @@ LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); | warning: mutation of an interior mutable `const` item with call to `store` - --> $DIR/const-item-interior-mutations-const-atomics.rs:115:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:114:14 | LL | let _a = A.store(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -507,7 +507,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-atomics.rs:118:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:117:14 | LL | let _a = A.swap(2, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -524,7 +524,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `compare_and_swap` - --> $DIR/const-item-interior-mutations-const-atomics.rs:121:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:120:14 | LL | let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -541,7 +541,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `compare_exchange` - --> $DIR/const-item-interior-mutations-const-atomics.rs:124:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:123:14 | LL | let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -558,7 +558,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` - --> $DIR/const-item-interior-mutations-const-atomics.rs:127:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:126:14 | LL | let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -575,7 +575,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_add` - --> $DIR/const-item-interior-mutations-const-atomics.rs:130:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:129:14 | LL | let _a = A.fetch_add(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -592,7 +592,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_sub` - --> $DIR/const-item-interior-mutations-const-atomics.rs:133:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:132:14 | LL | let _a = A.fetch_sub(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -609,7 +609,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_add` - --> $DIR/const-item-interior-mutations-const-atomics.rs:136:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:135:14 | LL | let _a = A.fetch_add(2, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -626,7 +626,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_nand` - --> $DIR/const-item-interior-mutations-const-atomics.rs:139:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:138:14 | LL | let _a = A.fetch_nand(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -643,7 +643,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_or` - --> $DIR/const-item-interior-mutations-const-atomics.rs:142:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:141:14 | LL | let _a = A.fetch_or(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -660,7 +660,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_xor` - --> $DIR/const-item-interior-mutations-const-atomics.rs:145:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:144:14 | LL | let _a = A.fetch_xor(1, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -677,7 +677,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:148:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:147:14 | LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -694,7 +694,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `try_update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:151:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:150:14 | LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -711,7 +711,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `update` - --> $DIR/const-item-interior-mutations-const-atomics.rs:154:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:153:14 | LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -728,7 +728,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_max` - --> $DIR/const-item-interior-mutations-const-atomics.rs:157:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:156:14 | LL | let _a = A.fetch_max(20, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -745,7 +745,7 @@ LL + static A: AtomicU32 = AtomicU32::new(0); | warning: mutation of an interior mutable `const` item with call to `fetch_min` - --> $DIR/const-item-interior-mutations-const-atomics.rs:160:14 + --> $DIR/const-item-interior-mutations-const-atomics.rs:159:14 | LL | let _a = A.fetch_min(5, Ordering::SeqCst); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/const-item-interior-mutations-const-cell.rs b/tests/ui/lint/const-item-interior-mutations-const-cell.rs index b4a7f54c8e7a..22b465fa0a95 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-cell.rs +++ b/tests/ui/lint/const-item-interior-mutations-const-cell.rs @@ -4,7 +4,6 @@ #![feature(sync_unsafe_cell)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::cell::{Cell, RefCell, SyncUnsafeCell, UnsafeCell}; use std::cell::{LazyCell, OnceCell}; diff --git a/tests/ui/lint/const-item-interior-mutations-const-cell.stderr b/tests/ui/lint/const-item-interior-mutations-const-cell.stderr index d9f19c61fa77..ec3a5f4e38ee 100644 --- a/tests/ui/lint/const-item-interior-mutations-const-cell.stderr +++ b/tests/ui/lint/const-item-interior-mutations-const-cell.stderr @@ -1,5 +1,5 @@ warning: mutation of an interior mutable `const` item with call to `force` - --> $DIR/const-item-interior-mutations-const-cell.rs:16:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:15:13 | LL | let _ = LazyCell::force(&A); | ^^^^^^^^^^^^^^^^^-^ @@ -17,7 +17,7 @@ LL + static A: LazyCell = LazyCell::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-cell.rs:23:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:22:13 | LL | let _ = A.set(10); | -^^^^^^^^ @@ -34,7 +34,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `try_insert` - --> $DIR/const-item-interior-mutations-const-cell.rs:26:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:25:13 | LL | let _ = A.try_insert(20); | -^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_init` - --> $DIR/const-item-interior-mutations-const-cell.rs:29:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:28:13 | LL | let _ = A.get_or_init(|| 30); | -^^^^^^^^^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_try_init` - --> $DIR/const-item-interior-mutations-const-cell.rs:32:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:31:13 | LL | let _ = A.get_or_try_init(|| Ok::<_, ()>(40)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + static A: OnceCell = OnceCell::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const-cell.rs:39:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:38:13 | LL | let _ = A.set(1); | -^^^^^^^ @@ -102,7 +102,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-cell.rs:42:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:41:13 | LL | let _ = A.swap(&A); | -^^^^^^^^^ @@ -119,7 +119,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:45:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:44:13 | LL | let _ = A.replace(2); | -^^^^^^^^^^^ @@ -136,7 +136,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:48:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:47:13 | LL | let _ = A.get(); | -^^^^^^ @@ -153,7 +153,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `update` - --> $DIR/const-item-interior-mutations-const-cell.rs:51:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:50:13 | LL | let _ = A.update(|x| x + 1); | -^^^^^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL + static A: Cell = Cell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:58:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:57:13 | LL | let _ = A.replace(1); | -^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace_with` - --> $DIR/const-item-interior-mutations-const-cell.rs:61:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:60:13 | LL | let _ = A.replace_with(|x| *x + 2); | -^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `swap` - --> $DIR/const-item-interior-mutations-const-cell.rs:64:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:63:13 | LL | let _ = A.swap(&A); | -^^^^^^^^^ @@ -221,7 +221,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `borrow` - --> $DIR/const-item-interior-mutations-const-cell.rs:67:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:66:13 | LL | let _ = A.borrow(); | -^^^^^^^^^ @@ -238,7 +238,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `try_borrow` - --> $DIR/const-item-interior-mutations-const-cell.rs:70:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:69:13 | LL | let _ = A.try_borrow(); | -^^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `borrow_mut` - --> $DIR/const-item-interior-mutations-const-cell.rs:73:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:72:13 | LL | let _ = A.borrow_mut(); | -^^^^^^^^^^^^^ @@ -272,7 +272,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `try_borrow_mut` - --> $DIR/const-item-interior-mutations-const-cell.rs:76:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:75:13 | LL | let _ = A.try_borrow_mut(); | -^^^^^^^^^^^^^^^^^ @@ -289,7 +289,7 @@ LL + static A: RefCell = RefCell::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const-cell.rs:83:22 + --> $DIR/const-item-interior-mutations-const-cell.rs:82:22 | LL | let _ = unsafe { A.replace(1) }; | -^^^^^^^^^^^ @@ -306,7 +306,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:86:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:85:13 | LL | let _ = A.get(); | -^^^^^^ @@ -323,7 +323,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `as_ref_unchecked` - --> $DIR/const-item-interior-mutations-const-cell.rs:90:17 + --> $DIR/const-item-interior-mutations-const-cell.rs:89:17 | LL | let _ = A.as_ref_unchecked(); | -^^^^^^^^^^^^^^^^^^^ @@ -340,7 +340,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `as_mut_unchecked` - --> $DIR/const-item-interior-mutations-const-cell.rs:93:17 + --> $DIR/const-item-interior-mutations-const-cell.rs:92:17 | LL | let _ = A.as_mut_unchecked(); | -^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL + static A: UnsafeCell = UnsafeCell::new(0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const-cell.rs:101:13 + --> $DIR/const-item-interior-mutations-const-cell.rs:100:13 | LL | let _ = A.get(); | -^^^^^^ diff --git a/tests/ui/lint/const-item-interior-mutations-const.fixed b/tests/ui/lint/const-item-interior-mutations-const.fixed index 82f3fdac43a3..97091ab10af8 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.fixed +++ b/tests/ui/lint/const-item-interior-mutations-const.fixed @@ -6,7 +6,6 @@ #![feature(lock_value_accessors)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; use std::time::Duration; diff --git a/tests/ui/lint/const-item-interior-mutations-const.rs b/tests/ui/lint/const-item-interior-mutations-const.rs index 5dbbfd8ca32f..40565118ca79 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.rs +++ b/tests/ui/lint/const-item-interior-mutations-const.rs @@ -6,7 +6,6 @@ #![feature(lock_value_accessors)] #![feature(once_cell_try_insert)] #![feature(once_cell_try)] -#![feature(lazy_get)] use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; use std::time::Duration; diff --git a/tests/ui/lint/const-item-interior-mutations-const.stderr b/tests/ui/lint/const-item-interior-mutations-const.stderr index 7d3e7bee7fbb..2fe8f190dbed 100644 --- a/tests/ui/lint/const-item-interior-mutations-const.stderr +++ b/tests/ui/lint/const-item-interior-mutations-const.stderr @@ -1,5 +1,5 @@ warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:17:14 + --> $DIR/const-item-interior-mutations-const.rs:16:14 | LL | let _a = A.set(1); | -^^^^^^^ @@ -17,7 +17,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const.rs:20:14 + --> $DIR/const-item-interior-mutations-const.rs:19:14 | LL | let _a = A.replace(2); | -^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `lock` - --> $DIR/const-item-interior-mutations-const.rs:23:10 + --> $DIR/const-item-interior-mutations-const.rs:22:10 | LL | drop(A.lock()); | -^^^^^^^ @@ -51,7 +51,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `try_lock` - --> $DIR/const-item-interior-mutations-const.rs:26:10 + --> $DIR/const-item-interior-mutations-const.rs:25:10 | LL | drop(A.try_lock()); | -^^^^^^^^^^^ @@ -68,7 +68,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `clear_poison` - --> $DIR/const-item-interior-mutations-const.rs:29:14 + --> $DIR/const-item-interior-mutations-const.rs:28:14 | LL | let _a = A.clear_poison(); | -^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL + static A: Mutex = Mutex::new(0); | warning: mutation of an interior mutable `const` item with call to `call_once` - --> $DIR/const-item-interior-mutations-const.rs:36:14 + --> $DIR/const-item-interior-mutations-const.rs:35:14 | LL | let _a = A.call_once(|| {}); | -^^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `call_once_force` - --> $DIR/const-item-interior-mutations-const.rs:39:14 + --> $DIR/const-item-interior-mutations-const.rs:38:14 | LL | let _a = A.call_once_force(|_| {}); | -^^^^^^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:42:14 + --> $DIR/const-item-interior-mutations-const.rs:41:14 | LL | let _a = A.wait(); | -^^^^^^^ @@ -136,7 +136,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `wait_force` - --> $DIR/const-item-interior-mutations-const.rs:45:14 + --> $DIR/const-item-interior-mutations-const.rs:44:14 | LL | let _a = A.wait_force(); | -^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ LL + static A: Once = Once::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:52:14 + --> $DIR/const-item-interior-mutations-const.rs:51:14 | LL | let _a = A.set(1); | -^^^^^^^ @@ -170,7 +170,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `replace` - --> $DIR/const-item-interior-mutations-const.rs:55:14 + --> $DIR/const-item-interior-mutations-const.rs:54:14 | LL | let _a = A.replace(2); | -^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `read` - --> $DIR/const-item-interior-mutations-const.rs:58:10 + --> $DIR/const-item-interior-mutations-const.rs:57:10 | LL | drop(A.read()); | -^^^^^^^ @@ -204,7 +204,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `try_read` - --> $DIR/const-item-interior-mutations-const.rs:61:10 + --> $DIR/const-item-interior-mutations-const.rs:60:10 | LL | drop(A.try_read()); | -^^^^^^^^^^^ @@ -221,7 +221,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `write` - --> $DIR/const-item-interior-mutations-const.rs:64:10 + --> $DIR/const-item-interior-mutations-const.rs:63:10 | LL | drop(A.write()); | -^^^^^^^^ @@ -238,7 +238,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `try_write` - --> $DIR/const-item-interior-mutations-const.rs:67:10 + --> $DIR/const-item-interior-mutations-const.rs:66:10 | LL | drop(A.try_write()); | -^^^^^^^^^^^^ @@ -255,7 +255,7 @@ LL + static A: RwLock = RwLock::new(0); | warning: mutation of an interior mutable `const` item with call to `force` - --> $DIR/const-item-interior-mutations-const.rs:74:14 + --> $DIR/const-item-interior-mutations-const.rs:73:14 | LL | let _a = LazyLock::force(&A); | ^^^^^^^^^^^^^^^^^-^ @@ -272,7 +272,7 @@ LL + static A: LazyLock = LazyLock::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const.rs:77:14 + --> $DIR/const-item-interior-mutations-const.rs:76:14 | LL | let _a = LazyLock::get(&A); | ^^^^^^^^^^^^^^^-^ @@ -289,7 +289,7 @@ LL + static A: LazyLock = LazyLock::new(|| 0); | warning: mutation of an interior mutable `const` item with call to `get` - --> $DIR/const-item-interior-mutations-const.rs:84:14 + --> $DIR/const-item-interior-mutations-const.rs:83:14 | LL | let _a = A.get(); | -^^^^^^ @@ -306,7 +306,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:87:14 + --> $DIR/const-item-interior-mutations-const.rs:86:14 | LL | let _a = A.wait(); | -^^^^^^^ @@ -323,7 +323,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `set` - --> $DIR/const-item-interior-mutations-const.rs:90:14 + --> $DIR/const-item-interior-mutations-const.rs:89:14 | LL | let _a = A.set(10); | -^^^^^^^^ @@ -340,7 +340,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `try_insert` - --> $DIR/const-item-interior-mutations-const.rs:93:14 + --> $DIR/const-item-interior-mutations-const.rs:92:14 | LL | let _a = A.try_insert(20); | -^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_init` - --> $DIR/const-item-interior-mutations-const.rs:96:14 + --> $DIR/const-item-interior-mutations-const.rs:95:14 | LL | let _a = A.get_or_init(|| 30); | -^^^^^^^^^^^^^^^^^^^ @@ -374,7 +374,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `get_or_try_init` - --> $DIR/const-item-interior-mutations-const.rs:99:14 + --> $DIR/const-item-interior-mutations-const.rs:98:14 | LL | let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -391,7 +391,7 @@ LL + static A: OnceLock = OnceLock::new(); | warning: mutation of an interior mutable `const` item with call to `wait` - --> $DIR/const-item-interior-mutations-const.rs:109:14 + --> $DIR/const-item-interior-mutations-const.rs:108:14 | LL | let _a = A.wait(guard); | -^^^^^^^^^^^^ @@ -408,7 +408,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_while` - --> $DIR/const-item-interior-mutations-const.rs:114:14 + --> $DIR/const-item-interior-mutations-const.rs:113:14 | LL | let _a = A.wait_while(guard, |x| *x == 0); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -425,7 +425,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout_ms` - --> $DIR/const-item-interior-mutations-const.rs:119:14 + --> $DIR/const-item-interior-mutations-const.rs:118:14 | LL | let _a = A.wait_timeout_ms(guard, 10); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -442,7 +442,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout` - --> $DIR/const-item-interior-mutations-const.rs:124:14 + --> $DIR/const-item-interior-mutations-const.rs:123:14 | LL | let _a = A.wait_timeout(guard, Duration::from_millis(10)); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -459,7 +459,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `wait_timeout_while` - --> $DIR/const-item-interior-mutations-const.rs:129:14 + --> $DIR/const-item-interior-mutations-const.rs:128:14 | LL | let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -476,7 +476,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `notify_one` - --> $DIR/const-item-interior-mutations-const.rs:132:14 + --> $DIR/const-item-interior-mutations-const.rs:131:14 | LL | let _a = A.notify_one(); | -^^^^^^^^^^^^^ @@ -493,7 +493,7 @@ LL + static A: Condvar = Condvar::new(); | warning: mutation of an interior mutable `const` item with call to `notify_all` - --> $DIR/const-item-interior-mutations-const.rs:135:14 + --> $DIR/const-item-interior-mutations-const.rs:134:14 | LL | let _a = A.notify_all(); | -^^^^^^^^^^^^^ diff --git a/tests/ui/lint/dangling-pointers-from-locals.stderr b/tests/ui/lint/dangling-pointers-from-locals.stderr index 45acc74ac34e..05ced1cdc004 100644 --- a/tests/ui/lint/dangling-pointers-from-locals.stderr +++ b/tests/ui/lint/dangling-pointers-from-locals.stderr @@ -9,6 +9,7 @@ LL | &x | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see = note: `#[warn(dangling_pointers_from_locals)]` on by default warning: function returns a dangling pointer to dropped local variable `x` @@ -24,6 +25,7 @@ LL | x | ^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:24:12 @@ -38,6 +40,7 @@ LL | return y; | ^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:30:5 @@ -52,6 +55,7 @@ LL | &x as *const u8 | dangling pointer created here | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:37:5 @@ -66,6 +70,7 @@ LL | x as *const u8 | ^^^^^^^^^^^^^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:43:12 @@ -80,6 +85,7 @@ LL | return &mut x as *mut u8 as *const u8 as *mut u8; | dangling pointer created here | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:49:5 @@ -92,6 +98,7 @@ LL | &{ x } | ^^^^^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:57:13 @@ -108,6 +115,7 @@ LL | | } | |_____________^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:67:12 @@ -120,6 +128,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:73:12 @@ -132,6 +141,7 @@ LL | return &mut x; | ^^^^^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:80:16 @@ -145,6 +155,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:88:5 @@ -157,6 +168,7 @@ LL | &x | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:94:12 @@ -169,6 +181,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: closure returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:101:16 @@ -181,6 +194,7 @@ LL | return &x; | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `x` --> $DIR/dangling-pointers-from-locals.rs:113:5 @@ -194,6 +208,7 @@ LL | &x | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:118:5 @@ -206,6 +221,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:123:5 @@ -218,6 +234,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:128:5 @@ -230,6 +247,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: function returns a dangling pointer to dropped local variable `a` --> $DIR/dangling-pointers-from-locals.rs:133:5 @@ -242,6 +260,7 @@ LL | &a | ^^ | = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: for more information, see warning: 19 warnings emitted diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs b/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs index d892ebdf6069..7ecee90479d2 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/allow.rs @@ -7,7 +7,7 @@ fn main() { #[deny(dangling_pointers_from_temporaries)] { dbg!(String::new().as_ptr()); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } S.foo() } @@ -18,6 +18,6 @@ impl S { #[warn(dangling_pointers_from_temporaries)] fn foo(self) { dbg!(String::new().as_ptr()); - //~^ WARNING a dangling pointer will be produced because the temporary `String` will be dropped + //~^ WARNING dangling pointer } } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr index e1c12cfd1a50..a235af144e48 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/allow.rs:9:28 | LL | dbg!(String::new().as_ptr()); - | ------------- ^^^^^^ this pointer will immediately be invalid + | ------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/allow.rs:7:12 | LL | #[deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: a dangling pointer will be produced because the temporary `String` will be dropped +warning: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/allow.rs:20:28 | LL | dbg!(String::new().as_ptr()); - | ------------- ^^^^^^ this pointer will immediately be invalid + | ------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/allow.rs:18:12 | diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs b/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs index b376582a8867..80787390176f 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/calls.rs @@ -25,12 +25,12 @@ fn ok() { fn not_ok() { { let ptr = cstring().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer consume(ptr); } consume({ let ptr = cstring().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer ptr }); consume({ @@ -39,11 +39,11 @@ fn not_ok() { //^ FIXME: should error }); let _ptr: *const u8 = cstring().as_ptr().cast(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer let _ptr: *const u8 = { cstring() }.as_ptr().cast(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer let _ptr: *const u8 = { cstring().as_ptr() }.cast(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer } fn main() { diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr index 41c6cdd0e3ef..4e302dcc9942 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/calls.stderr @@ -1,72 +1,72 @@ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:27:29 | LL | let ptr = cstring().as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/calls.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:32:29 | LL | let ptr = cstring().as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:41:37 | LL | let _ptr: *const u8 = cstring().as_ptr().cast(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:43:41 | LL | let _ptr: *const u8 = { cstring() }.as_ptr().cast(); - | ------------- ^^^^^^ this pointer will immediately be invalid + | ------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/calls.rs:45:39 | LL | let _ptr: *const u8 = { cstring().as_ptr() }.cast(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 5 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs index a98378794abc..7036019362cd 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.rs @@ -7,12 +7,12 @@ use std::ffi::CString; macro_rules! mymacro { () => { let s = CString::new("some text").unwrap().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer } } fn main() { let s = CString::new("some text").unwrap().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer mymacro!(); } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr index d4126ba231f7..be9f8b19545b 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/cstring-as-ptr.stderr @@ -6,39 +6,39 @@ LL | #![deny(temporary_cstring_as_ptr)] | = note: `#[warn(renamed_and_removed_lints)]` on by default -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/cstring-as-ptr.rs:15:48 | LL | let s = CString::new("some text").unwrap().as_ptr(); - | ---------------------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/cstring-as-ptr.rs:2:9 | LL | #![deny(temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/cstring-as-ptr.rs:9:52 | LL | let s = CString::new("some text").unwrap().as_ptr(); - | ---------------------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement ... LL | mymacro!(); | ---------- in this macro invocation | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see = note: this error originates in the macro `mymacro` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs index 0fb07a3f3bc9..771ddb349344 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.rs @@ -3,9 +3,9 @@ const MAX_PATH: usize = 260; fn main() { let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer let str2 = String::from("TotototototototototototototototototoT").as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer unsafe { std::ptr::copy_nonoverlapping(str2, str1, 30); println!("{:?}", String::from_raw_parts(str1, 30, 30)); diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr index aace55e92cf1..b8baa2bf5601 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/example-from-issue123613.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/example-from-issue123613.rs:5:48 | LL | let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); - | ------------------------------- ^^^^^^^^^^ this pointer will immediately be invalid + | ------------------------------- ^^^^^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_mut_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_mut_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_mut_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/example-from-issue123613.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/example-from-issue123613.rs:7:70 | LL | let str2 = String::from("TotototototototototototototototototoT").as_ptr(); - | ----------------------------------------------------- ^^^^^^ this pointer will immediately be invalid + | ----------------------------------------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 2 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs b/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs index a5e84d36090f..e56bc0f433e4 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/ext.rs @@ -26,7 +26,7 @@ impl Ext2 for *const u32 { fn main() { let _ptr1 = Vec::::new().as_ptr().dbg(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer let _ptr2 = vec![0].as_ptr().foo(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr index 976334ddef9c..f780f88134f2 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/ext.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/ext.rs:28:35 | LL | let _ptr1 = Vec::::new().as_ptr().dbg(); - | ----------------- ^^^^^^ this pointer will immediately be invalid + | ----------------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/ext.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/ext.rs:30:25 | LL | let _ptr2 = vec![0].as_ptr().foo(); - | ------- ^^^^^^ this pointer will immediately be invalid + | ------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 2 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs b/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs index 26019b376d3a..10666e0a8282 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/methods.rs @@ -2,7 +2,7 @@ fn main() { vec![0u8].as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer vec![0u8].as_mut_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr index a86a69bc39a2..367dfae9e65d 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/methods.stderr @@ -1,33 +1,33 @@ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/methods.rs:4:15 | LL | vec![0u8].as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/methods.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/methods.rs:6:15 | LL | vec![0u8].as_mut_ptr(); - | --------- ^^^^^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_mut_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_mut_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_mut_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 2 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs index 1f216586ae81..1f816996d514 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.rs @@ -19,18 +19,18 @@ fn main() { // Call string().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // MethodCall "hello".to_string().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // Tup // impossible // Binary (string() + "hello").as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // Path { @@ -66,7 +66,7 @@ fn main() { // If { (if true { String::new() } else { "hello".into() }).as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } // Loop @@ -75,7 +75,7 @@ fn main() { break String::new(); }) .as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } // Match @@ -84,7 +84,7 @@ fn main() { s => s, } .as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer } // Closure @@ -92,7 +92,7 @@ fn main() { // Block { string() }.as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer // Assign, AssignOp // impossible @@ -132,5 +132,5 @@ fn main() { // Macro vec![0u8].as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr index e8994703cabf..be001acad747 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/temporaries.stderr @@ -1,115 +1,115 @@ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:21:14 | LL | string().as_ptr(); - | -------- ^^^^^^ this pointer will immediately be invalid + | -------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/temporaries.rs:2:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:25:25 | LL | "hello".to_string().as_ptr(); - | ------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:32:26 | LL | (string() + "hello").as_ptr(); - | -------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:68:61 | LL | (if true { String::new() } else { "hello".into() }).as_ptr(); - | --------------------------------------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------------------------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:77:10 | LL | / (loop { LL | | break String::new(); LL | | }) - | |__________- this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | |__________- this `String` is dropped at end of statement LL | .as_ptr(); - | ^^^^^^ this pointer will immediately be invalid + | ^^^^^^ pointer created here | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:86:10 | LL | / match string() { LL | | s => s, LL | | } - | |_________- this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | |_________- this `String` is dropped at end of statement LL | .as_ptr(); - | ^^^^^^ this pointer will immediately be invalid + | ^^^^^^ pointer created here | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/temporaries.rs:94:18 | LL | { string() }.as_ptr(); - | ------------ ^^^^^^ this pointer will immediately be invalid + | ------------ ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/temporaries.rs:134:15 | LL | vec![0u8].as_ptr(); - | --------- ^^^^^^ this pointer will immediately be invalid + | --------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 8 previous errors diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/types.rs b/tests/ui/lint/dangling-pointers-from-temporaries/types.rs index 17c3eca89e27..072ec25f4d83 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/types.rs +++ b/tests/ui/lint/dangling-pointers-from-temporaries/types.rs @@ -19,39 +19,39 @@ fn declval() -> T { fn main() { declval::().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `CString` will be dropped + //~^ ERROR dangling pointer because temporary `CString` declval::().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `String` will be dropped + //~^ ERROR dangling pointer because temporary `String` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer because temporary `Vec` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box<[u8]>` will be dropped + //~^ ERROR dangling pointer because temporary `Box<[u8]>` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::<[u8; 10]>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `[u8; 10]` will be dropped + //~^ ERROR dangling pointer because temporary `[u8; 10]` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box<[u8; 10]>` will be dropped + //~^ ERROR dangling pointer because temporary `Box<[u8; 10]>` declval::>>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box>` will be dropped + //~^ ERROR dangling pointer because temporary `Box>` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box` will be dropped + //~^ ERROR dangling pointer because temporary `Box` declval::>>>>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Box>>>` will be dropped + //~^ ERROR dangling pointer because temporary `Box>>>` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Cell` will be dropped + //~^ ERROR dangling pointer because temporary `Cell` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `MaybeUninit` will be dropped + //~^ ERROR dangling pointer because temporary `MaybeUninit` declval::>().as_ptr(); - //~^ ERROR a dangling pointer will be produced because the temporary `Vec` will be dropped + //~^ ERROR dangling pointer because temporary `Vec` declval::>().get(); - //~^ ERROR a dangling pointer will be produced because the temporary `UnsafeCell` will be dropped + //~^ ERROR dangling pointer because temporary `UnsafeCell` declval::>().get(); - //~^ ERROR a dangling pointer will be produced because the temporary `SyncUnsafeCell` will be dropped + //~^ ERROR dangling pointer because temporary `SyncUnsafeCell` declval::>().as_ptr(); declval::().as_ptr(); } diff --git a/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr b/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr index fab2459b53f6..bb37c8ad211b 100644 --- a/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr +++ b/tests/ui/lint/dangling-pointers-from-temporaries/types.stderr @@ -1,228 +1,228 @@ -error: a dangling pointer will be produced because the temporary `CString` will be dropped +error: this creates a dangling pointer because temporary `CString` is dropped at end of statement --> $DIR/types.rs:21:26 | LL | declval::().as_ptr(); - | -------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------- ^^^^^^ pointer created here | | - | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `CString` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `CString` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `CString` inside the function will not suffice - = help: for more information, see + = help: bind the `CString` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see note: the lint level is defined here --> $DIR/types.rs:1:9 | LL | #![deny(dangling_pointers_from_temporaries)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: a dangling pointer will be produced because the temporary `String` will be dropped +error: this creates a dangling pointer because temporary `String` is dropped at end of statement --> $DIR/types.rs:23:25 | LL | declval::().as_ptr(); - | ------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------- ^^^^^^ pointer created here | | - | this `String` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `String` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `String` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `String` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `String` inside the function will not suffice - = help: for more information, see + = help: bind the `String` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/types.rs:25:26 | LL | declval::>().as_ptr(); - | -------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:27:31 | LL | declval::>().as_ptr(); - | ------------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------------- ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box<[u8]>` will be dropped +error: this creates a dangling pointer because temporary `Box<[u8]>` is dropped at end of statement --> $DIR/types.rs:29:28 | LL | declval::>().as_ptr(); - | ---------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------- ^^^^^^ pointer created here | | - | this `Box<[u8]>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box<[u8]>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<[u8]>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box<[u8]>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box<[u8]>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box<[u8]>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:31:27 | LL | declval::>().as_ptr(); - | --------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------- ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:33:28 | LL | declval::>().as_ptr(); - | ---------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------- ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `[u8; 10]` will be dropped +error: this creates a dangling pointer because temporary `[u8; 10]` is dropped at end of statement --> $DIR/types.rs:35:27 | LL | declval::<[u8; 10]>().as_ptr(); - | --------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------- ^^^^^^ pointer created here | | - | this `[u8; 10]` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `[u8; 10]` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `[u8; 10]` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `[u8; 10]` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `[u8; 10]` inside the function will not suffice - = help: for more information, see + = help: bind the `[u8; 10]` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box<[u8; 10]>` will be dropped +error: this creates a dangling pointer because temporary `Box<[u8; 10]>` is dropped at end of statement --> $DIR/types.rs:37:32 | LL | declval::>().as_ptr(); - | -------------------------- ^^^^^^ this pointer will immediately be invalid + | -------------------------- ^^^^^^ pointer created here | | - | this `Box<[u8; 10]>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box<[u8; 10]>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box<[u8; 10]>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box<[u8; 10]>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box<[u8; 10]>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box<[u8; 10]>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box>` will be dropped +error: this creates a dangling pointer because temporary `Box>` is dropped at end of statement --> $DIR/types.rs:39:31 | LL | declval::>>().as_ptr(); - | ------------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------------- ^^^^^^ pointer created here | | - | this `Box>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box` will be dropped +error: this creates a dangling pointer because temporary `Box` is dropped at end of statement --> $DIR/types.rs:41:30 | LL | declval::>().as_ptr(); - | ------------------------ ^^^^^^ this pointer will immediately be invalid + | ------------------------ ^^^^^^ pointer created here | | - | this `Box` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box` inside the function will not suffice - = help: for more information, see + = help: bind the `Box` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Box>>>` will be dropped +error: this creates a dangling pointer because temporary `Box>>>` is dropped at end of statement --> $DIR/types.rs:43:43 | LL | declval::>>>>().as_ptr(); - | ------------------------------------- ^^^^^^ this pointer will immediately be invalid + | ------------------------------------- ^^^^^^ pointer created here | | - | this `Box>>>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Box>>>` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Box>>>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Box>>>` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Box>>>` inside the function will not suffice - = help: for more information, see + = help: bind the `Box>>>` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Cell` will be dropped +error: this creates a dangling pointer because temporary `Cell` is dropped at end of statement --> $DIR/types.rs:45:27 | LL | declval::>().as_ptr(); - | --------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------- ^^^^^^ pointer created here | | - | this `Cell` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Cell` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Cell` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Cell` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Cell` inside the function will not suffice - = help: for more information, see + = help: bind the `Cell` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `MaybeUninit` will be dropped +error: this creates a dangling pointer because temporary `MaybeUninit` is dropped at end of statement --> $DIR/types.rs:47:34 | LL | declval::>().as_ptr(); - | ---------------------------- ^^^^^^ this pointer will immediately be invalid + | ---------------------------- ^^^^^^ pointer created here | | - | this `MaybeUninit` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `MaybeUninit` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `MaybeUninit` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `MaybeUninit` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `MaybeUninit` inside the function will not suffice - = help: for more information, see + = help: bind the `MaybeUninit` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `Vec` will be dropped +error: this creates a dangling pointer because temporary `Vec` is dropped at end of statement --> $DIR/types.rs:49:33 | LL | declval::>().as_ptr(); - | --------------------------- ^^^^^^ this pointer will immediately be invalid + | --------------------------- ^^^^^^ pointer created here | | - | this `Vec` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `Vec` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `as_ptr` the `Vec` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `Vec` to lives at least as long as the pointer returned by the call to `as_ptr` - = help: in particular, if this pointer is returned from the current function, binding the `Vec` inside the function will not suffice - = help: for more information, see + = help: bind the `Vec` to a variable such that it outlives the pointer returned by `as_ptr` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `UnsafeCell` will be dropped +error: this creates a dangling pointer because temporary `UnsafeCell` is dropped at end of statement --> $DIR/types.rs:51:33 | LL | declval::>().get(); - | --------------------------- ^^^ this pointer will immediately be invalid + | --------------------------- ^^^ pointer created here | | - | this `UnsafeCell` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `UnsafeCell` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `get` the `UnsafeCell` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `UnsafeCell` to lives at least as long as the pointer returned by the call to `get` - = help: in particular, if this pointer is returned from the current function, binding the `UnsafeCell` inside the function will not suffice - = help: for more information, see + = help: bind the `UnsafeCell` to a variable such that it outlives the pointer returned by `get` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see -error: a dangling pointer will be produced because the temporary `SyncUnsafeCell` will be dropped +error: this creates a dangling pointer because temporary `SyncUnsafeCell` is dropped at end of statement --> $DIR/types.rs:53:37 | LL | declval::>().get(); - | ------------------------------- ^^^ this pointer will immediately be invalid + | ------------------------------- ^^^ pointer created here | | - | this `SyncUnsafeCell` is deallocated at the end of the statement, bind it to a variable to extend its lifetime + | this `SyncUnsafeCell` is dropped at end of statement | - = note: pointers do not have a lifetime; when calling `get` the `SyncUnsafeCell` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: you must make sure that the variable you bind the `SyncUnsafeCell` to lives at least as long as the pointer returned by the call to `get` - = help: in particular, if this pointer is returned from the current function, binding the `SyncUnsafeCell` inside the function will not suffice - = help: for more information, see + = help: bind the `SyncUnsafeCell` to a variable such that it outlives the pointer returned by `get` + = note: a dangling pointer is safe, but dereferencing one is undefined behavior + = note: returning a pointer to a local variable will always result in a dangling pointer + = note: for more information, see error: aborting due to 17 previous errors diff --git a/tests/ui/lint/dead-code/allow-trait-or-impl.rs b/tests/ui/lint/dead-code/allow-trait-or-impl.rs new file mode 100644 index 000000000000..92817549a91e --- /dev/null +++ b/tests/ui/lint/dead-code/allow-trait-or-impl.rs @@ -0,0 +1,38 @@ +#![deny(dead_code)] + +pub mod a { + pub trait Foo { } + impl Foo for u32 { } + + struct PrivateType; //~ ERROR struct `PrivateType` is never constructed + impl Foo for PrivateType { } // <-- warns as dead, even though Foo is public + + struct AnotherPrivateType; //~ ERROR struct `AnotherPrivateType` is never constructed + impl Foo for AnotherPrivateType { } // <-- warns as dead, even though Foo is public +} + +pub mod b { + #[allow(dead_code)] + pub trait Foo { } + impl Foo for u32 { } + + struct PrivateType; + impl Foo for PrivateType { } // <-- no warning, trait is "allowed" + + struct AnotherPrivateType; + impl Foo for AnotherPrivateType { } // <-- no warning, trait is "allowed" +} + +pub mod c { + pub trait Foo { } + impl Foo for u32 { } + + struct PrivateType; + #[allow(dead_code)] + impl Foo for PrivateType { } // <-- no warning, impl is allowed + + struct AnotherPrivateType; //~ ERROR struct `AnotherPrivateType` is never constructed + impl Foo for AnotherPrivateType { } // <-- warns as dead, even though Foo is public +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/allow-trait-or-impl.stderr b/tests/ui/lint/dead-code/allow-trait-or-impl.stderr new file mode 100644 index 000000000000..130116b6c91d --- /dev/null +++ b/tests/ui/lint/dead-code/allow-trait-or-impl.stderr @@ -0,0 +1,26 @@ +error: struct `PrivateType` is never constructed + --> $DIR/allow-trait-or-impl.rs:7:12 + | +LL | struct PrivateType; + | ^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/allow-trait-or-impl.rs:1:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: struct `AnotherPrivateType` is never constructed + --> $DIR/allow-trait-or-impl.rs:10:12 + | +LL | struct AnotherPrivateType; + | ^^^^^^^^^^^^^^^^^^ + +error: struct `AnotherPrivateType` is never constructed + --> $DIR/allow-trait-or-impl.rs:34:12 + | +LL | struct AnotherPrivateType; + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/lint/dead-code/allow-unused-trait.rs b/tests/ui/lint/dead-code/allow-unused-trait.rs new file mode 100644 index 000000000000..4eb63bd4d27a --- /dev/null +++ b/tests/ui/lint/dead-code/allow-unused-trait.rs @@ -0,0 +1,29 @@ +//@ check-pass + +#![deny(dead_code)] + +#[allow(dead_code)] +trait Foo { + const FOO: u32; + type Baz; + fn foobar(); +} + +const fn bar(x: u32) -> u32 { + x +} + +struct Qux; + +struct FooBar; + +impl Foo for u32 { + const FOO: u32 = bar(0); + type Baz = Qux; + + fn foobar() { + let _ = FooBar; + } +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/closure-bang.stderr b/tests/ui/lint/dead-code/closure-bang.stderr index a0f5962dfe02..c2f83c17179c 100644 --- a/tests/ui/lint/dead-code/closure-bang.stderr +++ b/tests/ui/lint/dead-code/closure-bang.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/lint/dead-code/unused-fn-with-check-pass.rs b/tests/ui/lint/dead-code/unused-fn-with-check-pass.rs new file mode 100644 index 000000000000..a4853e125a1a --- /dev/null +++ b/tests/ui/lint/dead-code/unused-fn-with-check-pass.rs @@ -0,0 +1,8 @@ +//@ check-pass +//@ compile-flags: -Wunused + +fn foo() -> &'static str { //~ WARN function `foo` is never used + "hello" +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr b/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr new file mode 100644 index 000000000000..add938553563 --- /dev/null +++ b/tests/ui/lint/dead-code/unused-fn-with-check-pass.stderr @@ -0,0 +1,11 @@ +warning: function `foo` is never used + --> $DIR/unused-fn-with-check-pass.rs:4:4 + | +LL | fn foo() -> &'static str { + | ^^^ + | + = note: `-W dead-code` implied by `-W unused` + = help: to override `-W unused` add `#[expect(dead_code)]` or `#[allow(dead_code)]` + +warning: 1 warning emitted + diff --git a/tests/ui/lint/dead-code/with-core-crate.rs b/tests/ui/lint/dead-code/with-core-crate.rs index 0a94b528f333..9ccb6aecb75f 100644 --- a/tests/ui/lint/dead-code/with-core-crate.rs +++ b/tests/ui/lint/dead-code/with-core-crate.rs @@ -1,7 +1,6 @@ #![deny(dead_code)] #![allow(unreachable_code)] -#[macro_use] extern crate core; fn foo() { //~ ERROR function `foo` is never used diff --git a/tests/ui/lint/dead-code/with-core-crate.stderr b/tests/ui/lint/dead-code/with-core-crate.stderr index f466a616580c..9db26c956298 100644 --- a/tests/ui/lint/dead-code/with-core-crate.stderr +++ b/tests/ui/lint/dead-code/with-core-crate.stderr @@ -1,5 +1,5 @@ error: function `foo` is never used - --> $DIR/with-core-crate.rs:7:4 + --> $DIR/with-core-crate.rs:6:4 | LL | fn foo() { | ^^^ diff --git a/tests/ui/lint/fn-ptr-comparisons-some.stderr b/tests/ui/lint/fn-ptr-comparisons-some.stderr index 522c4399bce1..8674ce5e4a88 100644 --- a/tests/ui/lint/fn-ptr-comparisons-some.stderr +++ b/tests/ui/lint/fn-ptr-comparisons-some.stderr @@ -18,7 +18,6 @@ LL | assert_eq!(Some::(func), Some(func as unsafe extern "C" fn())); = note: the address of the same function can vary between different codegen units = note: furthermore, different functions could have the same address after being merged together = note: for more information visit - = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 2 warnings emitted diff --git a/tests/ui/lint/fn-ptr-comparisons-weird.stderr b/tests/ui/lint/fn-ptr-comparisons-weird.stderr index 2014e519c253..3c76e05016f5 100644 --- a/tests/ui/lint/fn-ptr-comparisons-weird.stderr +++ b/tests/ui/lint/fn-ptr-comparisons-weird.stderr @@ -61,7 +61,6 @@ LL | let _ = assert_eq!(g, g); = note: the address of the same function can vary between different codegen units = note: furthermore, different functions could have the same address after being merged together = note: for more information visit - = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique --> $DIR/fn-ptr-comparisons-weird.rs:35:13 @@ -72,7 +71,6 @@ LL | let _ = assert_ne!(g, g); = note: the address of the same function can vary between different codegen units = note: furthermore, different functions could have the same address after being merged together = note: for more information visit - = note: this warning originates in the macro `assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 7 warnings emitted diff --git a/tests/ui/lint/fn_must_use.stderr b/tests/ui/lint/fn_must_use.stderr index 0e8da873e7c3..bdf4eb6de4a5 100644 --- a/tests/ui/lint/fn_must_use.stderr +++ b/tests/ui/lint/fn_must_use.stderr @@ -5,7 +5,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions + = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, and traits = note: requested on the command line with `-W unused-attributes` warning: unused return value of `need_to_use_this_value` that must be used diff --git a/tests/ui/lint/future-incompatible-lint-group.stderr b/tests/ui/lint/future-incompatible-lint-group.stderr index bac24740fb4e..ff1e54f5dea3 100644 --- a/tests/ui/lint/future-incompatible-lint-group.stderr +++ b/tests/ui/lint/future-incompatible-lint-group.stderr @@ -5,7 +5,7 @@ LL | fn f(u8) {} | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error: ambiguous associated item diff --git a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs index 92cab01fe48c..d095903ec03a 100644 --- a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs +++ b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.rs @@ -4,7 +4,7 @@ // Typeck fails for the arg type as // `Self` makes no sense here -fn func(a: Self::ItemsIterator) { //~ ERROR failed to resolve: `Self` is only available in impls, traits, and type definitions +fn func(a: Self::ItemsIterator) { //~ ERROR cannot find `Self` a.into_iter(); } diff --git a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr index 73ceddae940b..1a0eaba92375 100644 --- a/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr +++ b/tests/ui/lint/ice-array-into-iter-lint-issue-121532.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find `Self` in this scope --> $DIR/ice-array-into-iter-lint-issue-121532.rs:7:12 | LL | fn func(a: Self::ItemsIterator) { diff --git a/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs new file mode 100644 index 000000000000..5d4279fc834d --- /dev/null +++ b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.rs @@ -0,0 +1,10 @@ +#![feature(unsafe_binders)] +#![expect(incomplete_features)] +#![deny(improper_ctypes)] + +extern "C" { + fn exit_2(x: unsafe<'a> &'a ()); + //~^ ERROR `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe +} + +fn main() {} diff --git a/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr new file mode 100644 index 000000000000..4b8d51690f1a --- /dev/null +++ b/tests/ui/lint/improper-ctypes/unsafe-binder-basic.stderr @@ -0,0 +1,15 @@ +error: `extern` block uses type `unsafe<'a> &'a ()`, which is not FFI-safe + --> $DIR/unsafe-binder-basic.rs:6:18 + | +LL | fn exit_2(x: unsafe<'a> &'a ()); + | ^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: unsafe binders are incompatible with foreign function interfaces +note: the lint level is defined here + --> $DIR/unsafe-binder-basic.rs:3:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/invalid_value-polymorphic.rs b/tests/ui/lint/invalid_value-polymorphic.rs index 6a31ac17d96f..4ed8950d20fa 100644 --- a/tests/ui/lint/invalid_value-polymorphic.rs +++ b/tests/ui/lint/invalid_value-polymorphic.rs @@ -1,4 +1,4 @@ -//@ compile-flags: --crate-type=lib -Zmir-enable-passes=+InstSimplify +//@ compile-flags: --crate-type=lib -Zmir-enable-passes=+InstSimplify-before-inline //@ build-pass #![feature(core_intrinsics)] diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr index cc6a2a1c8e53..3dd2a521ff2e 100644 --- a/tests/ui/lint/invalid_value.stderr +++ b/tests/ui/lint/invalid_value.stderr @@ -333,7 +333,6 @@ LL | let _val: (NonZero, i32) = mem::uninitialized(); | = note: `std::num::NonZero` must be non-null = note: because `core::num::niche_types::NonZeroU32Inner` must be non-null - = note: integers must be initialized error: the type `*const dyn Send` does not permit zero-initialization --> $DIR/invalid_value.rs:97:37 @@ -430,7 +429,6 @@ note: because `std::num::NonZero` must be non-null (in this field of the on LL | Banana(NonZero), | ^^^^^^^^^^^^ = note: because `core::num::niche_types::NonZeroU32Inner` must be non-null - = note: integers must be initialized error: the type `bool` does not permit being left uninitialized --> $DIR/invalid_value.rs:111:26 diff --git a/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs index 5b5843a8ddbb..570b559eb61a 100644 --- a/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs +++ b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs @@ -1,5 +1,5 @@ //@ run-pass -#![allow(unused_variables)] +#![warn(unused)] #![deny(non_shorthand_field_patterns)] pub struct Value { pub value: A } @@ -13,5 +13,5 @@ macro_rules! pat { fn main() { let pat!(value) = Value { value: () }; - //~^ WARN value assigned to `value` is never read + //~^ WARN unused variable: `value` } diff --git a/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.stderr b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.stderr index ba7d3515b0d8..3a68ec212b4a 100644 --- a/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.stderr +++ b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.stderr @@ -1,11 +1,15 @@ -warning: value assigned to `value` is never read +warning: unused variable: `value` --> $DIR/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs:15:14 | LL | let pat!(value) = Value { value: () }; - | ^^^^^ + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_value` | - = help: maybe it is overwritten before being read? - = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default +note: the lint level is defined here + --> $DIR/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs:2:9 + | +LL | #![warn(unused)] + | ^^^^^^ + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: 1 warning emitted diff --git a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr index 77c8d1eab584..506791fd1726 100644 --- a/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr +++ b/tests/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr @@ -413,3 +413,21 @@ note: the lint level is defined here LL | #![forbid(forbidden_lint_groups)] | ^^^^^^^^^^^^^^^^^^^^^ +Future breakage diagnostic: +error: warn(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:22:13 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | #![deny(unused)] +LL | #![warn(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/lint/issue-97094.rs b/tests/ui/lint/issue-97094.rs index 22525ca11ae0..737f2827b67a 100644 --- a/tests/ui/lint/issue-97094.rs +++ b/tests/ui/lint/issue-97094.rs @@ -2,19 +2,19 @@ // Ensure that unknown lints inside cfg-attr's are linted for -#![cfg_attr(all(), allow(nonex_lint_top_level))] +#![cfg_attr(true, allow(nonex_lint_top_level))] //~^ ERROR unknown lint -#![cfg_attr(all(), allow(bare_trait_object))] +#![cfg_attr(true, allow(bare_trait_object))] //~^ ERROR has been renamed -#[cfg_attr(all(), allow(nonex_lint_mod))] +#[cfg_attr(true, allow(nonex_lint_mod))] //~^ ERROR unknown lint mod baz { - #![cfg_attr(all(), allow(nonex_lint_mod_inner))] + #![cfg_attr(true, allow(nonex_lint_mod_inner))] //~^ ERROR unknown lint } -#[cfg_attr(all(), allow(nonex_lint_fn))] +#[cfg_attr(true, allow(nonex_lint_fn))] //~^ ERROR unknown lint pub fn main() {} @@ -25,24 +25,24 @@ macro_rules! bar { } bar!( - #[cfg_attr(all(), allow(nonex_lint_in_macro))] + #[cfg_attr(true, allow(nonex_lint_in_macro))] //~^ ERROR unknown lint pub fn _bar() {} ); // No warning for non-applying cfg -#[cfg_attr(any(), allow(nonex_lint_fn))] +#[cfg_attr(false, allow(nonex_lint_fn))] pub fn _foo() {} // Allowing unknown lints works if inside cfg_attr -#[cfg_attr(all(), allow(unknown_lints))] +#[cfg_attr(true, allow(unknown_lints))] mod bar_allowed { #[allow(nonex_lint_fn)] fn _foo() {} } // ... but not if the cfg_attr doesn't evaluate -#[cfg_attr(any(), allow(unknown_lints))] +#[cfg_attr(false, allow(unknown_lints))] mod bar_not_allowed { #[allow(nonex_lint_fn)] //~^ ERROR unknown lint diff --git a/tests/ui/lint/issue-97094.stderr b/tests/ui/lint/issue-97094.stderr index 1a0a3eaf2507..e12250aa7542 100644 --- a/tests/ui/lint/issue-97094.stderr +++ b/tests/ui/lint/issue-97094.stderr @@ -1,8 +1,8 @@ error: unknown lint: `nonex_lint_top_level` - --> $DIR/issue-97094.rs:5:26 + --> $DIR/issue-97094.rs:5:25 | -LL | #![cfg_attr(all(), allow(nonex_lint_top_level))] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![cfg_attr(true, allow(nonex_lint_top_level))] + | ^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/issue-97094.rs:1:9 @@ -12,36 +12,36 @@ LL | #![deny(warnings)] = note: `#[deny(unknown_lints)]` implied by `#[deny(warnings)]` error: lint `bare_trait_object` has been renamed to `bare_trait_objects` - --> $DIR/issue-97094.rs:7:26 + --> $DIR/issue-97094.rs:7:25 | -LL | #![cfg_attr(all(), allow(bare_trait_object))] - | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects` +LL | #![cfg_attr(true, allow(bare_trait_object))] + | ^^^^^^^^^^^^^^^^^ help: use the new name: `bare_trait_objects` | = note: `#[deny(renamed_and_removed_lints)]` implied by `#[deny(warnings)]` error: unknown lint: `nonex_lint_mod` - --> $DIR/issue-97094.rs:10:25 + --> $DIR/issue-97094.rs:10:24 | -LL | #[cfg_attr(all(), allow(nonex_lint_mod))] - | ^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, allow(nonex_lint_mod))] + | ^^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_mod_inner` - --> $DIR/issue-97094.rs:13:30 + --> $DIR/issue-97094.rs:13:29 | -LL | #![cfg_attr(all(), allow(nonex_lint_mod_inner))] - | ^^^^^^^^^^^^^^^^^^^^ +LL | #![cfg_attr(true, allow(nonex_lint_mod_inner))] + | ^^^^^^^^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_fn` - --> $DIR/issue-97094.rs:17:25 + --> $DIR/issue-97094.rs:17:24 | -LL | #[cfg_attr(all(), allow(nonex_lint_fn))] - | ^^^^^^^^^^^^^ +LL | #[cfg_attr(true, allow(nonex_lint_fn))] + | ^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_in_macro` - --> $DIR/issue-97094.rs:28:29 + --> $DIR/issue-97094.rs:28:28 | -LL | #[cfg_attr(all(), allow(nonex_lint_in_macro))] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true, allow(nonex_lint_in_macro))] + | ^^^^^^^^^^^^^^^^^^^ error: unknown lint: `nonex_lint_fn` --> $DIR/issue-97094.rs:47:13 diff --git a/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr b/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr index 6e42328a1113..b8e7abf4807c 100644 --- a/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr +++ b/tests/ui/lint/large_assignments/copy_into_box_rc_arc.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | let _ = NotBox::new(data); | ^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/copy_into_box_rc_arc.rs:1:9 | @@ -19,7 +19,7 @@ LL | | data, LL | | } | |_________^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/copy_into_fn.stderr b/tests/ui/lint/large_assignments/copy_into_fn.stderr index f05fc33e17e1..a4c4800266af 100644 --- a/tests/ui/lint/large_assignments/copy_into_fn.stderr +++ b/tests/ui/lint/large_assignments/copy_into_fn.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | one_arg(Data([0; 9999])); | ^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/copy_into_fn.rs:5:9 | @@ -17,7 +17,7 @@ error: moving 9999 bytes LL | many_args(Data([0; 9999]), true, Data([0; 9999])); | ^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: moving 9999 bytes --> $DIR/copy_into_fn.rs:17:38 @@ -25,7 +25,7 @@ error: moving 9999 bytes LL | many_args(Data([0; 9999]), true, Data([0; 9999])); | ^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 3 previous errors diff --git a/tests/ui/lint/large_assignments/inline_mir.stderr b/tests/ui/lint/large_assignments/inline_mir.stderr index 1a5fcb6c8fc1..b8170d8977d2 100644 --- a/tests/ui/lint/large_assignments/inline_mir.stderr +++ b/tests/ui/lint/large_assignments/inline_mir.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | let cell = std::cell::UnsafeCell::new(data); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/inline_mir.rs:2:9 | @@ -17,7 +17,7 @@ error: moving 9999 bytes LL | std::hint::black_box(cell); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/large_future.attribute.stderr b/tests/ui/lint/large_assignments/large_future.attribute.stderr index 734b7ff7ba22..1580c31df3c2 100644 --- a/tests/ui/lint/large_assignments/large_future.attribute.stderr +++ b/tests/ui/lint/large_assignments/large_future.attribute.stderr @@ -4,7 +4,7 @@ error: moving 10024 bytes LL | let z = (x, 42); | ^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/large_future.rs:1:9 | @@ -17,7 +17,7 @@ error: moving 10024 bytes LL | let a = z.0; | ^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/large_future.option.stderr b/tests/ui/lint/large_assignments/large_future.option.stderr index 734b7ff7ba22..1580c31df3c2 100644 --- a/tests/ui/lint/large_assignments/large_future.option.stderr +++ b/tests/ui/lint/large_assignments/large_future.option.stderr @@ -4,7 +4,7 @@ error: moving 10024 bytes LL | let z = (x, 42); | ^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/large_future.rs:1:9 | @@ -17,7 +17,7 @@ error: moving 10024 bytes LL | let a = z.0; | ^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr b/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr index a386de5e5e8e..35f30a79ad99 100644 --- a/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr +++ b/tests/ui/lint/large_assignments/move_into_box_rc_arc.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | data, | ^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/move_into_box_rc_arc.rs:1:9 | diff --git a/tests/ui/lint/large_assignments/move_into_fn.stderr b/tests/ui/lint/large_assignments/move_into_fn.stderr index 19ec6a51d2e7..4f4c710cacef 100644 --- a/tests/ui/lint/large_assignments/move_into_fn.stderr +++ b/tests/ui/lint/large_assignments/move_into_fn.stderr @@ -4,7 +4,7 @@ error: moving 9999 bytes LL | let data = Data([100; 9999]); | ^^^^^^^^^^^^^^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/move_into_fn.rs:5:9 | @@ -17,7 +17,7 @@ error: moving 9999 bytes LL | take_data(data); | ^^^^ value moved from here | - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` + = note: the current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: aborting due to 2 previous errors diff --git a/tests/ui/lint/lint-forbid-attr.rs b/tests/ui/lint/lint-forbid-attr.rs index 270a379c2f84..cbe7a02a0c17 100644 --- a/tests/ui/lint/lint-forbid-attr.rs +++ b/tests/ui/lint/lint-forbid-attr.rs @@ -1,6 +1,7 @@ -#![forbid(deprecated)] +#![forbid(deprecated)] //~ NOTE `forbid` level set here #[allow(deprecated)] -//~^ ERROR allow(deprecated) incompatible +//~^ ERROR allow(deprecated) incompatible with previous forbid [E0453] +//~^^ NOTE overruled by previous forbid fn main() { } diff --git a/tests/ui/lint/lint-forbid-cmdline-1.rs b/tests/ui/lint/lint-forbid-cmdline-1.rs new file mode 100644 index 000000000000..19a8f825f57d --- /dev/null +++ b/tests/ui/lint/lint-forbid-cmdline-1.rs @@ -0,0 +1,5 @@ +//@ compile-flags: -F deprecated + +#[allow(deprecated)] //~ ERROR allow(deprecated) incompatible with previous forbid [E0453] +fn main() { +} diff --git a/tests/ui/lint/lint-forbid-cmdline-1.stderr b/tests/ui/lint/lint-forbid-cmdline-1.stderr new file mode 100644 index 000000000000..7f4893fabd97 --- /dev/null +++ b/tests/ui/lint/lint-forbid-cmdline-1.stderr @@ -0,0 +1,11 @@ +error[E0453]: allow(deprecated) incompatible with previous forbid + --> $DIR/lint-forbid-cmdline-1.rs:3:9 + | +LL | #[allow(deprecated)] + | ^^^^^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line (`-F deprecated`) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/lint/lint-forbid-cmdline-2.rs b/tests/ui/lint/lint-forbid-cmdline-2.rs new file mode 100644 index 000000000000..3505c11f4201 --- /dev/null +++ b/tests/ui/lint/lint-forbid-cmdline-2.rs @@ -0,0 +1,8 @@ +//@ compile-flags: -F dead_code + +#[allow(unused)] +//~^ ERROR allow(unused) incompatible with previous forbid [E0453] +//~| NOTE overruled by previous forbid +//~| NOTE `forbid` lint level was set on command line (`-F dead_code`) +fn main() { +} diff --git a/tests/ui/lint/lint-forbid-cmdline-2.stderr b/tests/ui/lint/lint-forbid-cmdline-2.stderr new file mode 100644 index 000000000000..18a60b2f8b7e --- /dev/null +++ b/tests/ui/lint/lint-forbid-cmdline-2.stderr @@ -0,0 +1,11 @@ +error[E0453]: allow(unused) incompatible with previous forbid + --> $DIR/lint-forbid-cmdline-2.rs:3:9 + | +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = note: `forbid` lint level was set on command line (`-F dead_code`) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/lint/lint-forbid-cmdline.rs b/tests/ui/lint/lint-forbid-cmdline.rs deleted file mode 100644 index 8a4eb449d3c8..000000000000 --- a/tests/ui/lint/lint-forbid-cmdline.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ compile-flags: -F deprecated - -#[allow(deprecated)] //~ ERROR allow(deprecated) incompatible -fn main() { -} diff --git a/tests/ui/lint/lint-forbid-cmdline.stderr b/tests/ui/lint/lint-forbid-cmdline.stderr deleted file mode 100644 index 3920a7429763..000000000000 --- a/tests/ui/lint/lint-forbid-cmdline.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0453]: allow(deprecated) incompatible with previous forbid - --> $DIR/lint-forbid-cmdline.rs:3:9 - | -LL | #[allow(deprecated)] - | ^^^^^^^^^^ overruled by previous forbid - | - = note: `forbid` lint level was set on command line - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0453`. diff --git a/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr b/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr new file mode 100644 index 000000000000..21eebe42f8b1 --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.amdgpu.stderr @@ -0,0 +1,86 @@ +warning: `extern` fn uses type `()`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + = note: `#[warn(improper_ctypes_definitions)]` on by default + +warning: passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ + | + = help: use primitive types and raw pointers to get reliable behavior + = note: `#[warn(improper_gpu_kernel_arg)]` on by default + +warning: passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:41:35 + | +LL | extern "gpu-kernel" fn arg_ref(_: &i32) { } + | ^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:44:39 + | +LL | extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } + | ^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `S`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-gpu-kernel.rs:47:1 + | +LL | struct S { a: i32, b: i32 } + | ^^^^^^^^ + +warning: passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `(i32, i32)`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + +warning: passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: function with the "gpu-kernel" ABI has a mangled name + --> $DIR/lint-gpu-kernel.rs:61:1 + | +LL | pub extern "gpu-kernel" fn mangled_kernel() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + = note: mangled names make it hard to find the kernel, this is usually not intended + = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + +warning: 9 warnings emitted + diff --git a/tests/ui/lint/lint-gpu-kernel.nvptx.stderr b/tests/ui/lint/lint-gpu-kernel.nvptx.stderr new file mode 100644 index 000000000000..21eebe42f8b1 --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.nvptx.stderr @@ -0,0 +1,86 @@ +warning: `extern` fn uses type `()`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + = note: `#[warn(improper_ctypes_definitions)]` on by default + +warning: passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:36:35 + | +LL | extern "gpu-kernel" fn arg_zst(_: ()) { } + | ^^ + | + = help: use primitive types and raw pointers to get reliable behavior + = note: `#[warn(improper_gpu_kernel_arg)]` on by default + +warning: passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:41:35 + | +LL | extern "gpu-kernel" fn arg_ref(_: &i32) { } + | ^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:44:39 + | +LL | extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } + | ^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `S`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/lint-gpu-kernel.rs:47:1 + | +LL | struct S { a: i32, b: i32 } + | ^^^^^^^^ + +warning: passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:49:38 + | +LL | extern "gpu-kernel" fn arg_struct(_: S) { } + | ^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: `extern` fn uses type `(i32, i32)`, which is not FFI-safe + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ not FFI-safe + | + = help: consider using a struct instead + = note: tuples have unspecified layout + +warning: passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior + --> $DIR/lint-gpu-kernel.rs:54:35 + | +LL | extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } + | ^^^^^^^^^^ + | + = help: use primitive types and raw pointers to get reliable behavior + +warning: function with the "gpu-kernel" ABI has a mangled name + --> $DIR/lint-gpu-kernel.rs:61:1 + | +LL | pub extern "gpu-kernel" fn mangled_kernel() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: use `unsafe(no_mangle)` or `unsafe(export_name = "")` + = note: mangled names make it hard to find the kernel, this is usually not intended + = note: `#[warn(missing_gpu_kernel_export_name)]` on by default + +warning: 9 warnings emitted + diff --git a/tests/ui/lint/lint-gpu-kernel.rs b/tests/ui/lint/lint-gpu-kernel.rs new file mode 100644 index 000000000000..9b3ed0d14d8a --- /dev/null +++ b/tests/ui/lint/lint-gpu-kernel.rs @@ -0,0 +1,62 @@ +// Test argument and return type restrictions of the gpu-kernel ABI and +// check for warnings on mangled gpu-kernels. + +//@ check-pass +//@ ignore-backends: gcc +//@ revisions: amdgpu nvptx +//@ add-minicore +//@ edition: 2024 +//@[amdgpu] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900 +//@[amdgpu] needs-llvm-components: amdgpu +//@[nvptx] compile-flags: --target nvptx64-nvidia-cuda +//@[nvptx] needs-llvm-components: nvptx + +#![feature(no_core, abi_gpu_kernel)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +// Return types can be () or ! +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_empty() {} +#[unsafe(no_mangle)] +extern "gpu-kernel" fn ret_never() -> ! { loop {} } + +// Arguments can be scalars or pointers +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_i32(_: i32) { } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ptr(_: *const i32) { } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ptr_mut(_: *mut i32) { } + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_zst(_: ()) { } +//~^ WARN passing type `()` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `()`, which is not FFI-safe + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ref(_: &i32) { } +//~^ WARN passing type `&i32` to a function with "gpu-kernel" ABI may have unexpected behavior +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_ref_mut(_: &mut i32) { } +//~^ WARN passing type `&mut i32` to a function with "gpu-kernel" ABI may have unexpected behavior + +struct S { a: i32, b: i32 } +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_struct(_: S) { } +//~^ WARN passing type `S` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `S`, which is not FFI-safe + +#[unsafe(no_mangle)] +extern "gpu-kernel" fn arg_tup(_: (i32, i32)) { } +//~^ WARN passing type `(i32, i32)` to a function with "gpu-kernel" ABI may have unexpected behavior +//~^^ WARN `extern` fn uses type `(i32, i32)`, which is not FFI-safe + +#[unsafe(export_name = "kernel")] +pub extern "gpu-kernel" fn allowed_kernel_name() {} + +pub extern "gpu-kernel" fn mangled_kernel() { } +//~^ WARN function with the "gpu-kernel" ABI has a mangled name diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-update.rs b/tests/ui/lint/lint-invalid-atomic-ordering-update.rs index ac41e7cee0c2..0cb87d4eab1b 100644 --- a/tests/ui/lint/lint-invalid-atomic-ordering-update.rs +++ b/tests/ui/lint/lint-invalid-atomic-ordering-update.rs @@ -1,6 +1,4 @@ //@ only-x86_64 -#![feature(atomic_try_update)] - use std::sync::atomic::{AtomicIsize, Ordering}; fn main() { diff --git a/tests/ui/lint/lint-invalid-atomic-ordering-update.stderr b/tests/ui/lint/lint-invalid-atomic-ordering-update.stderr index 8c266bacf314..5a5efbd85b0a 100644 --- a/tests/ui/lint/lint-invalid-atomic-ordering-update.stderr +++ b/tests/ui/lint/lint-invalid-atomic-ordering-update.stderr @@ -1,5 +1,5 @@ error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:73:47 + --> $DIR/lint-invalid-atomic-ordering-update.rs:71:47 | LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -8,7 +8,7 @@ LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some( = note: `#[deny(invalid_atomic_ordering)]` on by default error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:75:45 + --> $DIR/lint-invalid-atomic-ordering-update.rs:73:45 | LL | let _ = x.try_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -16,7 +16,7 @@ LL | let _ = x.try_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(ol = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:77:41 + --> $DIR/lint-invalid-atomic-ordering-update.rs:75:41 | LL | let _ = x.update(Ordering::Relaxed, Ordering::AcqRel, |old| old + 1); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -24,7 +24,7 @@ LL | let _ = x.update(Ordering::Relaxed, Ordering::AcqRel, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:80:47 + --> $DIR/lint-invalid-atomic-ordering-update.rs:78:47 | LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -32,7 +32,7 @@ LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::AcqRel, |old| Some( = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:82:45 + --> $DIR/lint-invalid-atomic-ordering-update.rs:80:45 | LL | let _ = x.try_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -40,7 +40,7 @@ LL | let _ = x.try_update(Ordering::Acquire, Ordering::AcqRel, |old| Some(ol = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:84:41 + --> $DIR/lint-invalid-atomic-ordering-update.rs:82:41 | LL | let _ = x.update(Ordering::Acquire, Ordering::AcqRel, |old| old + 1); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -48,7 +48,7 @@ LL | let _ = x.update(Ordering::Acquire, Ordering::AcqRel, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:87:47 + --> $DIR/lint-invalid-atomic-ordering-update.rs:85:47 | LL | let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -56,7 +56,7 @@ LL | let _ = x.fetch_update(Ordering::Release, Ordering::AcqRel, |old| Some( = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:89:45 + --> $DIR/lint-invalid-atomic-ordering-update.rs:87:45 | LL | let _ = x.try_update(Ordering::Release, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -64,7 +64,7 @@ LL | let _ = x.try_update(Ordering::Release, Ordering::AcqRel, |old| Some(ol = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:91:41 + --> $DIR/lint-invalid-atomic-ordering-update.rs:89:41 | LL | let _ = x.update(Ordering::Release, Ordering::AcqRel, |old| old + 1); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -72,7 +72,7 @@ LL | let _ = x.update(Ordering::Release, Ordering::AcqRel, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:94:46 + --> $DIR/lint-invalid-atomic-ordering-update.rs:92:46 | LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -80,7 +80,7 @@ LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(o = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:96:44 + --> $DIR/lint-invalid-atomic-ordering-update.rs:94:44 | LL | let _ = x.try_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -88,7 +88,7 @@ LL | let _ = x.try_update(Ordering::AcqRel, Ordering::AcqRel, |old| Some(old = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:98:40 + --> $DIR/lint-invalid-atomic-ordering-update.rs:96:40 | LL | let _ = x.update(Ordering::AcqRel, Ordering::AcqRel, |old| old + 1); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -96,7 +96,7 @@ LL | let _ = x.update(Ordering::AcqRel, Ordering::AcqRel, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:101:46 + --> $DIR/lint-invalid-atomic-ordering-update.rs:99:46 | LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -104,7 +104,7 @@ LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(o = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:103:44 + --> $DIR/lint-invalid-atomic-ordering-update.rs:101:44 | LL | let _ = x.try_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -112,7 +112,7 @@ LL | let _ = x.try_update(Ordering::SeqCst, Ordering::AcqRel, |old| Some(old = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:105:40 + --> $DIR/lint-invalid-atomic-ordering-update.rs:103:40 | LL | let _ = x.update(Ordering::SeqCst, Ordering::AcqRel, |old| old + 1); | ^^^^^^^^^^^^^^^^ invalid failure ordering @@ -120,7 +120,7 @@ LL | let _ = x.update(Ordering::SeqCst, Ordering::AcqRel, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:110:47 + --> $DIR/lint-invalid-atomic-ordering-update.rs:108:47 | LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -128,7 +128,7 @@ LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::Release, |old| Some = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:112:45 + --> $DIR/lint-invalid-atomic-ordering-update.rs:110:45 | LL | let _ = x.try_update(Ordering::Relaxed, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -136,7 +136,7 @@ LL | let _ = x.try_update(Ordering::Relaxed, Ordering::Release, |old| Some(o = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:114:41 + --> $DIR/lint-invalid-atomic-ordering-update.rs:112:41 | LL | let _ = x.update(Ordering::Relaxed, Ordering::Release, |old| old + 1); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -144,7 +144,7 @@ LL | let _ = x.update(Ordering::Relaxed, Ordering::Release, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:117:47 + --> $DIR/lint-invalid-atomic-ordering-update.rs:115:47 | LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -152,7 +152,7 @@ LL | let _ = x.fetch_update(Ordering::Acquire, Ordering::Release, |old| Some = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:119:45 + --> $DIR/lint-invalid-atomic-ordering-update.rs:117:45 | LL | let _ = x.try_update(Ordering::Acquire, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -160,7 +160,7 @@ LL | let _ = x.try_update(Ordering::Acquire, Ordering::Release, |old| Some(o = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:121:41 + --> $DIR/lint-invalid-atomic-ordering-update.rs:119:41 | LL | let _ = x.update(Ordering::Acquire, Ordering::Release, |old| old + 1); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -168,7 +168,7 @@ LL | let _ = x.update(Ordering::Acquire, Ordering::Release, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:124:47 + --> $DIR/lint-invalid-atomic-ordering-update.rs:122:47 | LL | let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -176,7 +176,7 @@ LL | let _ = x.fetch_update(Ordering::Release, Ordering::Release, |old| Some = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:126:45 + --> $DIR/lint-invalid-atomic-ordering-update.rs:124:45 | LL | let _ = x.try_update(Ordering::Release, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -184,7 +184,7 @@ LL | let _ = x.try_update(Ordering::Release, Ordering::Release, |old| Some(o = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:128:41 + --> $DIR/lint-invalid-atomic-ordering-update.rs:126:41 | LL | let _ = x.update(Ordering::Release, Ordering::Release, |old| old + 1); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -192,7 +192,7 @@ LL | let _ = x.update(Ordering::Release, Ordering::Release, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:131:46 + --> $DIR/lint-invalid-atomic-ordering-update.rs:129:46 | LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -200,7 +200,7 @@ LL | let _ = x.fetch_update(Ordering::AcqRel, Ordering::Release, |old| Some( = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:133:44 + --> $DIR/lint-invalid-atomic-ordering-update.rs:131:44 | LL | let _ = x.try_update(Ordering::AcqRel, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -208,7 +208,7 @@ LL | let _ = x.try_update(Ordering::AcqRel, Ordering::Release, |old| Some(ol = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:135:40 + --> $DIR/lint-invalid-atomic-ordering-update.rs:133:40 | LL | let _ = x.update(Ordering::AcqRel, Ordering::Release, |old| old + 1); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -216,7 +216,7 @@ LL | let _ = x.update(Ordering::AcqRel, Ordering::Release, |old| old + 1); = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:138:46 + --> $DIR/lint-invalid-atomic-ordering-update.rs:136:46 | LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -224,7 +224,7 @@ LL | let _ = x.fetch_update(Ordering::SeqCst, Ordering::Release, |old| Some( = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `try_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `try_update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:140:44 + --> $DIR/lint-invalid-atomic-ordering-update.rs:138:44 | LL | let _ = x.try_update(Ordering::SeqCst, Ordering::Release, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^^ invalid failure ordering @@ -232,7 +232,7 @@ LL | let _ = x.try_update(Ordering::SeqCst, Ordering::Release, |old| Some(ol = help: consider using `Acquire` or `Relaxed` failure ordering instead error: `update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `update` does not result in a write - --> $DIR/lint-invalid-atomic-ordering-update.rs:142:40 + --> $DIR/lint-invalid-atomic-ordering-update.rs:140:40 | LL | let _ = x.update(Ordering::SeqCst, Ordering::Release, |old| old + 1); | ^^^^^^^^^^^^^^^^^ invalid failure ordering diff --git a/tests/ui/lint/lint-misplaced-attr.rs b/tests/ui/lint/lint-misplaced-attr.rs index d06917ea3f8a..557dbe294943 100644 --- a/tests/ui/lint/lint-misplaced-attr.rs +++ b/tests/ui/lint/lint-misplaced-attr.rs @@ -4,7 +4,7 @@ #![deny(unused_attributes)] mod a { - #![crate_type = "bin"] //~ ERROR should be in the root module + #![crate_type = "bin"] //~ ERROR the `#![crate_type]` attribute can only be used at the crate root } #[crate_type = "bin"] fn main() {} //~ ERROR should be an inner diff --git a/tests/ui/lint/lint-misplaced-attr.stderr b/tests/ui/lint/lint-misplaced-attr.stderr index bcfda1700800..d46bbc44c1b2 100644 --- a/tests/ui/lint/lint-misplaced-attr.stderr +++ b/tests/ui/lint/lint-misplaced-attr.stderr @@ -1,4 +1,4 @@ -error: crate-level attribute should be in the root module +error: the `#![crate_type]` attribute can only be used at the crate root --> $DIR/lint-misplaced-attr.rs:7:5 | LL | #![crate_type = "bin"] @@ -10,16 +10,17 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: crate-level attribute should be an inner attribute +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` --> $DIR/lint-misplaced-attr.rs:10:1 | LL | #[crate_type = "bin"] fn main() {} | ^^^^^^^^^^^^^^^^^^^^^ | -help: add a `!` +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/lint-misplaced-attr.rs:10:23 | -LL | #![crate_type = "bin"] fn main() {} - | + +LL | #[crate_type = "bin"] fn main() {} + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/lint/lint-missing-doc-crate-attr.rs b/tests/ui/lint/lint-missing-doc-crate-attr.rs new file mode 100644 index 000000000000..51959785c53b --- /dev/null +++ b/tests/ui/lint/lint-missing-doc-crate-attr.rs @@ -0,0 +1,4 @@ +// regression test for https://github.com/rust-lang/rust/issues/10656 +#![deny(missing_docs)] +//~^ ERROR missing documentation for the crate +#![crate_type = "lib"] diff --git a/tests/ui/lint/lint-missing-doc-crate-attr.stderr b/tests/ui/lint/lint-missing-doc-crate-attr.stderr new file mode 100644 index 000000000000..caff87df664b --- /dev/null +++ b/tests/ui/lint/lint-missing-doc-crate-attr.stderr @@ -0,0 +1,16 @@ +error: missing documentation for the crate + --> $DIR/lint-missing-doc-crate-attr.rs:2:1 + | +LL | / #![deny(missing_docs)] +LL | | +LL | | #![crate_type = "lib"] + | |______________________^ + | +note: the lint level is defined here + --> $DIR/lint-missing-doc-crate-attr.rs:2:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/lint-missing-doc-crate.rs b/tests/ui/lint/lint-missing-doc-crate-flags.rs similarity index 100% rename from tests/ui/lint/lint-missing-doc-crate.rs rename to tests/ui/lint/lint-missing-doc-crate-flags.rs diff --git a/tests/ui/lint/lint-missing-doc-crate-flags.stderr b/tests/ui/lint/lint-missing-doc-crate-flags.stderr new file mode 100644 index 000000000000..040d60a56ebf --- /dev/null +++ b/tests/ui/lint/lint-missing-doc-crate-flags.stderr @@ -0,0 +1,10 @@ +error: missing documentation for the crate + --> $DIR/lint-missing-doc-crate-flags.rs:4:47 + | +LL | + | ^ + | + = note: requested on the command line with `-D missing-docs` + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/lint-missing-doc-crate.stderr b/tests/ui/lint/lint-missing-doc-crate.stderr deleted file mode 100644 index 8efd3a17263f..000000000000 --- a/tests/ui/lint/lint-missing-doc-crate.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: missing documentation for the crate - --> $DIR/lint-missing-doc-crate.rs:4:47 - | -LL | - | ^ - | - = note: requested on the command line with `-D missing-docs` - -error: aborting due to 1 previous error - diff --git a/tests/ui/lint/lint-pre-expansion-extern-module.stderr b/tests/ui/lint/lint-pre-expansion-extern-module.stderr index 32c76da98b52..1de1784fc9c5 100644 --- a/tests/ui/lint/lint-pre-expansion-extern-module.stderr +++ b/tests/ui/lint/lint-pre-expansion-extern-module.stderr @@ -5,7 +5,7 @@ LL | pub fn try() {} | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see = note: `-W keyword-idents-2018` implied by `-W rust-2018-compatibility` = help: to override `-W rust-2018-compatibility` add `#[allow(keyword_idents_2018)]` diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr index bda4ee82d1fc..ce0bc36f6292 100644 --- a/tests/ui/lint/lint-stability-deprecated.stderr +++ b/tests/ui/lint/lint-stability-deprecated.stderr @@ -1,8 +1,8 @@ -warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text - --> $DIR/lint-stability-deprecated.rs:97:48 +warning: use of deprecated function `lint_stability::deprecated`: text + --> $DIR/lint-stability-deprecated.rs:24:9 | -LL | struct S2(T::TypeDeprecated); - | ^^^^^^^^^^^^^^^^^ +LL | deprecated(); + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/lint-stability-deprecated.rs:6:9 @@ -10,12 +10,6 @@ note: the lint level is defined here LL | #![warn(deprecated)] | ^^^^^^^^^^ -warning: use of deprecated function `lint_stability::deprecated`: text - --> $DIR/lint-stability-deprecated.rs:24:9 - | -LL | deprecated(); - | ^^^^^^^^^^ - warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:29:16 | @@ -322,6 +316,12 @@ warning: use of deprecated function `this_crate::MethodTester::test_method_body: LL | fn_in_body(); | ^^^^^^^^^^ +warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text + --> $DIR/lint-stability-deprecated.rs:97:48 + | +LL | struct S2(T::TypeDeprecated); + | ^^^^^^^^^^^^^^^^^ + warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text --> $DIR/lint-stability-deprecated.rs:101:13 | diff --git a/tests/ui/lint/lint-stability.stderr b/tests/ui/lint/lint-stability.stderr index 249f3ccaa542..fd57908a77b5 100644 --- a/tests/ui/lint/lint-stability.stderr +++ b/tests/ui/lint/lint-stability.stderr @@ -1,12 +1,3 @@ -error[E0658]: use of unstable library feature `unstable_test_feature` - --> $DIR/lint-stability.rs:88:48 - | -LL | struct S1(T::TypeUnstable); - | ^^^^^^^^^^^^^^^ - | - = help: add `#![feature(unstable_test_feature)]` 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[E0658]: use of unstable library feature `unstable_test_feature` --> $DIR/lint-stability.rs:17:5 | @@ -376,6 +367,15 @@ LL | let _ = Unstable::StableVariant; = help: add `#![feature(unstable_test_feature)]` 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[E0658]: use of unstable library feature `unstable_test_feature` + --> $DIR/lint-stability.rs:88:48 + | +LL | struct S1(T::TypeUnstable); + | ^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` 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[E0658]: use of unstable library feature `unstable_test_feature` --> $DIR/lint-stability.rs:92:13 | diff --git a/tests/ui/lint/lint-type-overflow2.rs b/tests/ui/lint/lint-type-overflow2.rs index ac7420326c89..d3ff02aeb722 100644 --- a/tests/ui/lint/lint-type-overflow2.rs +++ b/tests/ui/lint/lint-type-overflow2.rs @@ -1,13 +1,19 @@ //@ compile-flags: -O +#![feature(f16)] +#![feature(f128)] #![deny(overflowing_literals)] fn main() { let x2: i8 = --128; //~ ERROR literal out of range for `i8` //~| WARN use of a double negation + let x = -65520.0_f16; //~ ERROR literal out of range for `f16` + let x = 65520.0_f16; //~ ERROR literal out of range for `f16` let x = -3.40282357e+38_f32; //~ ERROR literal out of range for `f32` let x = 3.40282357e+38_f32; //~ ERROR literal out of range for `f32` let x = -1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64` let x = 1.7976931348623159e+308_f64; //~ ERROR literal out of range for `f64` + let x = -1.1897314953572317650857593266280075e+4932_f128; //~ ERROR literal out of range for `f128` + let x = 1.1897314953572317650857593266280075e+4932_f128; //~ ERROR literal out of range for `f128` } diff --git a/tests/ui/lint/lint-type-overflow2.stderr b/tests/ui/lint/lint-type-overflow2.stderr index 2cfb18e9fe92..c045d243753e 100644 --- a/tests/ui/lint/lint-type-overflow2.stderr +++ b/tests/ui/lint/lint-type-overflow2.stderr @@ -1,5 +1,5 @@ warning: use of a double negation - --> $DIR/lint-type-overflow2.rs:6:18 + --> $DIR/lint-type-overflow2.rs:8:18 | LL | let x2: i8 = --128; | ^^^^^ @@ -13,7 +13,7 @@ LL | let x2: i8 = -(-128); | + + error: literal out of range for `i8` - --> $DIR/lint-type-overflow2.rs:6:20 + --> $DIR/lint-type-overflow2.rs:8:20 | LL | let x2: i8 = --128; | ^^^ @@ -21,13 +21,29 @@ LL | let x2: i8 = --128; = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` = help: consider using the type `u8` instead note: the lint level is defined here - --> $DIR/lint-type-overflow2.rs:3:9 + --> $DIR/lint-type-overflow2.rs:5:9 | LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ +error: literal out of range for `f16` + --> $DIR/lint-type-overflow2.rs:11:14 + | +LL | let x = -65520.0_f16; + | ^^^^^^^^^^^ + | + = note: the literal `65520.0_f16` does not fit into the type `f16` and will be converted to `f16::INFINITY` + +error: literal out of range for `f16` + --> $DIR/lint-type-overflow2.rs:12:14 + | +LL | let x = 65520.0_f16; + | ^^^^^^^^^^^ + | + = note: the literal `65520.0_f16` does not fit into the type `f16` and will be converted to `f16::INFINITY` + error: literal out of range for `f32` - --> $DIR/lint-type-overflow2.rs:9:14 + --> $DIR/lint-type-overflow2.rs:13:14 | LL | let x = -3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ @@ -35,7 +51,7 @@ LL | let x = -3.40282357e+38_f32; = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY` error: literal out of range for `f32` - --> $DIR/lint-type-overflow2.rs:10:14 + --> $DIR/lint-type-overflow2.rs:14:14 | LL | let x = 3.40282357e+38_f32; | ^^^^^^^^^^^^^^^^^^ @@ -43,7 +59,7 @@ LL | let x = 3.40282357e+38_f32; = note: the literal `3.40282357e+38_f32` does not fit into the type `f32` and will be converted to `f32::INFINITY` error: literal out of range for `f64` - --> $DIR/lint-type-overflow2.rs:11:14 + --> $DIR/lint-type-overflow2.rs:15:14 | LL | let x = -1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,12 +67,28 @@ LL | let x = -1.7976931348623159e+308_f64; = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY` error: literal out of range for `f64` - --> $DIR/lint-type-overflow2.rs:12:14 + --> $DIR/lint-type-overflow2.rs:16:14 | LL | let x = 1.7976931348623159e+308_f64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `1.7976931348623159e+308_f64` does not fit into the type `f64` and will be converted to `f64::INFINITY` -error: aborting due to 5 previous errors; 1 warning emitted +error: literal out of range for `f128` + --> $DIR/lint-type-overflow2.rs:17:14 + | +LL | let x = -1.1897314953572317650857593266280075e+4932_f128; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `1.1897314953572317650857593266280075e+4932_f128` does not fit into the type `f128` and will be converted to `f128::INFINITY` + +error: literal out of range for `f128` + --> $DIR/lint-type-overflow2.rs:18:14 + | +LL | let x = 1.1897314953572317650857593266280075e+4932_f128; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the literal `1.1897314953572317650857593266280075e+4932_f128` does not fit into the type `f128` and will be converted to `f128::INFINITY` + +error: aborting due to 9 previous errors; 1 warning emitted diff --git a/tests/ui/lint/must_not_suspend/other_items.rs b/tests/ui/lint/must_not_suspend/other_items.rs index 7a42a2bba03b..1c46cce7ed3a 100644 --- a/tests/ui/lint/must_not_suspend/other_items.rs +++ b/tests/ui/lint/must_not_suspend/other_items.rs @@ -2,7 +2,7 @@ #![feature(must_not_suspend)] #![deny(must_not_suspend)] -#[must_not_suspend] //~ ERROR attribute should be +#[must_not_suspend] //~ ERROR attribute cannot be used on modules mod inner {} fn main() {} diff --git a/tests/ui/lint/must_not_suspend/other_items.stderr b/tests/ui/lint/must_not_suspend/other_items.stderr index dff5210b7e47..289230b027ad 100644 --- a/tests/ui/lint/must_not_suspend/other_items.stderr +++ b/tests/ui/lint/must_not_suspend/other_items.stderr @@ -1,10 +1,10 @@ -error: `must_not_suspend` attribute should be applied to a struct, enum, union, or trait +error: `#[must_not_suspend]` attribute cannot be used on modules --> $DIR/other_items.rs:5:1 | LL | #[must_not_suspend] | ^^^^^^^^^^^^^^^^^^^ -LL | mod inner {} - | ------------ is not a struct, enum, union, or trait + | + = help: `#[must_not_suspend]` can be applied to data types and traits error: aborting due to 1 previous error diff --git a/tests/ui/lint/must_not_suspend/return.rs b/tests/ui/lint/must_not_suspend/return.rs index a04f6a4cfb43..de78ee0f9299 100644 --- a/tests/ui/lint/must_not_suspend/return.rs +++ b/tests/ui/lint/must_not_suspend/return.rs @@ -2,7 +2,7 @@ #![feature(must_not_suspend)] #![deny(must_not_suspend)] -#[must_not_suspend] //~ ERROR attribute should be +#[must_not_suspend] //~ ERROR attribute cannot be used on functions fn foo() -> i32 { 0 } diff --git a/tests/ui/lint/must_not_suspend/return.stderr b/tests/ui/lint/must_not_suspend/return.stderr index 440f81656862..b041491128e1 100644 --- a/tests/ui/lint/must_not_suspend/return.stderr +++ b/tests/ui/lint/must_not_suspend/return.stderr @@ -1,12 +1,10 @@ -error: `must_not_suspend` attribute should be applied to a struct, enum, union, or trait +error: `#[must_not_suspend]` attribute cannot be used on functions --> $DIR/return.rs:5:1 | -LL | #[must_not_suspend] - | ^^^^^^^^^^^^^^^^^^^ -LL | / fn foo() -> i32 { -LL | | 0 -LL | | } - | |_- is not a struct, enum, union, or trait +LL | #[must_not_suspend] + | ^^^^^^^^^^^^^^^^^^^ + | + = help: `#[must_not_suspend]` can be applied to data types and traits error: aborting due to 1 previous error diff --git a/tests/ui/lint/outer-forbid.stderr b/tests/ui/lint/outer-forbid.stderr index 64a1077462ab..7810ca223f8a 100644 --- a/tests/ui/lint/outer-forbid.stderr +++ b/tests/ui/lint/outer-forbid.stderr @@ -453,3 +453,21 @@ note: the lint level is defined here LL | #![forbid(forbidden_lint_groups)] | ^^^^^^^^^^^^^^^^^^^^^ +Future breakage diagnostic: +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:25:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/lint/recommend-literal.rs b/tests/ui/lint/recommend-literal.rs index 45f9ae0a7bdf..be074c111453 100644 --- a/tests/ui/lint/recommend-literal.rs +++ b/tests/ui/lint/recommend-literal.rs @@ -1,3 +1,5 @@ +//~vv HELP consider importing this struct + type Real = double; //~^ ERROR cannot find type `double` in this scope //~| HELP perhaps you intended to use this type diff --git a/tests/ui/lint/recommend-literal.stderr b/tests/ui/lint/recommend-literal.stderr index 6b6dd134e1d2..01e993df17a9 100644 --- a/tests/ui/lint/recommend-literal.stderr +++ b/tests/ui/lint/recommend-literal.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `double` in this scope - --> $DIR/recommend-literal.rs:1:13 + --> $DIR/recommend-literal.rs:3:13 | LL | type Real = double; | ^^^^^^ @@ -8,7 +8,7 @@ LL | type Real = double; | help: perhaps you intended to use this type: `f64` error[E0425]: cannot find type `long` in this scope - --> $DIR/recommend-literal.rs:7:12 + --> $DIR/recommend-literal.rs:9:12 | LL | let y: long = 74802374902374923; | ^^^^ @@ -17,7 +17,7 @@ LL | let y: long = 74802374902374923; | help: perhaps you intended to use this type: `i64` error[E0425]: cannot find type `Boolean` in this scope - --> $DIR/recommend-literal.rs:10:13 + --> $DIR/recommend-literal.rs:12:13 | LL | let v1: Boolean = true; | ^^^^^^^ @@ -26,7 +26,7 @@ LL | let v1: Boolean = true; | help: perhaps you intended to use this type: `bool` error[E0425]: cannot find type `Bool` in this scope - --> $DIR/recommend-literal.rs:13:13 + --> $DIR/recommend-literal.rs:15:13 | LL | let v2: Bool = true; | ^^^^ @@ -41,9 +41,13 @@ help: perhaps you intended to use this type LL - let v2: Bool = true; LL + let v2: bool = true; | +help: consider importing this struct + | +LL + use std::mem::type_info::Bool; + | error[E0425]: cannot find type `boolean` in this scope - --> $DIR/recommend-literal.rs:19:9 + --> $DIR/recommend-literal.rs:21:9 | LL | fn z(a: boolean) { | ^^^^^^^ @@ -52,7 +56,7 @@ LL | fn z(a: boolean) { | help: perhaps you intended to use this type: `bool` error[E0425]: cannot find type `byte` in this scope - --> $DIR/recommend-literal.rs:24:11 + --> $DIR/recommend-literal.rs:26:11 | LL | fn a() -> byte { | ^^^^ @@ -61,7 +65,7 @@ LL | fn a() -> byte { | help: perhaps you intended to use this type: `u8` error[E0425]: cannot find type `float` in this scope - --> $DIR/recommend-literal.rs:31:12 + --> $DIR/recommend-literal.rs:33:12 | LL | width: float, | ^^^^^ @@ -70,7 +74,7 @@ LL | width: float, | help: perhaps you intended to use this type: `f32` error[E0425]: cannot find type `int` in this scope - --> $DIR/recommend-literal.rs:34:19 + --> $DIR/recommend-literal.rs:36:19 | LL | depth: Option, | ^^^ not found in this scope @@ -86,7 +90,7 @@ LL | struct Data { | +++++ error[E0425]: cannot find type `short` in this scope - --> $DIR/recommend-literal.rs:40:16 + --> $DIR/recommend-literal.rs:42:16 | LL | impl Stuff for short {} | ^^^^^ diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-2.rs b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-2.rs new file mode 100644 index 000000000000..43ee6bf26a69 --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-2.rs @@ -0,0 +1,14 @@ +// Make sure that the copied `#[expect]` attr in the derived code does not trigger an unfulfilled +// expectation as it's linked to the original one which is fulfilled. +// +// See for rational. + +//@ check-pass + +#[expect(non_camel_case_types)] +#[derive(Debug)] +pub struct SCREAMING_CASE { + pub t_ref: i64, +} + +fn main() {} diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.rs b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.rs new file mode 100644 index 000000000000..904366e6532e --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.rs @@ -0,0 +1,14 @@ +// Make sure we produce the unfulfilled expectation lint if neither the struct or the +// derived code fulfilled it. + +//@ check-pass + +#[expect(unexpected_cfgs)] +//~^ WARN this lint expectation is unfulfilled +//~^^ WARN this lint expectation is unfulfilled +#[derive(Debug)] +pub struct MyStruct { + pub t_ref: i64, +} + +fn main() {} diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.stderr b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.stderr new file mode 100644 index 000000000000..6478ec435db0 --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553-3.stderr @@ -0,0 +1,18 @@ +warning: this lint expectation is unfulfilled + --> $DIR/derive-expect-issue-150553-3.rs:6:10 + | +LL | #[expect(unexpected_cfgs)] + | ^^^^^^^^^^^^^^^ + | + = note: `#[warn(unfulfilled_lint_expectations)]` on by default + +warning: this lint expectation is unfulfilled + --> $DIR/derive-expect-issue-150553-3.rs:6:10 + | +LL | #[expect(unexpected_cfgs)] + | ^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: 2 warnings emitted + diff --git a/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553.rs b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553.rs new file mode 100644 index 000000000000..1752835c8bb8 --- /dev/null +++ b/tests/ui/lint/rfc-2383-lint-reason/derive-expect-issue-150553.rs @@ -0,0 +1,22 @@ +// Make sure we properly copy the `#[expect]` attr to the derived code and that no +// unfulfilled expectations are trigerred. +// +// See for rational. + +//@ check-pass + +#![deny(redundant_lifetimes)] + +use std::fmt::Debug; + +#[derive(Debug)] +#[expect(redundant_lifetimes)] +pub struct RefWrapper<'a, T> +where + 'a: 'static, + T: Debug, +{ + pub t_ref: &'a T, +} + +fn main() {} diff --git a/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout index 80abac44ca84..0fcfc936a59b 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout +++ b/tests/ui/lint/rfc-2383-lint-reason/no_ice_for_partial_compiler_runs.stdout @@ -1,6 +1,5 @@ #![feature(prelude_import)] #![no_std] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/lint/unused-parens-labeled-break-issue-143256.rs b/tests/ui/lint/unused-parens-labeled-break-issue-143256.rs new file mode 100644 index 000000000000..8594e646f605 --- /dev/null +++ b/tests/ui/lint/unused-parens-labeled-break-issue-143256.rs @@ -0,0 +1,25 @@ +//@ check-pass +// testcase for https://github.com/rust-lang/rust/issues/143256 + +#![deny(unused_parens)] +#![allow(unreachable_code, unused_variables, dead_code)] + +fn foo() { + let _x = || 'outer: loop { + let inner = 'inner: loop { + let i = Default::default(); + // the parentheses here are necessary + if (break 'outer i) { + loop { + break 'inner 5i8; + } + } else if true { + break 'inner 6; + } + break 7; + }; + break inner < 8; + }; +} + +fn main() {} diff --git a/tests/ui/lint/unused-visibilities.fixed b/tests/ui/lint/unused-visibilities.fixed new file mode 100644 index 000000000000..97c1a5c73249 --- /dev/null +++ b/tests/ui/lint/unused-visibilities.fixed @@ -0,0 +1,29 @@ +//@ check-pass +//@ run-rustfix + +#![warn(unused_visibilities)] + + const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + + const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + +macro_rules! foo { + () => { + const _: () = {}; + //~^WARN visibility qualifiers have no effect on `const _` declarations + }; +} + +foo!(); + +macro_rules! bar { + ($tt:tt) => { + pub const $tt: () = {}; + }; +} + +bar!(_); + +fn main() {} diff --git a/tests/ui/lint/unused-visibilities.rs b/tests/ui/lint/unused-visibilities.rs new file mode 100644 index 000000000000..4bcbd1201e4a --- /dev/null +++ b/tests/ui/lint/unused-visibilities.rs @@ -0,0 +1,29 @@ +//@ check-pass +//@ run-rustfix + +#![warn(unused_visibilities)] + +pub const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + +pub(self) const _: () = {}; +//~^WARN visibility qualifiers have no effect on `const _` declarations + +macro_rules! foo { + () => { + pub const _: () = {}; + //~^WARN visibility qualifiers have no effect on `const _` declarations + }; +} + +foo!(); + +macro_rules! bar { + ($tt:tt) => { + pub const $tt: () = {}; + }; +} + +bar!(_); + +fn main() {} diff --git a/tests/ui/lint/unused-visibilities.stderr b/tests/ui/lint/unused-visibilities.stderr new file mode 100644 index 000000000000..e5ff2a7fcae8 --- /dev/null +++ b/tests/ui/lint/unused-visibilities.stderr @@ -0,0 +1,35 @@ +warning: visibility qualifiers have no effect on `const _` declarations + --> $DIR/unused-visibilities.rs:6:1 + | +LL | pub const _: () = {}; + | ^^^ help: remove the qualifier + | + = note: `const _` does not declare a name, so there is nothing for the qualifier to apply to +note: the lint level is defined here + --> $DIR/unused-visibilities.rs:4:9 + | +LL | #![warn(unused_visibilities)] + | ^^^^^^^^^^^^^^^^^^^ + +warning: visibility qualifiers have no effect on `const _` declarations + --> $DIR/unused-visibilities.rs:9:1 + | +LL | pub(self) const _: () = {}; + | ^^^^^^^^^ help: remove the qualifier + | + = note: `const _` does not declare a name, so there is nothing for the qualifier to apply to + +warning: visibility qualifiers have no effect on `const _` declarations + --> $DIR/unused-visibilities.rs:14:9 + | +LL | pub const _: () = {}; + | ^^^ help: remove the qualifier +... +LL | foo!(); + | ------ in this macro invocation + | + = note: `const _` does not declare a name, so there is nothing for the qualifier to apply to + = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 3 warnings emitted + diff --git a/tests/ui/lint/unused/auxiliary/unused_assignment_proc_macro.rs b/tests/ui/lint/unused/auxiliary/unused_assignment_proc_macro.rs new file mode 100644 index 000000000000..41cfefbaff54 --- /dev/null +++ b/tests/ui/lint/unused/auxiliary/unused_assignment_proc_macro.rs @@ -0,0 +1,23 @@ +#![feature(proc_macro_quote)] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_derive(Drop)] +pub fn generate(ts: TokenStream) -> TokenStream { + let mut ts = ts.into_iter(); + let _pub = ts.next(); + let _struct = ts.next(); + let name = ts.next().unwrap(); + let TokenTree::Group(fields) = ts.next().unwrap() else { panic!() }; + let mut fields = fields.stream().into_iter(); + let field = fields.next().unwrap(); + + quote! { + impl Drop for $name { + fn drop(&mut self) { + let Self { $field } = self; + } + } + } +} diff --git a/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr b/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr index b06e65af7bc7..5928eb6c58c4 100644 --- a/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr +++ b/tests/ui/lint/unused/concat-in-crate-name-issue-137687.stderr @@ -17,7 +17,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[crate_name = concat !()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this macro def +note: this attribute does not have an `!`, which means it is applied to this macro def --> $DIR/concat-in-crate-name-issue-137687.rs:5:1 | LL | / macro_rules! a { diff --git a/tests/ui/lint/unused/diverging-path.rs b/tests/ui/lint/unused/diverging-path.rs new file mode 100644 index 000000000000..7f364518fe97 --- /dev/null +++ b/tests/ui/lint/unused/diverging-path.rs @@ -0,0 +1,21 @@ +//! Assignments to a captured variable within a diverging closure should not be considered unused if +//! the divergence is caught. +//! +//! Regression test for https://github.com/rust-lang/rust/issues/152079 +//@ compile-flags: -Wunused +//@ check-pass + +fn main() { + let mut x = 1; + catch(|| { + x = 2; + panic!(); + }); + dbg!(x); +} + +fn catch(f: F) { + if let Ok(true) = std::fs::exists("may_or_may_not_call_f") { + _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)); + } +} diff --git a/tests/ui/lint/unused/lint-unsed-in-macro-issue-151269.rs b/tests/ui/lint/unused/lint-unsed-in-macro-issue-151269.rs new file mode 100644 index 000000000000..65b8a22d383a --- /dev/null +++ b/tests/ui/lint/unused/lint-unsed-in-macro-issue-151269.rs @@ -0,0 +1,15 @@ +#![deny(unused_must_use)] + +fn error() -> Result<(), ()> { + Err(()) +} + +macro_rules! foo { + () => {{ + error(); + }}; +} + +fn main() { + let _ = foo!(); //~ ERROR unused `Result` that must be used +} diff --git a/tests/ui/lint/unused/lint-unsed-in-macro-issue-151269.stderr b/tests/ui/lint/unused/lint-unsed-in-macro-issue-151269.stderr new file mode 100644 index 000000000000..12cedf58974b --- /dev/null +++ b/tests/ui/lint/unused/lint-unsed-in-macro-issue-151269.stderr @@ -0,0 +1,19 @@ +error: unused `Result` that must be used + --> $DIR/lint-unsed-in-macro-issue-151269.rs:14:13 + | +LL | let _ = foo!(); + | ^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled +note: the lint level is defined here + --> $DIR/lint-unsed-in-macro-issue-151269.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = error(); + | +++++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/unused/match_with_guard.rs b/tests/ui/lint/unused/match_with_guard.rs new file mode 100644 index 000000000000..61e4321f6735 --- /dev/null +++ b/tests/ui/lint/unused/match_with_guard.rs @@ -0,0 +1,10 @@ +//! The mere presence of a match guard should not deem bound variables "used". +//! Regression test for https://github.com/rust-lang/rust/issues/151983 +//@ check-pass +#![warn(unused)] +fn main() { + match Some(42) { + Some(unused) if true => (), //~WARN unused variable: `unused` + _ => (), + } +} diff --git a/tests/ui/lint/unused/match_with_guard.stderr b/tests/ui/lint/unused/match_with_guard.stderr new file mode 100644 index 000000000000..6a509e568b68 --- /dev/null +++ b/tests/ui/lint/unused/match_with_guard.stderr @@ -0,0 +1,15 @@ +warning: unused variable: `unused` + --> $DIR/match_with_guard.rs:7:14 + | +LL | Some(unused) if true => (), + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_unused` + | +note: the lint level is defined here + --> $DIR/match_with_guard.rs:4:9 + | +LL | #![warn(unused)] + | ^^^^^^ + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: 1 warning emitted + diff --git a/tests/ui/lint/unused/mut-used-despite-borrowck-error.rs b/tests/ui/lint/unused/mut-used-despite-borrowck-error.rs new file mode 100644 index 000000000000..7f1a51bc8510 --- /dev/null +++ b/tests/ui/lint/unused/mut-used-despite-borrowck-error.rs @@ -0,0 +1,19 @@ +//! Do not fire unused_mut lint when mutation of the bound variable fails due to a borrow-checking +//! error. +//! +//! Regression test for https://github.com/rust-lang/rust/issues/152024 +//@ compile-flags: -W unused_mut + +struct Thing; +impl Drop for Thing { + fn drop(&mut self) {} +} + +fn main() { + let mut t; + let mut b = None; + loop { + t = Thing; //~ ERROR cannot assign to `t` because it is borrowed + b.insert(&t); + } +} diff --git a/tests/ui/lint/unused/mut-used-despite-borrowck-error.stderr b/tests/ui/lint/unused/mut-used-despite-borrowck-error.stderr new file mode 100644 index 000000000000..c03cf3f7c609 --- /dev/null +++ b/tests/ui/lint/unused/mut-used-despite-borrowck-error.stderr @@ -0,0 +1,13 @@ +error[E0506]: cannot assign to `t` because it is borrowed + --> $DIR/mut-used-despite-borrowck-error.rs:16:9 + | +LL | t = Thing; + | ^ `t` is assigned to here but it was already borrowed +LL | b.insert(&t); + | - -- `t` is borrowed here + | | + | borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/lint/unused/underscore-capture-issue-149889.rs b/tests/ui/lint/unused/underscore-capture-issue-149889.rs new file mode 100644 index 000000000000..3fbaf2588516 --- /dev/null +++ b/tests/ui/lint/unused/underscore-capture-issue-149889.rs @@ -0,0 +1,29 @@ +//@ check-pass +#![deny(unused_assignments)] + +fn lock() -> impl Drop { + struct Handle; + + impl Drop for Handle { + fn drop(&mut self) {} + } + + Handle +} + +fn bar(_f: impl FnMut(bool)) {} + +pub fn foo() { + let mut _handle = None; + bar(move |l| { + if l { + _handle = Some(lock()); + } else { + _handle = None; + } + }) +} + +fn main() { + foo(); +} diff --git a/tests/ui/lint/unused/unused-allocation-box-ref-issue-151846.rs b/tests/ui/lint/unused/unused-allocation-box-ref-issue-151846.rs new file mode 100644 index 000000000000..57eefc3891fa --- /dev/null +++ b/tests/ui/lint/unused/unused-allocation-box-ref-issue-151846.rs @@ -0,0 +1,54 @@ +//@ check-pass +// Test for issue #151846: unused_allocation warning should ignore +// allocations to pass Box to things taking self: &Box + +#![deny(unused_allocation)] + +struct MyStruct; + +trait TraitTakesBoxRef { + fn trait_takes_box_ref(&self); +} + +impl TraitTakesBoxRef for Box { + fn trait_takes_box_ref(&self) {} +} + +impl MyStruct { + fn inherent_takes_box_ref(self: &Box) {} +} + +fn takes_box_ref(_: &Box) {} + +trait TraitTakesBoxVal { + fn trait_takes_box_val(self); +} + +impl TraitTakesBoxVal for Box { + fn trait_takes_box_val(self) {} +} + +impl MyStruct { + fn inherent_takes_box_val(self: Box) {} +} + +fn takes_box_val(_: Box) {} + +pub fn foo() { + // These should NOT warn - the allocation is necessary because + // the method takes &Box + Box::new(MyStruct).trait_takes_box_ref(); + Box::new(MyStruct).inherent_takes_box_ref(); + takes_box_ref(&Box::new(MyStruct)); + + // These already don't warn - the allocation is necessary + Box::new(MyStruct).trait_takes_box_val(); + Box::new(MyStruct).inherent_takes_box_val(); + takes_box_val(Box::new(MyStruct)); + + // Fully-qualified syntax also does not warn: + as TraitTakesBoxRef>::trait_takes_box_ref(&Box::new(MyStruct)); + MyStruct::inherent_takes_box_ref(&Box::new(MyStruct)); +} + +fn main() {} diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 86506dba5f08..351645f4a783 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -28,18 +28,6 @@ note: attribute also specified here LL | #[no_link] | ^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:34:1 - | -LL | #![no_builtins] - | ^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:33:1 - | -LL | #![no_builtins] - | ^^^^^^^^^^^^^^^ - error: unused attribute --> $DIR/unused-attr-duplicate.rs:41:1 | @@ -316,5 +304,17 @@ LL | #![windows_subsystem = "console"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:34:1 + | +LL | #![no_builtins] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:33:1 + | +LL | #![no_builtins] + | ^^^^^^^^^^^^^^^ + error: aborting due to 25 previous errors diff --git a/tests/ui/lint/unused/unused-attr-macro-rules.stderr b/tests/ui/lint/unused/unused-attr-macro-rules.stderr index e251ec65622e..75e86d3c014f 100644 --- a/tests/ui/lint/unused/unused-attr-macro-rules.stderr +++ b/tests/ui/lint/unused/unused-attr-macro-rules.stderr @@ -27,7 +27,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[recursion_limit="1"] | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this macro def +note: this attribute does not have an `!`, which means it is applied to this macro def --> $DIR/unused-attr-macro-rules.rs:12:1 | LL | / macro_rules! foo { diff --git a/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs new file mode 100644 index 000000000000..a9da3e4175bd --- /dev/null +++ b/tests/ui/lint/unused/unused-attr-repr-packed-c-order.rs @@ -0,0 +1,13 @@ +//! regression test for +//@ check-pass +#![deny(unused_attributes)] + +#[repr(C)] +#[repr(packed)] +pub struct Foo; + +#[repr(packed)] +#[repr(C)] +pub struct Bar; + +fn main() {} diff --git a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr index c07411745549..0f0288c6def6 100644 --- a/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr +++ b/tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr @@ -105,7 +105,7 @@ LL | / if num == 3 { LL | | true | | ^^^^ expected `()`, found `bool` LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | help: you might have meant to return this value | diff --git a/tests/ui/lint/unused/unused-macros.stderr b/tests/ui/lint/unused/unused-macros.stderr index d0baf5becec4..50c80b61eb5b 100644 --- a/tests/ui/lint/unused/unused-macros.stderr +++ b/tests/ui/lint/unused/unused-macros.stderr @@ -15,6 +15,11 @@ error: unused macro definition: `m` | LL | macro_rules! m { | ^ +... +LL | create_macro!(); + | --------------- in this macro invocation + | + = note: this error originates in the macro `create_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: unused macro definition: `unused` --> $DIR/unused-macros.rs:26:18 diff --git a/tests/ui/lint/unused/unused-trait-fn.rs b/tests/ui/lint/unused/unused-trait-fn.rs new file mode 100644 index 000000000000..57b39c0de17e --- /dev/null +++ b/tests/ui/lint/unused/unused-trait-fn.rs @@ -0,0 +1,10 @@ +//! regression test for +//@ run-pass + +trait Str { fn foo(&self) {} } //~ WARN method `foo` is never used +impl Str for str {} +impl<'a, S: ?Sized> Str for &'a S where S: Str {} + +fn main() { + let _: &dyn Str = &"x"; +} diff --git a/tests/ui/lint/unused/unused-trait-fn.stderr b/tests/ui/lint/unused/unused-trait-fn.stderr new file mode 100644 index 000000000000..f33fed29c94c --- /dev/null +++ b/tests/ui/lint/unused/unused-trait-fn.stderr @@ -0,0 +1,12 @@ +warning: method `foo` is never used + --> $DIR/unused-trait-fn.rs:4:16 + | +LL | trait Str { fn foo(&self) {} } + | --- ^^^ + | | + | method in this trait + | + = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/lint/unused/unused-var-in-match-arm.rs b/tests/ui/lint/unused/unused-var-in-match-arm.rs new file mode 100644 index 000000000000..780225f98dbb --- /dev/null +++ b/tests/ui/lint/unused/unused-var-in-match-arm.rs @@ -0,0 +1,11 @@ +//! regression test for +#![deny(unused_variables)] + +fn f(_: i32) {} + +fn main() { + let mut v = 0; + f(v); + v = match 0 { a => 0 }; //~ ERROR: unused variable: `a` + f(v); +} diff --git a/tests/ui/lint/unused/unused-var-in-match-arm.stderr b/tests/ui/lint/unused/unused-var-in-match-arm.stderr new file mode 100644 index 000000000000..a1b9849293ef --- /dev/null +++ b/tests/ui/lint/unused/unused-var-in-match-arm.stderr @@ -0,0 +1,14 @@ +error: unused variable: `a` + --> $DIR/unused-var-in-match-arm.rs:9:19 + | +LL | v = match 0 { a => 0 }; + | ^ help: if this is intentional, prefix it with an underscore: `_a` + | +note: the lint level is defined here + --> $DIR/unused-var-in-match-arm.rs:2:9 + | +LL | #![deny(unused_variables)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/unused/unused_assignment.rs b/tests/ui/lint/unused/unused_assignment.rs new file mode 100644 index 000000000000..f7b8ec94bc3b --- /dev/null +++ b/tests/ui/lint/unused/unused_assignment.rs @@ -0,0 +1,21 @@ +// Unused assignments to an unused variable should trigger only the `unused_variables` lint and not +// also the `unused_assignments` lint. This test covers the situation where the span of the unused +// variable identifier comes from a different scope to the binding pattern - here, from a proc +// macro's input tokenstream (whereas the binding pattern is generated within the proc macro +// itself). +// +// Regression test for https://github.com/rust-lang/rust/issues/151514 +// +//@ check-pass +//@ proc-macro: unused_assignment_proc_macro.rs +#![warn(unused)] + +extern crate unused_assignment_proc_macro; +use unused_assignment_proc_macro::Drop; + +#[derive(Drop)] +pub struct S { + a: (), //~ WARN unused variable: `a` +} + +fn main() {} diff --git a/tests/ui/lint/unused/unused_assignment.stderr b/tests/ui/lint/unused/unused_assignment.stderr new file mode 100644 index 000000000000..1f0619ecf142 --- /dev/null +++ b/tests/ui/lint/unused/unused_assignment.stderr @@ -0,0 +1,15 @@ +warning: unused variable: `a` + --> $DIR/unused_assignment.rs:18:5 + | +LL | a: (), + | ^ help: try ignoring the field: `a: _` + | +note: the lint level is defined here + --> $DIR/unused_assignment.rs:11:9 + | +LL | #![warn(unused)] + | ^^^^^^ + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: 1 warning emitted + diff --git a/tests/ui/lint/unused/unused_assignments_across_match_guards.rs b/tests/ui/lint/unused/unused_assignments_across_match_guards.rs new file mode 100644 index 000000000000..666a529b8f85 --- /dev/null +++ b/tests/ui/lint/unused/unused_assignments_across_match_guards.rs @@ -0,0 +1,19 @@ +// Regression test for +// This test ensures that unused_assignments does not report assignments used in a match. +//@ check-pass + +fn pnk(x: usize) -> &'static str { + let mut k1 = "k1"; + let mut h1 = "h1"; + match x & 3 { + 3 if { k1 = "unused?"; false } => (), + _ if { h1 = k1; true } => (), + _ => (), + } + h1 +} + +#[deny(unused_assignments)] +fn main() { + pnk(3); +} diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr index 9b9a6a9c9f3d..3fc340b5188f 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.stderr +++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr @@ -5,7 +5,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits note: the lint level is defined here --> $DIR/unused_attributes-must_use.rs:4:9 | @@ -19,7 +19,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on modules --> $DIR/unused_attributes-must_use.rs:11:1 @@ -28,7 +28,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on use statements --> $DIR/unused_attributes-must_use.rs:15:1 @@ -37,7 +37,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on constants --> $DIR/unused_attributes-must_use.rs:19:1 @@ -46,7 +46,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on statics --> $DIR/unused_attributes-must_use.rs:22:1 @@ -55,7 +55,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on inherent impl blocks --> $DIR/unused_attributes-must_use.rs:40:1 @@ -64,7 +64,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on foreign modules --> $DIR/unused_attributes-must_use.rs:55:1 @@ -73,7 +73,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on foreign statics --> $DIR/unused_attributes-must_use.rs:59:5 @@ -82,7 +82,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on type aliases --> $DIR/unused_attributes-must_use.rs:73:1 @@ -91,16 +91,16 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits -error: `#[must_use]` attribute cannot be used on function params +error: `#[must_use]` attribute cannot be used on type parameters --> $DIR/unused_attributes-must_use.rs:77:8 | LL | fn qux<#[must_use] T>(_: T) {} | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on associated consts --> $DIR/unused_attributes-must_use.rs:82:5 @@ -109,7 +109,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on associated types --> $DIR/unused_attributes-must_use.rs:85:5 @@ -118,7 +118,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on trait impl blocks --> $DIR/unused_attributes-must_use.rs:95:1 @@ -127,7 +127,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on trait methods in impl blocks --> $DIR/unused_attributes-must_use.rs:100:5 @@ -136,7 +136,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions + = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, and traits error: `#[must_use]` attribute cannot be used on trait aliases --> $DIR/unused_attributes-must_use.rs:107:1 @@ -145,7 +145,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on macro defs --> $DIR/unused_attributes-must_use.rs:111:1 @@ -154,7 +154,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on statements --> $DIR/unused_attributes-must_use.rs:120:5 @@ -163,7 +163,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on closures --> $DIR/unused_attributes-must_use.rs:125:13 @@ -172,7 +172,7 @@ LL | let x = #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, foreign functions, functions, methods, traits, and unions + = help: `#[must_use]` can be applied to data types, foreign functions, functions, methods, and traits error: `#[must_use]` attribute cannot be used on match arms --> $DIR/unused_attributes-must_use.rs:148:9 @@ -181,7 +181,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on struct fields --> $DIR/unused_attributes-must_use.rs:157:28 @@ -190,7 +190,7 @@ LL | let s = PatternField { #[must_use] foo: 123 }; | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: `#[must_use]` attribute cannot be used on pattern fields --> $DIR/unused_attributes-must_use.rs:159:24 @@ -199,7 +199,7 @@ LL | let PatternField { #[must_use] foo } = s; | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits error: unused `X` that must be used --> $DIR/unused_attributes-must_use.rs:130:5 diff --git a/tests/ui/lint/unused/unused_parens/parens-around-guard-patterns-not-unused.rs b/tests/ui/lint/unused/unused_parens/parens-around-guard-patterns-not-unused.rs new file mode 100644 index 000000000000..d5b8365ee612 --- /dev/null +++ b/tests/ui/lint/unused/unused_parens/parens-around-guard-patterns-not-unused.rs @@ -0,0 +1,13 @@ +//! Guard patterns require parentheses to disambiguate precedence +//! +//! Regression test for https://github.com/rust-lang/rust/issues/149594 + +//@ check-pass + +#![feature(guard_patterns)] +#![expect(incomplete_features)] +#![warn(unused_parens)] + +fn main() { + let (_ if false) = (); +} diff --git a/tests/ui/lint/unused/useless-comment.rs b/tests/ui/lint/unused/useless-comment.rs index 898665278e39..24ff91752081 100644 --- a/tests/ui/lint/unused/useless-comment.rs +++ b/tests/ui/lint/unused/useless-comment.rs @@ -1,6 +1,7 @@ #![feature(stmt_expr_attributes)] #![deny(unused_doc_comments)] +#![deny(unused_attributes)] macro_rules! mac { () => {} @@ -15,7 +16,8 @@ unsafe extern "C" { } fn foo() { /// a //~ ERROR unused doc comment - #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment + #[doc(test(attr(allow(dead_code))))] + //~^ ERROR unused doc comment let x = 12; /// multi-line //~ ERROR unused doc comment @@ -24,7 +26,8 @@ fn foo() { match x { /// c //~ ERROR unused doc comment 1 => {}, - #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment + #[doc(test(attr(allow(dead_code))))] + //~^ ERROR unused doc comment _ => {} } @@ -38,7 +41,8 @@ fn foo() { /// bar //~ ERROR unused doc comment mac!(); - #[doc(test(attr(allow(dead_code))))] //~ ERROR unused doc comment + #[doc(test(attr(allow(dead_code))))] + //~^ ERROR unused doc comment let x = /** comment */ 47; //~ ERROR unused doc comment /// dox //~ ERROR unused doc comment diff --git a/tests/ui/lint/unused/useless-comment.stderr b/tests/ui/lint/unused/useless-comment.stderr index 39873b82b757..22e63caf607a 100644 --- a/tests/ui/lint/unused/useless-comment.stderr +++ b/tests/ui/lint/unused/useless-comment.stderr @@ -1,5 +1,5 @@ error: unused doc comment - --> $DIR/useless-comment.rs:9:1 + --> $DIR/useless-comment.rs:10:1 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations @@ -12,7 +12,7 @@ LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ error: unused doc comment - --> $DIR/useless-comment.rs:12:1 + --> $DIR/useless-comment.rs:13:1 | LL | /// a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | unsafe extern "C" { } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:13:1 + --> $DIR/useless-comment.rs:14:1 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ LL | unsafe extern "C" { } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:38:5 + --> $DIR/useless-comment.rs:41:5 | LL | /// bar | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations @@ -41,28 +41,29 @@ LL | /// bar = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment - --> $DIR/useless-comment.rs:17:5 + --> $DIR/useless-comment.rs:18:5 | LL | /// a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | #[doc(test(attr(allow(dead_code))))] +... LL | let x = 12; | ----------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:18:5 + --> $DIR/useless-comment.rs:19:5 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | let x = 12; | ----------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:21:5 + --> $DIR/useless-comment.rs:23:5 | LL | / /// multi-line LL | | /// doc comment @@ -72,6 +73,7 @@ LL | / match x { LL | | /// c LL | | 1 => {}, LL | | #[doc(test(attr(allow(dead_code))))] +LL | | LL | | _ => {} LL | | } | |_____- rustdoc does not generate documentation for expressions @@ -79,7 +81,7 @@ LL | | } = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:25:9 + --> $DIR/useless-comment.rs:27:9 | LL | /// c | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,17 +91,18 @@ LL | 1 => {}, = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:27:9 + --> $DIR/useless-comment.rs:29:9 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | _ => {} | ------- rustdoc does not generate documentation for match arms | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:31:5 + --> $DIR/useless-comment.rs:34:5 | LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -109,7 +112,7 @@ LL | unsafe {} = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:34:5 + --> $DIR/useless-comment.rs:37:5 | LL | #[doc = "foo"] | ^^^^^^^^^^^^^^ @@ -120,7 +123,7 @@ LL | 3; = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:35:5 + --> $DIR/useless-comment.rs:38:5 | LL | #[doc = "bar"] | ^^^^^^^^^^^^^^ @@ -130,17 +133,18 @@ LL | 3; = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:41:5 + --> $DIR/useless-comment.rs:44:5 | LL | #[doc(test(attr(allow(dead_code))))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | LL | let x = /** comment */ 47; | -------------------------- rustdoc does not generate documentation for statements | = help: use `//` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:42:13 + --> $DIR/useless-comment.rs:46:13 | LL | let x = /** comment */ 47; | ^^^^^^^^^^^^^^ -- rustdoc does not generate documentation for expressions @@ -148,7 +152,7 @@ LL | let x = /** comment */ 47; = help: use `/* */` for a plain comment error: unused doc comment - --> $DIR/useless-comment.rs:44:5 + --> $DIR/useless-comment.rs:48:5 | LL | /// dox | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/liveness/liveness-move-in-while.stderr b/tests/ui/liveness/liveness-move-in-while.stderr index dc48c4cc9acf..1bb97ad68c7c 100644 --- a/tests/ui/liveness/liveness-move-in-while.stderr +++ b/tests/ui/liveness/liveness-move-in-while.stderr @@ -35,7 +35,6 @@ LL | while true { while true { while true { x = y; x.clone(); } } } | | inside of this loop | inside of this loop | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value if the performance cost is acceptable | LL | while true { while true { while true { x = y.clone(); x.clone(); } } } diff --git a/tests/ui/liveness/liveness-use-after-move.stderr b/tests/ui/liveness/liveness-use-after-move.stderr index eab51edca37f..a94ceae79d56 100644 --- a/tests/ui/liveness/liveness-use-after-move.stderr +++ b/tests/ui/liveness/liveness-use-after-move.stderr @@ -9,7 +9,6 @@ LL | LL | println!("{}", *x); | ^^ value borrowed here after move | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value if the performance cost is acceptable | LL | let y = x.clone(); diff --git a/tests/ui/liveness/liveness-use-after-send.stderr b/tests/ui/liveness/liveness-use-after-send.stderr index 2323451a7d2d..da682325347c 100644 --- a/tests/ui/liveness/liveness-use-after-send.stderr +++ b/tests/ui/liveness/liveness-use-after-send.stderr @@ -13,7 +13,6 @@ note: consider changing this parameter type in function `send` to borrow instead | LL | fn send(ch: Chan, data: T) { | ---- in this function ^ this parameter takes ownership of the value - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value if the performance cost is acceptable | LL | send(ch, message.clone()); diff --git a/tests/ui/loop-match/invalid-attribute.stderr b/tests/ui/loop-match/invalid-attribute.stderr index ddb68aea31b6..c23452b9b844 100644 --- a/tests/ui/loop-match/invalid-attribute.stderr +++ b/tests/ui/loop-match/invalid-attribute.stderr @@ -94,14 +94,6 @@ LL | #[const_continue] | = help: `#[const_continue]` can be applied to -error: `#[const_continue]` should be applied to a break expression - --> $DIR/invalid-attribute.rs:40:9 - | -LL | #[const_continue] - | ^^^^^^^^^^^^^^^^^ -LL | 5 - | - not a break expression - error: `#[loop_match]` should be applied to a loop --> $DIR/invalid-attribute.rs:39:9 | @@ -111,5 +103,13 @@ LL | #[const_continue] LL | 5 | - not a loop +error: `#[const_continue]` should be applied to a break expression + --> $DIR/invalid-attribute.rs:40:9 + | +LL | #[const_continue] + | ^^^^^^^^^^^^^^^^^ +LL | 5 + | - not a break expression + error: aborting due to 14 previous errors diff --git a/tests/ui/loops/dont-suggest-break-thru-item.stderr b/tests/ui/loops/dont-suggest-break-thru-item.stderr index e7ed7ae15015..576bd353520f 100644 --- a/tests/ui/loops/dont-suggest-break-thru-item.stderr +++ b/tests/ui/loops/dont-suggest-break-thru-item.stderr @@ -6,7 +6,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -23,7 +23,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -40,7 +40,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` LL | | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -53,7 +53,7 @@ LL | | Err(1) | | ^^^^^^ expected `()`, found `Result<_, {integer}>` LL | | LL | | } - | |_____________- expected this to be `()` + | |_____________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` diff --git a/tests/ui/loops/loop-proper-liveness.stderr b/tests/ui/loops/loop-proper-liveness.stderr index cd4c064bcd19..5432043c7d24 100644 --- a/tests/ui/loops/loop-proper-liveness.stderr +++ b/tests/ui/loops/loop-proper-liveness.stderr @@ -7,7 +7,6 @@ LL | let x: i32; LL | println!("{:?}", x); | ^ `x` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let x: i32 = 42; diff --git a/tests/ui/lowering/issue-96847.rs b/tests/ui/lowering/issue-96847.rs index 9408f6b9b4ab..a1fd105d9dd4 100644 --- a/tests/ui/lowering/issue-96847.rs +++ b/tests/ui/lowering/issue-96847.rs @@ -1,4 +1,4 @@ -//@ run-pass +//@ check-fail // Test that this doesn't abort during AST lowering. In #96847 it did abort // because the attribute was being lowered twice. @@ -9,6 +9,7 @@ fn main() { for _ in [1,2,3] { #![lang="foo"] + //~^ ERROR definition of an unknown lang item: `foo` [E0522] println!("foo"); } } diff --git a/tests/ui/lowering/issue-96847.stderr b/tests/ui/lowering/issue-96847.stderr new file mode 100644 index 000000000000..2cded32f9fb8 --- /dev/null +++ b/tests/ui/lowering/issue-96847.stderr @@ -0,0 +1,9 @@ +error[E0522]: definition of an unknown lang item: `foo` + --> $DIR/issue-96847.rs:11:9 + | +LL | #![lang="foo"] + | ^^^^^^^^^^^^^^ definition of unknown lang item `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0522`. diff --git a/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr b/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr index 555d8eec6bab..3d1233cdd019 100644 --- a/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr +++ b/tests/ui/lowering/no-name-for-DefPath-issue-133426.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | fn b(_: impl Iterator) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0614]: type `!` cannot be dereferenced diff --git a/tests/ui/macros/assert-matches-macro-msg.rs b/tests/ui/macros/assert-matches-macro-msg.rs index 956bc9cf0f49..17900936a299 100644 --- a/tests/ui/macros/assert-matches-macro-msg.rs +++ b/tests/ui/macros/assert-matches-macro-msg.rs @@ -4,9 +4,7 @@ //@ error-pattern: right: 3 //@ needs-subprocess -#![feature(assert_matches)] - -use std::assert_matches::assert_matches; +use std::assert_matches; fn main() { assert_matches!(1 + 1, 3, "1 + 1 definitely should be 3"); diff --git a/tests/ui/macros/assert.with-generic-asset.stderr b/tests/ui/macros/assert.with-generic-asset.stderr index 51d8f28a35c3..523346830662 100644 --- a/tests/ui/macros/assert.with-generic-asset.stderr +++ b/tests/ui/macros/assert.with-generic-asset.stderr @@ -15,8 +15,6 @@ error: macro requires a boolean expression as an argument | LL | debug_assert!(); | ^^^^^^^^^^^^^^^ boolean expression required - | - = note: this error originates in the macro `debug_assert` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found keyword `struct` --> $DIR/assert.rs:8:19 diff --git a/tests/ui/macros/assert.without-generic-asset.stderr b/tests/ui/macros/assert.without-generic-asset.stderr index 51d8f28a35c3..523346830662 100644 --- a/tests/ui/macros/assert.without-generic-asset.stderr +++ b/tests/ui/macros/assert.without-generic-asset.stderr @@ -15,8 +15,6 @@ error: macro requires a boolean expression as an argument | LL | debug_assert!(); | ^^^^^^^^^^^^^^^ boolean expression required - | - = note: this error originates in the macro `debug_assert` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found keyword `struct` --> $DIR/assert.rs:8:19 diff --git a/tests/ui/macros/builtin-prelude-no-accidents.rs b/tests/ui/macros/builtin-prelude-no-accidents.rs index 9bebcb75526f..bffe3776b7b4 100644 --- a/tests/ui/macros/builtin-prelude-no-accidents.rs +++ b/tests/ui/macros/builtin-prelude-no-accidents.rs @@ -2,7 +2,7 @@ // because macros with the same names are in prelude. fn main() { - env::current_dir; //~ ERROR use of unresolved module or unlinked crate `env` - type A = panic::PanicInfo; //~ ERROR use of unresolved module or unlinked crate `panic` - type B = vec::Vec; //~ ERROR use of unresolved module or unlinked crate `vec` + env::current_dir; //~ ERROR cannot find module or crate `env` + type A = panic::PanicInfo; //~ ERROR cannot find module or crate `panic` + type B = vec::Vec; //~ ERROR cannot find module or crate `vec` } diff --git a/tests/ui/macros/builtin-prelude-no-accidents.stderr b/tests/ui/macros/builtin-prelude-no-accidents.stderr index 8c7095a6aedf..3cc322373afb 100644 --- a/tests/ui/macros/builtin-prelude-no-accidents.stderr +++ b/tests/ui/macros/builtin-prelude-no-accidents.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `env` +error[E0433]: cannot find module or crate `env` in this scope --> $DIR/builtin-prelude-no-accidents.rs:5:5 | LL | env::current_dir; @@ -10,7 +10,7 @@ help: consider importing this module LL + use std::env; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `panic` +error[E0433]: cannot find module or crate `panic` in this scope --> $DIR/builtin-prelude-no-accidents.rs:6:14 | LL | type A = panic::PanicInfo; @@ -22,7 +22,7 @@ help: consider importing this module LL + use std::panic; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `vec` +error[E0433]: cannot find module or crate `vec` in this scope --> $DIR/builtin-prelude-no-accidents.rs:7:14 | LL | type B = vec::Vec; diff --git a/tests/ui/macros/builtin-std-paths-fail.rs b/tests/ui/macros/builtin-std-paths-fail.rs index c1a4e32a6dcb..fd51c42ff37f 100644 --- a/tests/ui/macros/builtin-std-paths-fail.rs +++ b/tests/ui/macros/builtin-std-paths-fail.rs @@ -1,25 +1,25 @@ #[derive( - core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` - //~| ERROR could not find `RustcDecodable` in `core` - core::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `core` - //~| ERROR could not find `RustcDecodable` in `core` + core::RustcDecodable, //~ ERROR cannot find `RustcDecodable` in `core` + //~| ERROR cannot find `RustcDecodable` in `core` + core::RustcDecodable, //~ ERROR cannot find `RustcDecodable` in `core` + //~| ERROR cannot find `RustcDecodable` in `core` )] -#[core::bench] //~ ERROR could not find `bench` in `core` -#[core::global_allocator] //~ ERROR could not find `global_allocator` in `core` -#[core::test_case] //~ ERROR could not find `test_case` in `core` -#[core::test] //~ ERROR could not find `test` in `core` +#[core::bench] //~ ERROR cannot find `bench` in `core` +#[core::global_allocator] //~ ERROR cannot find `global_allocator` in `core` +#[core::test_case] //~ ERROR cannot find `test_case` in `core` +#[core::test] //~ ERROR cannot find `test` in `core` struct Core; #[derive( - std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` - //~| ERROR could not find `RustcDecodable` in `std` - std::RustcDecodable, //~ ERROR could not find `RustcDecodable` in `std` - //~| ERROR could not find `RustcDecodable` in `std` + std::RustcDecodable, //~ ERROR cannot find `RustcDecodable` in `std` + //~| ERROR cannot find `RustcDecodable` in `std` + std::RustcDecodable, //~ ERROR cannot find `RustcDecodable` in `std` + //~| ERROR cannot find `RustcDecodable` in `std` )] -#[std::bench] //~ ERROR could not find `bench` in `std` -#[std::global_allocator] //~ ERROR could not find `global_allocator` in `std` -#[std::test_case] //~ ERROR could not find `test_case` in `std` -#[std::test] //~ ERROR could not find `test` in `std` +#[std::bench] //~ ERROR cannot find `bench` in `std` +#[std::global_allocator] //~ ERROR cannot find `global_allocator` in `std` +#[std::test_case] //~ ERROR cannot find `test_case` in `std` +#[std::test] //~ ERROR cannot find `test` in `std` struct Std; fn main() {} diff --git a/tests/ui/macros/builtin-std-paths-fail.stderr b/tests/ui/macros/builtin-std-paths-fail.stderr index 85d2bd2132f2..247e3f172a3c 100644 --- a/tests/ui/macros/builtin-std-paths-fail.stderr +++ b/tests/ui/macros/builtin-std-paths-fail.stderr @@ -1,16 +1,16 @@ -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find `RustcDecodable` in `core` --> $DIR/builtin-std-paths-fail.rs:2:11 | LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find `RustcDecodable` in `core` --> $DIR/builtin-std-paths-fail.rs:4:11 | LL | core::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `core` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find `RustcDecodable` in `core` --> $DIR/builtin-std-paths-fail.rs:2:11 | LL | core::RustcDecodable, @@ -18,7 +18,7 @@ LL | core::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `core` +error[E0433]: cannot find `RustcDecodable` in `core` --> $DIR/builtin-std-paths-fail.rs:4:11 | LL | core::RustcDecodable, @@ -26,43 +26,43 @@ LL | core::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `bench` in `core` +error[E0433]: cannot find `bench` in `core` --> $DIR/builtin-std-paths-fail.rs:7:9 | LL | #[core::bench] | ^^^^^ could not find `bench` in `core` -error[E0433]: failed to resolve: could not find `global_allocator` in `core` +error[E0433]: cannot find `global_allocator` in `core` --> $DIR/builtin-std-paths-fail.rs:8:9 | LL | #[core::global_allocator] | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `core` -error[E0433]: failed to resolve: could not find `test_case` in `core` +error[E0433]: cannot find `test_case` in `core` --> $DIR/builtin-std-paths-fail.rs:9:9 | LL | #[core::test_case] | ^^^^^^^^^ could not find `test_case` in `core` -error[E0433]: failed to resolve: could not find `test` in `core` +error[E0433]: cannot find `test` in `core` --> $DIR/builtin-std-paths-fail.rs:10:9 | LL | #[core::test] | ^^^^ could not find `test` in `core` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find `RustcDecodable` in `std` --> $DIR/builtin-std-paths-fail.rs:14:10 | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find `RustcDecodable` in `std` --> $DIR/builtin-std-paths-fail.rs:16:10 | LL | std::RustcDecodable, | ^^^^^^^^^^^^^^ could not find `RustcDecodable` in `std` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find `RustcDecodable` in `std` --> $DIR/builtin-std-paths-fail.rs:14:10 | LL | std::RustcDecodable, @@ -70,7 +70,7 @@ LL | std::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `RustcDecodable` in `std` +error[E0433]: cannot find `RustcDecodable` in `std` --> $DIR/builtin-std-paths-fail.rs:16:10 | LL | std::RustcDecodable, @@ -78,25 +78,25 @@ LL | std::RustcDecodable, | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: could not find `bench` in `std` +error[E0433]: cannot find `bench` in `std` --> $DIR/builtin-std-paths-fail.rs:19:8 | LL | #[std::bench] | ^^^^^ could not find `bench` in `std` -error[E0433]: failed to resolve: could not find `global_allocator` in `std` +error[E0433]: cannot find `global_allocator` in `std` --> $DIR/builtin-std-paths-fail.rs:20:8 | LL | #[std::global_allocator] | ^^^^^^^^^^^^^^^^ could not find `global_allocator` in `std` -error[E0433]: failed to resolve: could not find `test_case` in `std` +error[E0433]: cannot find `test_case` in `std` --> $DIR/builtin-std-paths-fail.rs:21:8 | LL | #[std::test_case] | ^^^^^^^^^ could not find `test_case` in `std` -error[E0433]: failed to resolve: could not find `test` in `std` +error[E0433]: cannot find `test` in `std` --> $DIR/builtin-std-paths-fail.rs:22:8 | LL | #[std::test] diff --git a/tests/ui/macros/cfg.rs b/tests/ui/macros/cfg.rs index d992ec82e2fd..f0c51b2942f1 100644 --- a/tests/ui/macros/cfg.rs +++ b/tests/ui/macros/cfg.rs @@ -2,5 +2,6 @@ fn main() { cfg!(); //~ ERROR macro requires a cfg-pattern cfg!(123); //~ ERROR malformed `cfg` macro input cfg!(foo = 123); //~ ERROR malformed `cfg` macro input - cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern + cfg!(false, false); //~ ERROR expected 1 cfg-pattern + cfg!(foo); //~ WARN unexpected `cfg` condition name: `foo` } diff --git a/tests/ui/macros/cfg.stderr b/tests/ui/macros/cfg.stderr index 9a4c187f37b2..06529a5b7a61 100644 --- a/tests/ui/macros/cfg.stderr +++ b/tests/ui/macros/cfg.stderr @@ -29,9 +29,20 @@ LL | cfg!(foo = 123); error: expected 1 cfg-pattern --> $DIR/cfg.rs:5:5 | -LL | cfg!(foo, bar); - | ^^^^^^^^^^^^^^ +LL | cfg!(false, false); + | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 4 previous errors +warning: unexpected `cfg` condition name: `foo` + --> $DIR/cfg.rs:6:10 + | +LL | cfg!(foo); + | ^^^ + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(foo)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +error: aborting due to 4 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/macros/cfg_select.rs b/tests/ui/macros/cfg_select.rs index 2a627cc05b93..693e27daad7a 100644 --- a/tests/ui/macros/cfg_select.rs +++ b/tests/ui/macros/cfg_select.rs @@ -1,5 +1,6 @@ #![feature(cfg_select)] #![crate_type = "lib"] +#![warn(unreachable_cfg_select_predicates)] // Unused warnings are disabled by default in UI tests. fn print() { println!(cfg_select! { @@ -23,34 +24,139 @@ fn arm_rhs_expr_1() -> i32 { fn arm_rhs_expr_2() -> i32 { cfg_select! { - true => 1, - false => 2 + false => 2, + true => 1 } } fn arm_rhs_expr_3() -> i32 { cfg_select! { - true => 1, - false => 2, - true => { 42 } - false => -1 as i32, - true => 2 + 2, - false => "", - true => if true { 42 } else { 84 } - false => if true { 42 } else { 84 }, - true => return 42, - false => loop {} - true => (1, 2), - false => (1, 2,), - true => todo!(), - false => println!("hello"), + any(true) => 1, + any(false) => 2, + any(true) => { 42 } + any(true) => { 42 }, + any(false) => -1 as i32, + any(true) => 2 + 2, + any(false) => "", + any(true) => if true { 42 } else { 84 } + any(false) => if true { 42 } else { 84 }, + any(true) => return 42, + any(false) => loop {} + any(true) => (1, 2), + any(false) => (1, 2,), + any(true) => todo!(), + any(false) => println!("hello"), + } +} + +fn expand_to_statements() -> i32 { + cfg_select! { + false => { + let b = 2; + b + 1 + } + true => { + let a = 1; + a + 1 + } + } +} + +type ExpandToType = cfg_select! { + unix => { u32 }, + _ => i32, +}; + +fn expand_to_pattern(x: Option) -> bool { + match x { + (cfg_select! { + unix => Some(n), + _ => None, + }) => true, + _ => false, + } +} + +cfg_select! { + false => { + fn foo() {} + } + _ => { + fn bar() {} + } +} + +struct S; + +impl S { + cfg_select! { + false => { + fn foo() {} + } + _ => { + fn bar() {} + } + } +} + +trait T { + cfg_select! { + false => { + fn a(); + } + _ => { + fn b(); + } + } +} + +impl T for S { + cfg_select! { + false => { + fn a() {} + }, + _ => { + fn b() {} + } + } +} + +extern "C" { + cfg_select! { + false => { + fn puts(s: *const i8) -> i32; + } + _ => { + fn printf(fmt: *const i8, ...) -> i32; + } } } cfg_select! { _ => {} true => {} - //~^ WARN unreachable predicate + //~^ WARN unreachable configuration predicate +} + +cfg_select! { + true => {} + _ => {} + //~^ WARN unreachable configuration predicate +} + +cfg_select! { + unix => {} + not(unix) => {}, + _ => {} + //~^ WARN unreachable configuration predicate +} + +cfg_select! { + test => {} + test => {} + //~^ WARN unreachable configuration predicate + _ => {} + //~^ WARN unreachable configuration predicate } cfg_select! { @@ -68,7 +174,7 @@ cfg_select! { cfg_select! { () => {} - //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `(` + //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression } cfg_select! { @@ -89,9 +195,11 @@ cfg_select! { cfg_select! { a + 1 => {} //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `+` + //~| WARN unexpected `cfg` condition name } cfg_select! { cfg!() => {} //~^ ERROR expected one of `(`, `::`, `=>`, or `=`, found `!` + //~| WARN unexpected `cfg` condition name } diff --git a/tests/ui/macros/cfg_select.stderr b/tests/ui/macros/cfg_select.stderr index 3a5d2b0a1e1e..2da0c2169497 100644 --- a/tests/ui/macros/cfg_select.stderr +++ b/tests/ui/macros/cfg_select.stderr @@ -1,13 +1,5 @@ -warning: unreachable predicate - --> $DIR/cfg_select.rs:52:5 - | -LL | _ => {} - | - always matches -LL | true => {} - | ^^^^ this predicate is never reached - error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:56:1 + --> $DIR/cfg_select.rs:162:1 | LL | / cfg_select! { LL | | @@ -16,56 +8,114 @@ LL | | } | |_^ error: none of the predicates in this `cfg_select` evaluated to true - --> $DIR/cfg_select.rs:61:1 + --> $DIR/cfg_select.rs:167:1 | LL | cfg_select! {} | ^^^^^^^^^^^^^^ error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `=>` - --> $DIR/cfg_select.rs:65:5 + --> $DIR/cfg_select.rs:171:5 | LL | => {} | ^^ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `(` - --> $DIR/cfg_select.rs:70:5 +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/cfg_select.rs:176:5 | LL | () => {} - | ^ + | ^^ expressions are not allowed here error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:75:5 + --> $DIR/cfg_select.rs:181:5 | LL | "str" => {} | ^^^^^ expected a valid identifier here - | error[E0539]: malformed `cfg_select` macro input - --> $DIR/cfg_select.rs:80:5 + --> $DIR/cfg_select.rs:186:5 | LL | a::b => {} | ^^^^ expected a valid identifier here - | error[E0537]: invalid predicate `a` - --> $DIR/cfg_select.rs:85:5 + --> $DIR/cfg_select.rs:191:5 | LL | a() => {} | ^^^ error: expected one of `(`, `::`, `=>`, or `=`, found `+` - --> $DIR/cfg_select.rs:90:7 + --> $DIR/cfg_select.rs:196:7 | LL | a + 1 => {} | ^ expected one of `(`, `::`, `=>`, or `=` error: expected one of `(`, `::`, `=>`, or `=`, found `!` - --> $DIR/cfg_select.rs:95:8 + --> $DIR/cfg_select.rs:202:8 | LL | cfg!() => {} | ^ expected one of `(`, `::`, `=>`, or `=` -error: aborting due to 9 previous errors; 1 warning emitted +warning: unreachable configuration predicate + --> $DIR/cfg_select.rs:137:5 + | +LL | _ => {} + | - always matches +LL | true => {} + | ^^^^ this configuration predicate is never reached + | +note: the lint level is defined here + --> $DIR/cfg_select.rs:3:9 + | +LL | #![warn(unreachable_cfg_select_predicates)] // Unused warnings are disabled by default in UI tests. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: unreachable configuration predicate + --> $DIR/cfg_select.rs:143:5 + | +LL | true => {} + | ---- always matches +LL | _ => {} + | ^ this configuration predicate is never reached + +warning: unreachable configuration predicate + --> $DIR/cfg_select.rs:150:5 + | +LL | _ => {} + | ^ this configuration predicate is never reached + +warning: unreachable configuration predicate + --> $DIR/cfg_select.rs:156:5 + | +LL | test => {} + | ^^^^ this configuration predicate is never reached + +warning: unreachable configuration predicate + --> $DIR/cfg_select.rs:158:5 + | +LL | _ => {} + | ^ this configuration predicate is never reached + +warning: unexpected `cfg` condition name: `a` + --> $DIR/cfg_select.rs:196:5 + | +LL | a + 1 => {} + | ^ help: found config with similar value: `target_feature = "a"` + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(a)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: unexpected `cfg` condition name: `cfg` + --> $DIR/cfg_select.rs:202:5 + | +LL | cfg!() => {} + | ^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(cfg)` + = note: see for more information about checking conditional configuration + +error: aborting due to 9 previous errors; 7 warnings emitted Some errors have detailed explanations: E0537, E0539. For more information about an error, try `rustc --explain E0537`. diff --git a/tests/ui/macros/cfg_select_parse_error.rs b/tests/ui/macros/cfg_select_parse_error.rs new file mode 100644 index 000000000000..90fcb2309b34 --- /dev/null +++ b/tests/ui/macros/cfg_select_parse_error.rs @@ -0,0 +1,18 @@ +#![feature(cfg_select)] +#![crate_type = "lib"] + +// Check that parse errors in arms that are not selected are still reported. + +fn print() { + println!(cfg_select! { + false => { 1 ++ 2 } + //~^ ERROR Rust has no postfix increment operator + _ => { "not unix" } + }); +} + +cfg_select! { + false => { fn foo() { 1 +++ 2 } } + //~^ ERROR Rust has no postfix increment operator + _ => {} +} diff --git a/tests/ui/macros/cfg_select_parse_error.stderr b/tests/ui/macros/cfg_select_parse_error.stderr new file mode 100644 index 000000000000..d4c86c3ceade --- /dev/null +++ b/tests/ui/macros/cfg_select_parse_error.stderr @@ -0,0 +1,26 @@ +error: Rust has no postfix increment operator + --> $DIR/cfg_select_parse_error.rs:8:22 + | +LL | false => { 1 ++ 2 } + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL - false => { 1 ++ 2 } +LL + false => { { let tmp = 1 ; 1 += 1; tmp } 2 } + | + +error: Rust has no postfix increment operator + --> $DIR/cfg_select_parse_error.rs:15:29 + | +LL | false => { fn foo() { 1 +++ 2 } } + | ^^ not a valid postfix operator + | +help: use `+= 1` instead + | +LL - false => { fn foo() { 1 +++ 2 } } +LL + false => { fn foo() { { let tmp = 1 ; 1 += 1; tmp }+ 2 } } + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/macros/column-macro-collision.rs b/tests/ui/macros/column-macro-collision.rs new file mode 100644 index 000000000000..7acf491888af --- /dev/null +++ b/tests/ui/macros/column-macro-collision.rs @@ -0,0 +1,17 @@ +//! regression test for +//! user-defined `column!` macro must not shadow +//! the built-in `column!()` used internally by `panic!()`. +//@ check-pass +#![allow(unused)] + +macro_rules! column { + ($i:ident) => { + $i + }; +} + +fn foo() -> ! { + panic!(); +} + +fn main() {} diff --git a/tests/ui/macros/compile_error_macro-suppress-errors.rs b/tests/ui/macros/compile_error_macro-suppress-errors.rs new file mode 100644 index 000000000000..e1c2248035e9 --- /dev/null +++ b/tests/ui/macros/compile_error_macro-suppress-errors.rs @@ -0,0 +1,40 @@ +pub mod some_module { + compile_error!("Error in a module"); //~ ERROR: Error in a module + + fn abc() -> Hello { + let _: self::SomeType = self::Hello::new(); + let _: SomeType = Hello::new(); + } + + mod inner_module { + use super::Hello; + use crate::another_module::NotExist; //~ ERROR: unresolved import `crate::another_module::NotExist` + use crate::some_module::World; + struct Foo { + bar: crate::some_module::Xyz, + error: self::MissingType, //~ ERROR: cannot find type `MissingType` in module `self` + } + } +} + +pub mod another_module { + use crate::some_module::NotExist; + fn error_in_this_function() { + compile_error!("Error in a function"); //~ ERROR: Error in a function + } +} + +fn main() { + // these errors are suppressed because of the compile_error! macro + + let _ = some_module::some_function(); + let _: some_module::SomeType = some_module::Hello::new(); + + // these errors are not suppressed + + let _ = another_module::some_function(); + //~^ ERROR: cannot find function `some_function` in module `another_module` + let _: another_module::SomeType = another_module::Hello::new(); + //~^ ERROR: cannot find type `SomeType` in module `another_module` + //~| ERROR: cannot find `Hello` in `another_module` +} diff --git a/tests/ui/macros/compile_error_macro-suppress-errors.stderr b/tests/ui/macros/compile_error_macro-suppress-errors.stderr new file mode 100644 index 000000000000..bda1deb9c413 --- /dev/null +++ b/tests/ui/macros/compile_error_macro-suppress-errors.stderr @@ -0,0 +1,46 @@ +error: Error in a module + --> $DIR/compile_error_macro-suppress-errors.rs:2:5 + | +LL | compile_error!("Error in a module"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: Error in a function + --> $DIR/compile_error_macro-suppress-errors.rs:23:9 + | +LL | compile_error!("Error in a function"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0432]: unresolved import `crate::another_module::NotExist` + --> $DIR/compile_error_macro-suppress-errors.rs:11:13 + | +LL | use crate::another_module::NotExist; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `NotExist` in `another_module` + +error[E0433]: cannot find `Hello` in `another_module` + --> $DIR/compile_error_macro-suppress-errors.rs:37:55 + | +LL | let _: another_module::SomeType = another_module::Hello::new(); + | ^^^^^ could not find `Hello` in `another_module` + +error[E0425]: cannot find type `MissingType` in module `self` + --> $DIR/compile_error_macro-suppress-errors.rs:15:26 + | +LL | error: self::MissingType, + | ^^^^^^^^^^^ not found in `self` + +error[E0425]: cannot find function `some_function` in module `another_module` + --> $DIR/compile_error_macro-suppress-errors.rs:35:29 + | +LL | let _ = another_module::some_function(); + | ^^^^^^^^^^^^^ not found in `another_module` + +error[E0425]: cannot find type `SomeType` in module `another_module` + --> $DIR/compile_error_macro-suppress-errors.rs:37:28 + | +LL | let _: another_module::SomeType = another_module::Hello::new(); + | ^^^^^^^^ not found in `another_module` + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0425, E0432, E0433. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/macros/concat-nested-repetition.rs b/tests/ui/macros/concat-nested-repetition.rs new file mode 100644 index 000000000000..ac5394ef8dcc --- /dev/null +++ b/tests/ui/macros/concat-nested-repetition.rs @@ -0,0 +1,35 @@ +//@ check-pass +#![feature(macro_metavar_expr_concat)] + +struct A; +struct B; +const AA: A = A; +const BB: B = B; + +macro_rules! define_ioctl_data { + (struct $s:ident { + $($field:ident: $ty:ident $([$opt:ident])?,)* + }) => { + pub struct $s { + $($field: $ty,)* + } + + impl $s { + $($( + fn ${concat(get_, $field)}(&self) -> $ty { + let _ = $opt; + todo!() + } + )?)* + } + }; +} + +define_ioctl_data! { + struct Foo { + a: A [AA], + b: B [BB], + } +} + +fn main() {} diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr index 795d99449c26..17ec247bd4de 100644 --- a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr +++ b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr @@ -5,7 +5,7 @@ LL | ($e:expr) => { | ^^^^ | = warning: this changes meaning in Rust 2024 - = note: for more information, see Migration Guide + = note: for more information, see note: the lint level is defined here --> $DIR/expr_2021_cargo_fix_edition.rs:4:9 | @@ -23,7 +23,7 @@ LL | ($($i:expr)*) => { }; | ^^^^ | = warning: this changes meaning in Rust 2024 - = note: for more information, see Migration Guide + = note: for more information, see help: to keep the existing behavior, use the `expr_2021` fragment specifier | LL | ($($i:expr_2021)*) => { }; diff --git a/tests/ui/macros/failed-to-reparse-issue-139445.stderr b/tests/ui/macros/failed-to-reparse-issue-139445.stderr index 6f7d88fb3446..fc3a2645e25e 100644 --- a/tests/ui/macros/failed-to-reparse-issue-139445.stderr +++ b/tests/ui/macros/failed-to-reparse-issue-139445.stderr @@ -9,16 +9,12 @@ error: expected `while`, `for`, `loop` or `{` after a label | LL | assert_eq!(3, 'a,) | ^^^^^^^^^^^^^^^^^^ expected `while`, `for`, `loop` or `{` after a label - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found `` --> $DIR/failed-to-reparse-issue-139445.rs:2:5 | LL | assert_eq!(3, 'a,) | ^^^^^^^^^^^^^^^^^^ expected expression - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/macros/format-parse-errors.stderr b/tests/ui/macros/format-parse-errors.stderr index f9ea4c63377b..baa29170a7d4 100644 --- a/tests/ui/macros/format-parse-errors.stderr +++ b/tests/ui/macros/format-parse-errors.stderr @@ -3,8 +3,6 @@ error: requires at least a format string argument | LL | format!(); | ^^^^^^^^^ - | - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected expression, found keyword `struct` --> $DIR/format-parse-errors.rs:5:13 diff --git a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout index ba93384644d5..f01807ec0617 100644 --- a/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout +++ b/tests/ui/macros/genercs-in-path-with-prettry-hir.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir //@ edition: 2015 diff --git a/tests/ui/macros/issue-118786.fixed b/tests/ui/macros/issue-118786.fixed new file mode 100644 index 000000000000..5d4006acd6c8 --- /dev/null +++ b/tests/ui/macros/issue-118786.fixed @@ -0,0 +1,20 @@ +#![allow(unused_macros)] +//@ compile-flags: --crate-type lib +//@ dont-require-annotations: NOTE +//@ run-rustfix + +// Regression test for issue 118786 + +macro_rules! make_macro { + ($macro_name:tt) => { + macro_rules! $macro_name { + //~^ ERROR macro expansion ignores `{` and any tokens following + //~| ERROR cannot find macro `macro_rules` in this scope + //~| NOTE put a macro name here + () => {} + } + } +} + +make_macro!(meow); +//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon diff --git a/tests/ui/macros/issue-118786.rs b/tests/ui/macros/issue-118786.rs index 78fd6ab6eddd..b79a2c7eedd7 100644 --- a/tests/ui/macros/issue-118786.rs +++ b/tests/ui/macros/issue-118786.rs @@ -1,5 +1,7 @@ -//@ compile-flags: --crate-type lib -O -C debug-assertions=yes +#![allow(unused_macros)] +//@ compile-flags: --crate-type lib //@ dont-require-annotations: NOTE +//@ run-rustfix // Regression test for issue 118786 diff --git a/tests/ui/macros/issue-118786.stderr b/tests/ui/macros/issue-118786.stderr index ddec281b8232..02b26e5a1f31 100644 --- a/tests/ui/macros/issue-118786.stderr +++ b/tests/ui/macros/issue-118786.stderr @@ -1,21 +1,17 @@ error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-118786.rs:17:13 + --> $DIR/issue-118786.rs:19:13 | LL | make_macro!((meow)); | ^^^^^^ | -help: change the delimiters to curly braces +help: to define a macro, remove the parentheses around the macro name | LL - make_macro!((meow)); -LL + make_macro!({meow}); +LL + make_macro!(meow); | -help: add a semicolon - | -LL | macro_rules! $macro_name; { - | + error: macro expansion ignores `{` and any tokens following - --> $DIR/issue-118786.rs:8:34 + --> $DIR/issue-118786.rs:10:34 | LL | macro_rules! $macro_name { | ^ @@ -26,7 +22,7 @@ LL | make_macro!((meow)); = note: the usage of `make_macro!` is likely invalid in item context error: cannot find macro `macro_rules` in this scope - --> $DIR/issue-118786.rs:8:9 + --> $DIR/issue-118786.rs:10:9 | LL | macro_rules! $macro_name { | ^^^^^^^^^^^ @@ -35,7 +31,7 @@ LL | make_macro!((meow)); | ------------------- in this macro invocation | note: maybe you have forgotten to define a name for this `macro_rules!` - --> $DIR/issue-118786.rs:8:20 + --> $DIR/issue-118786.rs:10:20 | LL | macro_rules! $macro_name { | ^ put a macro name here diff --git a/tests/ui/macros/issue-34171.rs b/tests/ui/macros/issue-34171.rs index fbc2ea50097d..3f13341230fa 100644 --- a/tests/ui/macros/issue-34171.rs +++ b/tests/ui/macros/issue-34171.rs @@ -6,5 +6,5 @@ macro_rules! apply_null { } fn main() { - apply_null!(#[cfg(all())] fn f() {}); + apply_null!(#[cfg(true)] fn f() {}); } diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr deleted file mode 100644 index 4342d7d88f54..000000000000 --- a/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0428]: the name `A` is defined multiple times - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:13 - | -LL | const A = "A".$fn(); - | ^^^^^^^^^^^^^^^^^^^^ `A` redefined here -... -LL | / suite! { -LL | | len; -LL | | is_empty; -LL | | } - | |_- in this macro invocation - | - = note: `A` must be defined only once in the value namespace of this module - = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: missing type for `const` item - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 - | -LL | const A = "A".$fn(); - | ^ help: provide a type for the constant: `: usize` -... -LL | / suite! { -LL | | len; -LL | | is_empty; -LL | | } - | |_- in this macro invocation - | - = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0121]: missing type for item - --> $DIR/issue-69396-const-no-type-in-macro.rs:4:20 - | -LL | const A = "A".$fn(); - | ^ not allowed in type signatures -... -LL | / suite! { -LL | | len; -LL | | is_empty; -LL | | } - | |_- in this macro invocation - | - = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0121, E0428. -For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/macros/macro-context.stderr b/tests/ui/macros/macro-context.stderr index edddfef9de3b..3ec1af3a82f8 100644 --- a/tests/ui/macros/macro-context.stderr +++ b/tests/ui/macros/macro-context.stderr @@ -46,12 +46,16 @@ error[E0425]: cannot find type `i` in this scope --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); - | ^ help: a builtin type with a similar name exists: `i8` + | ^ ... LL | let a: m!(); | ---- in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a builtin type with a similar name exists + | +LL | () => ( i8 ; typeof ); + | + error[E0425]: cannot find value `i` in this scope --> $DIR/macro-context.rs:3:13 diff --git a/tests/ui/macros/macro-expansion-empty-span-147255.stderr b/tests/ui/macros/macro-expansion-empty-span-147255.stderr index 99396622b34e..cea691679988 100644 --- a/tests/ui/macros/macro-expansion-empty-span-147255.stderr +++ b/tests/ui/macros/macro-expansion-empty-span-147255.stderr @@ -8,7 +8,6 @@ LL | println!("{}", x_str); | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-inner-attributes.rs b/tests/ui/macros/macro-inner-attributes.rs index 1a832ca9b0c4..fc69f2e4cebe 100644 --- a/tests/ui/macros/macro-inner-attributes.rs +++ b/tests/ui/macros/macro-inner-attributes.rs @@ -4,8 +4,8 @@ macro_rules! test { ($nm:ident, #[$a:meta], $i:item) => (mod $nm { #![$a] $i }); } -test!(a, - #[cfg(false)], +test!(a, //~ NOTE: found an item that was configured out + #[cfg(false)], //~ NOTE: the item is gated here pub fn bar() { }); test!(b, @@ -14,7 +14,7 @@ test!(b, #[rustc_dummy] fn main() { - a::bar(); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `a` + a::bar(); //~ ERROR: cannot find module or crate `a` + //~^ NOTE: use of unresolved module or unlinked crate `a` b::bar(); } diff --git a/tests/ui/macros/macro-inner-attributes.stderr b/tests/ui/macros/macro-inner-attributes.stderr index 3c043c38abb5..5523dda33c32 100644 --- a/tests/ui/macros/macro-inner-attributes.stderr +++ b/tests/ui/macros/macro-inner-attributes.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `a` +error[E0433]: cannot find module or crate `a` in this scope --> $DIR/macro-inner-attributes.rs:17:5 | LL | a::bar(); diff --git a/tests/ui/macros/macro-lifetime-used-with-labels.rs b/tests/ui/macros/macro-lifetime-used-with-labels.rs index 3b51b8050b34..4489ca6b681b 100644 --- a/tests/ui/macros/macro-lifetime-used-with-labels.rs +++ b/tests/ui/macros/macro-lifetime-used-with-labels.rs @@ -1,5 +1,4 @@ //@ run-pass -#![allow(stable_features)] #![allow(unused_labels)] #![allow(unreachable_code)] diff --git a/tests/ui/macros/macro-local-data-key-priv.stderr b/tests/ui/macros/macro-local-data-key-priv.stderr index 8df1aec140d0..2aced92c4152 100644 --- a/tests/ui/macros/macro-local-data-key-priv.stderr +++ b/tests/ui/macros/macro-local-data-key-priv.stderr @@ -9,7 +9,6 @@ note: the constant `baz` is defined here | LL | thread_local!(static baz: f64 = 0.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_process_attrs` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs index d2bd31b06d60..3ee11d373e05 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs +++ b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.rs @@ -11,7 +11,7 @@ macro_rules! InRepetition { ) => { $( $( - ${concat(_, $arg)} //~ ERROR nested repetitions with `${concat(...)}` metavariable expressions are not yet supported + ${concat(_, $arg)} //~ ERROR macro expansion ends with an incomplete expression: expected one of `!` or `::` )* )* }; diff --git a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr index ec39ca799e19..b84d98874931 100644 --- a/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr +++ b/tests/ui/macros/macro-metavar-expr-concat/in-repetition.stderr @@ -1,8 +1,8 @@ -error: nested repetitions with `${concat(...)}` metavariable expressions are not yet supported - --> $DIR/in-repetition.rs:14:30 +error: macro expansion ends with an incomplete expression: expected one of `!` or `::` + --> $DIR/in-repetition.rs:14:35 | LL | ${concat(_, $arg)} - | ^^^ + | ^ expected one of `!` or `::` error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-name-typo.stderr b/tests/ui/macros/macro-name-typo.stderr index 1cc7ea6ec1b6..bca7dbe9369c 100644 --- a/tests/ui/macros/macro-name-typo.stderr +++ b/tests/ui/macros/macro-name-typo.stderr @@ -2,11 +2,16 @@ error: cannot find macro `printlx` in this scope --> $DIR/macro-name-typo.rs:2:5 | LL | printlx!("oh noes!"); - | ^^^^^^^ help: a macro with a similar name exists: `println` + | ^^^^^^^ | --> $SRC_DIR/std/src/macros.rs:LL:COL | = note: similarly named macro `println` defined here +help: a macro with a similar name exists + | +LL - printlx!("oh noes!"); +LL + println!("oh noes!"); + | error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-path-prelude-fail-1.rs b/tests/ui/macros/macro-path-prelude-fail-1.rs index d93792bdfe38..a077ef0c6632 100644 --- a/tests/ui/macros/macro-path-prelude-fail-1.rs +++ b/tests/ui/macros/macro-path-prelude-fail-1.rs @@ -1,7 +1,9 @@ mod m { fn check() { - Vec::clone!(); //~ ERROR failed to resolve: `Vec` is a struct, not a module - u8::clone!(); //~ ERROR failed to resolve: `u8` is a builtin type, not a module + Vec::clone!(); //~ ERROR cannot find + //~^ NOTE `Vec` is a struct, not a module + u8::clone!(); //~ ERROR cannot find + //~^ NOTE `u8` is a builtin type, not a module } } diff --git a/tests/ui/macros/macro-path-prelude-fail-1.stderr b/tests/ui/macros/macro-path-prelude-fail-1.stderr index f8377ffb3555..0332b18992eb 100644 --- a/tests/ui/macros/macro-path-prelude-fail-1.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-1.stderr @@ -1,11 +1,11 @@ -error[E0433]: failed to resolve: `Vec` is a struct, not a module +error[E0433]: cannot find module `Vec` in this scope --> $DIR/macro-path-prelude-fail-1.rs:3:9 | LL | Vec::clone!(); | ^^^ `Vec` is a struct, not a module -error[E0433]: failed to resolve: `u8` is a builtin type, not a module - --> $DIR/macro-path-prelude-fail-1.rs:4:9 +error[E0433]: cannot find module `u8` in this scope + --> $DIR/macro-path-prelude-fail-1.rs:5:9 | LL | u8::clone!(); | ^^ `u8` is a builtin type, not a module diff --git a/tests/ui/macros/macro-path-prelude-fail-2.rs b/tests/ui/macros/macro-path-prelude-fail-2.rs index 816a3c4ccc00..f359f34e4fd1 100644 --- a/tests/ui/macros/macro-path-prelude-fail-2.rs +++ b/tests/ui/macros/macro-path-prelude-fail-2.rs @@ -1,6 +1,6 @@ mod m { fn check() { - Result::Ok!(); //~ ERROR failed to resolve: partially resolved path in a macro + Result::Ok!(); //~ ERROR cannot find } } diff --git a/tests/ui/macros/macro-path-prelude-fail-2.stderr b/tests/ui/macros/macro-path-prelude-fail-2.stderr index 87646031cdb8..e1ea8cbc60ec 100644 --- a/tests/ui/macros/macro-path-prelude-fail-2.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-2.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: partially resolved path in a macro +error[E0433]: cannot find macro `Ok` in enum `Result` --> $DIR/macro-path-prelude-fail-2.rs:3:9 | LL | Result::Ok!(); - | ^^^^^^^^^^ partially resolved path in a macro + | ^^^^^^^^^^ a macro can't exist within an enum error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-path-prelude-fail-3.stderr b/tests/ui/macros/macro-path-prelude-fail-3.stderr index 3d0a074deeb0..7bf166d0e56f 100644 --- a/tests/ui/macros/macro-path-prelude-fail-3.stderr +++ b/tests/ui/macros/macro-path-prelude-fail-3.stderr @@ -2,13 +2,18 @@ error: cannot find macro `inline` in this scope --> $DIR/macro-path-prelude-fail-3.rs:2:5 | LL | inline!(); - | ^^^^^^ help: a macro with a similar name exists: `line` + | ^^^^^^ | --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named macro `line` defined here | = note: `inline` is in scope, but it is an attribute: `#[inline]` +help: a macro with a similar name exists + | +LL - inline!(); +LL + line!(); + | error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-reexport-removed.stderr b/tests/ui/macros/macro-reexport-removed.stderr index 8130fe0c4bda..752133162214 100644 --- a/tests/ui/macros/macro-reexport-removed.stderr +++ b/tests/ui/macros/macro-reexport-removed.stderr @@ -11,7 +11,13 @@ error: cannot find attribute `macro_reexport` in this scope --> $DIR/macro-reexport-removed.rs:5:3 | LL | #[macro_reexport(macro_one)] - | ^^^^^^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_export` + | ^^^^^^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[macro_reexport(macro_one)] +LL + #[macro_export(macro_one)] + | error: aborting due to 2 previous errors diff --git a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs index a2e1398c61e6..a556983e204d 100644 --- a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs +++ b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.rs @@ -5,5 +5,4 @@ macro_rules! sample { () => {} } #[sample] //~ ERROR cannot find attribute `sample` in this scope #[derive(sample)] //~ ERROR cannot find derive macro `sample` in this scope //~| ERROR cannot find derive macro `sample` in this scope - //~| ERROR cannot find derive macro `sample` in this scope pub struct S {} diff --git a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr index aad4a844ec17..a3c21df43e75 100644 --- a/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr +++ b/tests/ui/macros/macro-rules-as-derive-or-attr-issue-132928.stderr @@ -1,12 +1,3 @@ -error: cannot find derive macro `sample` in this scope - --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10 - | -LL | macro_rules! sample { () => {} } - | ------ `sample` exists, but has no `derive` rules -... -LL | #[derive(sample)] - | ^^^^^^ - error: cannot find attribute `sample` in this scope --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:5:3 | @@ -24,8 +15,6 @@ LL | macro_rules! sample { () => {} } ... LL | #[derive(sample)] | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: cannot find derive macro `sample` in this scope --> $DIR/macro-rules-as-derive-or-attr-issue-132928.rs:6:10 @@ -38,5 +27,5 @@ LL | #[derive(sample)] | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/macros/macro_path_as_generic_bound.rs b/tests/ui/macros/macro_path_as_generic_bound.rs index 663f85688ec9..d720752f4ca5 100644 --- a/tests/ui/macros/macro_path_as_generic_bound.rs +++ b/tests/ui/macros/macro_path_as_generic_bound.rs @@ -4,6 +4,6 @@ macro_rules! foo(($t:path) => { impl Foo for T {} }); -foo!(m::m2::A); //~ ERROR failed to resolve +foo!(m::m2::A); //~ ERROR cannot find fn main() {} diff --git a/tests/ui/macros/macro_path_as_generic_bound.stderr b/tests/ui/macros/macro_path_as_generic_bound.stderr index 9fe4ad27aa05..c4454ff23e6a 100644 --- a/tests/ui/macros/macro_path_as_generic_bound.stderr +++ b/tests/ui/macros/macro_path_as_generic_bound.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `m` +error[E0433]: cannot find module or crate `m` in this scope --> $DIR/macro_path_as_generic_bound.rs:7:6 | LL | foo!(m::m2::A); diff --git a/tests/ui/macros/macro_undefined.stderr b/tests/ui/macros/macro_undefined.stderr index cc3efacbc541..ed58be8808b2 100644 --- a/tests/ui/macros/macro_undefined.stderr +++ b/tests/ui/macros/macro_undefined.stderr @@ -5,7 +5,12 @@ LL | macro_rules! kl { | --------------- similarly named macro `kl` defined here ... LL | k!(); - | ^ help: a macro with a similar name exists: `kl` + | ^ + | +help: a macro with a similar name exists + | +LL | kl!(); + | + error: aborting due to 1 previous error diff --git a/tests/ui/macros/meta-item-absolute-path.rs b/tests/ui/macros/meta-item-absolute-path.rs index e677016cff82..429d259ae2c4 100644 --- a/tests/ui/macros/meta-item-absolute-path.rs +++ b/tests/ui/macros/meta-item-absolute-path.rs @@ -1,6 +1,6 @@ //@ edition:2015 -#[derive(::Absolute)] //~ ERROR failed to resolve - //~| ERROR failed to resolve +#[derive(::Absolute)] //~ ERROR cannot find + //~| ERROR cannot find struct S; fn main() {} diff --git a/tests/ui/macros/meta-item-absolute-path.stderr b/tests/ui/macros/meta-item-absolute-path.stderr index 93c442036ce2..9a9d90ca3f44 100644 --- a/tests/ui/macros/meta-item-absolute-path.stderr +++ b/tests/ui/macros/meta-item-absolute-path.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `Absolute` +error[E0433]: cannot find module or crate `Absolute` in the crate root --> $DIR/meta-item-absolute-path.rs:2:12 | LL | #[derive(::Absolute)] | ^^^^^^^^ use of unresolved module or unlinked crate `Absolute` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `Absolute` +error[E0433]: cannot find module or crate `Absolute` in the crate root --> $DIR/meta-item-absolute-path.rs:2:12 | LL | #[derive(::Absolute)] diff --git a/tests/ui/macros/metavar-expressions/concat-repetitions.rs b/tests/ui/macros/metavar-expressions/concat-repetitions.rs index 52a7d5cd8a7e..133a969b1248 100644 --- a/tests/ui/macros/metavar-expressions/concat-repetitions.rs +++ b/tests/ui/macros/metavar-expressions/concat-repetitions.rs @@ -11,8 +11,7 @@ macro_rules! one_rep { macro_rules! issue_128346 { ( $($a:ident)* ) => { A( - const ${concat($a, Z)}: i32 = 3; - //~^ ERROR invalid syntax + const ${concat($a, Z)}: i32 = 3; //~ ERROR `${concat(...)}` variable is still repeating at this depth )* }; } @@ -20,8 +19,8 @@ macro_rules! issue_128346 { macro_rules! issue_131393 { ($t:ident $($en:ident)?) => { read::<${concat($t, $en)}>() - //~^ ERROR invalid syntax - //~| ERROR invalid syntax + //~^ ERROR `${concat(...)}` variable is still repeating at this depth + //~| ERROR `${concat(...)}` variable is still repeating at this depth } } diff --git a/tests/ui/macros/metavar-expressions/concat-repetitions.stderr b/tests/ui/macros/metavar-expressions/concat-repetitions.stderr index 18b0a90c1c8a..0ef20c65a284 100644 --- a/tests/ui/macros/metavar-expressions/concat-repetitions.stderr +++ b/tests/ui/macros/metavar-expressions/concat-repetitions.stderr @@ -1,20 +1,20 @@ -error: invalid syntax - --> $DIR/concat-repetitions.rs:14:20 +error: `${concat(...)}` variable is still repeating at this depth + --> $DIR/concat-repetitions.rs:14:29 | LL | const ${concat($a, Z)}: i32 = 3; - | ^^^^^^^^^^^^^^^ + | ^ -error: invalid syntax - --> $DIR/concat-repetitions.rs:22:17 +error: `${concat(...)}` variable is still repeating at this depth + --> $DIR/concat-repetitions.rs:21:30 | LL | read::<${concat($t, $en)}>() - | ^^^^^^^^^^^^^^^^^ + | ^^ -error: invalid syntax - --> $DIR/concat-repetitions.rs:22:17 +error: `${concat(...)}` variable is still repeating at this depth + --> $DIR/concat-repetitions.rs:21:30 | LL | read::<${concat($t, $en)}>() - | ^^^^^^^^^^^^^^^^^ + | ^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/macros/metavar-expressions/usage-errors.rs b/tests/ui/macros/metavar-expressions/usage-errors.rs index feff02e2ce47..966ffadb32af 100644 --- a/tests/ui/macros/metavar-expressions/usage-errors.rs +++ b/tests/ui/macros/metavar-expressions/usage-errors.rs @@ -27,6 +27,7 @@ curly__rhs_dollar__no_round !(a); macro_rules! no_curly__no_rhs_dollar__round { ( $( $i:ident ),* ) => { count(i) }; //~^ ERROR missing `fn` or `struct` for function or struct definition + //~| HELP if you meant to call a macro, try } no_curly__no_rhs_dollar__round !(a, b, c); @@ -34,6 +35,7 @@ no_curly__no_rhs_dollar__round !(a, b, c); macro_rules! no_curly__no_rhs_dollar__no_round { ( $i:ident ) => { count(i) }; //~^ ERROR missing `fn` or `struct` for function or struct definition + //~| HELP if you meant to call a macro, try } no_curly__no_rhs_dollar__no_round !(a); diff --git a/tests/ui/macros/metavar-expressions/usage-errors.stderr b/tests/ui/macros/metavar-expressions/usage-errors.stderr index f66f522e23b9..3d22e3ac4b30 100644 --- a/tests/ui/macros/metavar-expressions/usage-errors.stderr +++ b/tests/ui/macros/metavar-expressions/usage-errors.stderr @@ -26,7 +26,7 @@ LL | ( $( $i:ident ),* ) => { count!(i) }; | + error: missing `fn` or `struct` for function or struct definition - --> $DIR/usage-errors.rs:35:23 + --> $DIR/usage-errors.rs:36:23 | LL | ( $i:ident ) => { count(i) }; | ^^^^^ @@ -41,13 +41,13 @@ LL | ( $i:ident ) => { count!(i) }; | + error: variable `i` is still repeating at this depth - --> $DIR/usage-errors.rs:42:36 + --> $DIR/usage-errors.rs:44:36 | LL | ( $( $i:ident ),* ) => { count($i) }; | ^^ error[E0425]: cannot find value `a` in this scope - --> $DIR/usage-errors.rs:52:49 + --> $DIR/usage-errors.rs:54:49 | LL | ( $i:ident ) => { count($i) }; | -- due to this macro variable @@ -56,7 +56,7 @@ LL | const _: u32 = no_curly__rhs_dollar__no_round! (a); | ^ not found in this scope error[E0425]: cannot find function `count` in this scope - --> $DIR/usage-errors.rs:49:23 + --> $DIR/usage-errors.rs:51:23 | LL | ( $i:ident ) => { count($i) }; | ^^^^^ not found in this scope diff --git a/tests/ui/macros/non-fmt-panic.stderr b/tests/ui/macros/non-fmt-panic.stderr index 43f59782ee72..8a89d5ea7939 100644 --- a/tests/ui/macros/non-fmt-panic.stderr +++ b/tests/ui/macros/non-fmt-panic.stderr @@ -4,6 +4,7 @@ warning: panic message contains a brace LL | panic!("here's a brace: {"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default help: add a "{}" format string to use the message literally @@ -17,6 +18,7 @@ warning: panic message contains a brace LL | unreachable!("here's a brace: {"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -29,6 +31,7 @@ warning: panic message contains a brace LL | std::panic!("another one: }"); | ^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -41,6 +44,7 @@ warning: panic message contains an unused formatting placeholder LL | core::panic!("Hello {}"); | ^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | @@ -57,6 +61,7 @@ warning: panic message contains unused formatting placeholders LL | assert!(false, "{:03x} {test} bla"); | ^^^^^^ ^^^^^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing arguments | @@ -73,6 +78,7 @@ warning: panic message is not a string literal LL | assert!(false, S); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -86,6 +92,7 @@ warning: panic message is not a string literal LL | assert!(false, 123); | ^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -99,6 +106,7 @@ warning: panic message is not a string literal LL | assert!(false, Some(123)); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `Option` @@ -112,6 +120,7 @@ warning: panic message contains braces LL | debug_assert!(false, "{{}} bla"); | ^^^^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -124,6 +133,7 @@ warning: panic message is not a string literal LL | panic!(C); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -137,6 +147,7 @@ warning: panic message is not a string literal LL | panic!(S); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -150,6 +161,7 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -163,6 +175,7 @@ warning: panic message is not a string literal LL | unreachable!(S); | ^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -176,6 +189,7 @@ warning: panic message is not a string literal LL | std::panic!(123); | ^^^ | + = note: for more information, see = note: this usage of `std::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -194,6 +208,7 @@ warning: panic message is not a string literal LL | core::panic!(&*"abc"); | ^^^^^^^ | + = note: for more information, see = note: this usage of `core::panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -207,6 +222,7 @@ warning: panic message is not a string literal LL | panic!(Some(123)); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `Option` @@ -225,6 +241,7 @@ warning: panic message contains an unused formatting placeholder LL | panic!(concat!("{", "}")); | ^^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | @@ -241,6 +258,7 @@ warning: panic message contains braces LL | panic!(concat!("{", "{")); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | @@ -253,6 +271,7 @@ warning: panic message contains an unused formatting placeholder LL | fancy_panic::fancy_panic!("test {} 123"); | ^^ | + = note: for more information, see = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 warning: panic message is not a string literal @@ -261,6 +280,7 @@ warning: panic message is not a string literal LL | panic!(a!()); | ^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -279,6 +299,7 @@ warning: panic message is not a string literal LL | unreachable!(a!()); | ^^^^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -292,6 +313,7 @@ warning: panic message is not a string literal LL | panic!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `panic!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -307,6 +329,7 @@ warning: panic message is not a string literal LL | unreachable!(format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `unreachable!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -322,6 +345,7 @@ warning: panic message is not a string literal LL | assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `assert!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -337,6 +361,7 @@ warning: panic message is not a string literal LL | debug_assert!(false, format!("{}", 1)); | ^^^^^^^^^^^^^^^^ | + = note: for more information, see = note: this usage of `debug_assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: the `debug_assert!()` macro supports formatting, so there's no need for the `format!()` macro here @@ -352,6 +377,7 @@ warning: panic message is not a string literal LL | panic![123]; | ^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -370,6 +396,7 @@ warning: panic message is not a string literal LL | panic!{123}; | ^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -390,6 +417,7 @@ LL | panic!(v); | | | help: use std::panic::panic_any instead: `std::panic::panic_any` | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see @@ -399,6 +427,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see @@ -408,6 +437,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `T` @@ -426,6 +456,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{:?}" format string to use the `Debug` implementation of `T` @@ -439,6 +470,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -457,6 +489,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -470,6 +503,7 @@ warning: panic message is not a string literal LL | panic!(v); | ^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message @@ -488,6 +522,7 @@ warning: panic message is not a string literal LL | assert!(false, v); | ^ | + = note: for more information, see = note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see help: add a "{}" format string to `Display` the message diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs index 27ead36f69d8..2c384bdb42ef 100644 --- a/tests/ui/macros/parse-complex-macro-invoc-op.rs +++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs @@ -3,14 +3,10 @@ #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unused_variables)] -#![allow(stable_features)] #![allow(dropping_copy_types)] // Test parsing binary operators after macro invocations. - -#![feature(macro_rules)] - macro_rules! id { ($e: expr) => { $e } } diff --git a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout index e29655faabe5..d47f733d40ed 100644 --- a/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout +++ b/tests/ui/macros/rfc-2011-nicer-assert-messages/non-consuming-methods-have-optimized-codegen.stdout @@ -5,7 +5,6 @@ //@ edition: 2015 #![feature(core_intrinsics, generic_assert)] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index fa06da5cbfbc..0367b8c2d023 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -5,6 +5,7 @@ #![allow(incomplete_features)] #![feature(auto_traits)] #![feature(box_patterns)] +#![feature(const_block_items)] #![feature(const_trait_impl)] #![feature(coroutines)] #![feature(decl_macro)] @@ -369,6 +370,9 @@ fn test_item() { c1!(item, [ pub const S: () = {}; ], "pub const S: () = {};"); c1!(item, [ const S: (); ], "const S: ();"); + // ItemKind::ConstBlock + c1!(item, [ const {} ], "const {}"); + // ItemKind::Fn c1!(item, [ pub default const async unsafe extern "C" fn f() {} ], diff --git a/tests/ui/macros/tokenstream-ice-issue-149954.rs b/tests/ui/macros/tokenstream-ice-issue-149954.rs new file mode 100644 index 000000000000..958a86cbde8b --- /dev/null +++ b/tests/ui/macros/tokenstream-ice-issue-149954.rs @@ -0,0 +1,22 @@ +// Regression test for ICE https://github.com/rust-lang/rust/issues/149954 +//@ edition: 2024 + +enum A { + A + const A: A = { //~ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found keyword `const` + #[derive(Debug)] + struct A + where + A: A<{ struct A> ; enum A } + //~^ ERROR malformed `cfg` attribute input + //~| ERROR malformed `cfg` attribute input + //~| ERROR expected trait, found struct `A` + //~| ERROR expected trait, found type parameter `A` + //~| ERROR expected trait, found struct `A` + //~| ERROR expected trait, found type parameter `A` + //~| ERROR expected one of `<`, `where`, or `{`, found `}` + //~| ERROR expected one of `<`, `where`, or `{`, found `}` + //~| ERROR expected one of `,`, `>`, or `}`, found `` + } + >; +}; //~ ERROR `main` function not found in crate diff --git a/tests/ui/macros/tokenstream-ice-issue-149954.stderr b/tests/ui/macros/tokenstream-ice-issue-149954.stderr new file mode 100644 index 000000000000..750f3efcc612 --- /dev/null +++ b/tests/ui/macros/tokenstream-ice-issue-149954.stderr @@ -0,0 +1,110 @@ +error: expected one of `(`, `,`, `=`, `{`, or `}`, found keyword `const` + --> $DIR/tokenstream-ice-issue-149954.rs:6:5 + | +LL | A + | - expected one of `(`, `,`, `=`, `{`, or `}` +LL | const A: A = { + | ^^^^^ unexpected token + | + = help: enum variants can be `Variant`, `Variant = `, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }` + +error: expected one of `<`, `where`, or `{`, found `}` + --> $DIR/tokenstream-ice-issue-149954.rs:10:60 + | +LL | A: A<{ struct A> ; enum A } + | - ^ expected one of `<`, `where`, or `{` + | | + | while parsing this enum + +error: expected one of `<`, `where`, or `{`, found `}` + --> $DIR/tokenstream-ice-issue-149954.rs:10:60 + | +LL | A: A<{ struct A> ; enum A } + | - ^ expected one of `<`, `where`, or `{` + | | + | while parsing this enum + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: expected one of `,`, `>`, or `}`, found `` + --> $DIR/tokenstream-ice-issue-149954.rs:10:60 + | +LL | A: A<{ struct A> ; enum A } + | ^ expected one of `,`, `>`, or `}` + | +help: you might have meant to end the type parameters here + | +LL | A: A<{ struct A> ; enum A }> + | + + +error[E0539]: malformed `cfg` attribute input + --> $DIR/tokenstream-ice-issue-149954.rs:10:36 + | +LL | A: A<{ struct A> ; enum A } + | ^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit + +error[E0539]: malformed `cfg` attribute input + --> $DIR/tokenstream-ice-issue-149954.rs:10:36 + | +LL | A: A<{ struct A> ; enum A } + | ^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0404]: expected trait, found struct `A` + --> $DIR/tokenstream-ice-issue-149954.rs:10:16 + | +LL | A: A<{ struct A> ; enum A } + | ________________^ +... | +LL | | >; + | |_________^ not a trait + +error[E0404]: expected trait, found type parameter `A` + --> $DIR/tokenstream-ice-issue-149954.rs:10:32 + | +LL | A: A<{ struct A> ; enum A } + | - ^^^^^^^^^^^^^^^^ not a trait + | | + | found this type parameter + +error[E0404]: expected trait, found struct `A` + --> $DIR/tokenstream-ice-issue-149954.rs:10:16 + | +LL | A: A<{ struct A> ; enum A } + | ________________^ +... | +LL | | >; + | |_________^ not a trait + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0404]: expected trait, found type parameter `A` + --> $DIR/tokenstream-ice-issue-149954.rs:10:32 + | +LL | A: A<{ struct A> ; enum A } + | - ^^^^^^^^^^^^^^^^ not a trait + | | + | found this type parameter + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0601]: `main` function not found in crate `tokenstream_ice_issue_149954` + --> $DIR/tokenstream-ice-issue-149954.rs:22:3 + | +LL | }; + | ^ consider adding a `main` function to `$DIR/tokenstream-ice-issue-149954.rs` + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0404, E0539, E0601. +For more information about an error, try `rustc --explain E0404`. diff --git a/tests/ui/macros/undefined-macro-in-impl.rs b/tests/ui/macros/undefined-macro-in-impl.rs new file mode 100644 index 000000000000..64b394f984be --- /dev/null +++ b/tests/ui/macros/undefined-macro-in-impl.rs @@ -0,0 +1,9 @@ +//! regression test for https://github.com/rust-lang/rust/issues/19734 +fn main() {} + +struct Type; + +impl Type { + undef!(); + //~^ ERROR cannot find macro `undef` in this scope +} diff --git a/tests/ui/macros/undefined-macro-in-impl.stderr b/tests/ui/macros/undefined-macro-in-impl.stderr new file mode 100644 index 000000000000..8d1bd958d7f6 --- /dev/null +++ b/tests/ui/macros/undefined-macro-in-impl.stderr @@ -0,0 +1,8 @@ +error: cannot find macro `undef` in this scope + --> $DIR/undefined-macro-in-impl.rs:7:5 + | +LL | undef!(); + | ^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/macros/vec-macro-in-pattern.rs b/tests/ui/macros/vec-macro-in-pattern.rs index 9b9a1edf54c9..0e9cb087f66a 100644 --- a/tests/ui/macros/vec-macro-in-pattern.rs +++ b/tests/ui/macros/vec-macro-in-pattern.rs @@ -6,7 +6,7 @@ fn main() { match Some(vec![42]) { Some(vec![43]) => {} //~ ERROR expected a pattern, found a function call //~| ERROR found associated function - //~| ERROR usage of qualified paths in this context is experimental + //~| ERROR expected a pattern, found a function call _ => {} } } diff --git a/tests/ui/macros/vec-macro-in-pattern.stderr b/tests/ui/macros/vec-macro-in-pattern.stderr index 71ba0ea5ad4f..38e4aebb8f48 100644 --- a/tests/ui/macros/vec-macro-in-pattern.stderr +++ b/tests/ui/macros/vec-macro-in-pattern.stderr @@ -5,29 +5,24 @@ LL | Some(vec![43]) => {} | ^^^^^^^^ not a tuple struct or tuple variant | = note: function calls are not allowed in patterns: - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0658]: usage of qualified paths in this context is experimental +error[E0532]: expected a pattern, found a function call --> $DIR/vec-macro-in-pattern.rs:7:14 | LL | Some(vec![43]) => {} - | ^^^^^^^^ + | ^^^^^^^^ not a tuple struct or tuple variant | - = note: see issue #86935 for more information - = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: function calls are not allowed in patterns: -error[E0164]: expected tuple struct or tuple variant, found associated function `<[_]>::into_vec` +error[E0164]: expected tuple struct or tuple variant, found associated function `::alloc::boxed::Box::new_uninit` --> $DIR/vec-macro-in-pattern.rs:7:14 | LL | Some(vec![43]) => {} | ^^^^^^^^ `fn` calls are not allowed in patterns | = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors -Some errors have detailed explanations: E0164, E0532, E0658. +Some errors have detailed explanations: E0164, E0532. For more information about an error, try `rustc --explain E0164`. diff --git a/tests/ui/macros/write-missing-destination.rs b/tests/ui/macros/write-missing-destination.rs new file mode 100644 index 000000000000..02e0e096a907 --- /dev/null +++ b/tests/ui/macros/write-missing-destination.rs @@ -0,0 +1,7 @@ +// Check that `write!` without a destination gives a helpful error message. +// See https://github.com/rust-lang/rust/issues/152493 + +fn main() { + write!("S"); + //~^ ERROR requires a destination and format arguments +} diff --git a/tests/ui/macros/write-missing-destination.stderr b/tests/ui/macros/write-missing-destination.stderr new file mode 100644 index 000000000000..3136191ca17a --- /dev/null +++ b/tests/ui/macros/write-missing-destination.stderr @@ -0,0 +1,8 @@ +error: requires a destination and format arguments, like `write!(dest, "format string", args...)` + --> $DIR/write-missing-destination.rs:5:5 + | +LL | write!("S"); + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/malformed/malformed-derive-entry.rs b/tests/ui/malformed/malformed-derive-entry.rs index 77fa2f566a8f..f9dc98d9d270 100644 --- a/tests/ui/malformed/malformed-derive-entry.rs +++ b/tests/ui/malformed/malformed-derive-entry.rs @@ -1,14 +1,14 @@ #[derive(Copy(Bad))] -//~^ ERROR traits in `#[derive(...)]` don't accept arguments -//~| ERROR the trait bound +//~^ ERROR: traits in `#[derive(...)]` don't accept arguments struct Test1; +//~^ ERROR: the trait bound #[derive(Copy="bad")] -//~^ ERROR traits in `#[derive(...)]` don't accept values -//~| ERROR the trait bound +//~^ ERROR: traits in `#[derive(...)]` don't accept values struct Test2; +//~^ ERROR: the trait bound -#[derive] //~ ERROR malformed `derive` attribute input +#[derive] //~ ERROR: malformed `derive` attribute input struct Test4; fn main() {} diff --git a/tests/ui/malformed/malformed-derive-entry.stderr b/tests/ui/malformed/malformed-derive-entry.stderr index 02036e8d4c90..a5d7c3a4f8aa 100644 --- a/tests/ui/malformed/malformed-derive-entry.stderr +++ b/tests/ui/malformed/malformed-derive-entry.stderr @@ -17,10 +17,13 @@ LL | #[derive] | ^^^^^^^^^ help: must be of the form: `#[derive(Trait1, Trait2, ...)]` error[E0277]: the trait bound `Test1: Clone` is not satisfied - --> $DIR/malformed-derive-entry.rs:1:10 + --> $DIR/malformed-derive-entry.rs:3:8 | LL | #[derive(Copy(Bad))] - | ^^^^ the trait `Clone` is not implemented for `Test1` + | ---- in this derive macro expansion +LL | +LL | struct Test1; + | ^^^^^ the trait `Clone` is not implemented for `Test1` | note: required by a bound in `Copy` --> $SRC_DIR/core/src/marker.rs:LL:COL @@ -31,10 +34,13 @@ LL | struct Test1; | error[E0277]: the trait bound `Test2: Clone` is not satisfied - --> $DIR/malformed-derive-entry.rs:6:10 + --> $DIR/malformed-derive-entry.rs:8:8 | LL | #[derive(Copy="bad")] - | ^^^^ the trait `Clone` is not implemented for `Test2` + | ---- in this derive macro expansion +LL | +LL | struct Test2; + | ^^^^^ the trait `Clone` is not implemented for `Test2` | note: required by a bound in `Copy` --> $SRC_DIR/core/src/marker.rs:LL:COL diff --git a/tests/ui/malformed/malformed-regressions.rs b/tests/ui/malformed/malformed-regressions.rs index c0f8c0d15bb8..63b918520ec0 100644 --- a/tests/ui/malformed/malformed-regressions.rs +++ b/tests/ui/malformed/malformed-regressions.rs @@ -1,5 +1,6 @@ +#![deny(invalid_doc_attributes)] + #[doc] //~ ERROR valid forms for the attribute are -//~^ WARN this was previously accepted #[ignore()] //~ ERROR valid forms for the attribute are //~^ WARN this was previously accepted #[inline = ""] //~ ERROR valid forms for the attribute are diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index 181207984877..283834a48552 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -1,58 +1,23 @@ -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-regressions.rs:1:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - error[E0539]: malformed `link` attribute input - --> $DIR/malformed-regressions.rs:7:1 + --> $DIR/malformed-regressions.rs:8:1 | LL | #[link] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | ++++++++++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | +++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link` attribute input - --> $DIR/malformed-regressions.rs:10:1 + --> $DIR/malformed-regressions.rs:11:1 | LL | #[link = ""] - | ^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^----^ + | | + | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link = ""] -LL + #[link(name = "...")] - | -LL - #[link = ""] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link = ""] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link = ""] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/malformed-regressions.rs:7:1 + --> $DIR/malformed-regressions.rs:8:1 | LL | #[link] | ^^^^^^^ @@ -63,17 +28,30 @@ LL | fn main() {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: requested on the command line with `-W unused-attributes` -error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` --> $DIR/malformed-regressions.rs:3:1 | +LL | #[doc] + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/malformed-regressions.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` + --> $DIR/malformed-regressions.rs:4:1 + | LL | #[ignore()] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-regressions.rs:5:1 + --> $DIR/malformed-regressions.rs:6:1 | LL | #[inline = ""] | ^^^^^^^^^^^^^^ @@ -85,20 +63,8 @@ error: aborting due to 5 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-regressions.rs:1:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-regressions.rs:3:1 + --> $DIR/malformed-regressions.rs:4:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -109,7 +75,7 @@ LL | #[ignore()] Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-regressions.rs:5:1 + --> $DIR/malformed-regressions.rs:6:1 | LL | #[inline = ""] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/malformed/malformed-special-attrs.rs b/tests/ui/malformed/malformed-special-attrs.rs index 05b7ebe46666..f0e66ef0f835 100644 --- a/tests/ui/malformed/malformed-special-attrs.rs +++ b/tests/ui/malformed/malformed-special-attrs.rs @@ -1,3 +1,5 @@ +#![deny(invalid_doc_attributes)] + #[cfg_attr] //~ ERROR malformed `cfg_attr` attribute struct S1; diff --git a/tests/ui/malformed/malformed-special-attrs.stderr b/tests/ui/malformed/malformed-special-attrs.stderr index 91e5939eb1f9..a2501d2aa398 100644 --- a/tests/ui/malformed/malformed-special-attrs.stderr +++ b/tests/ui/malformed/malformed-special-attrs.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-special-attrs.rs:1:1 + --> $DIR/malformed-special-attrs.rs:3:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg_attr] = note: for more information, visit error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-special-attrs.rs:4:1 + --> $DIR/malformed-special-attrs.rs:6:1 | LL | #[cfg_attr = ""] | ^^^^^^^^^^^^^^^^ @@ -21,13 +21,13 @@ LL | #[cfg_attr = ""] = note: for more information, visit error: malformed `derive` attribute input - --> $DIR/malformed-special-attrs.rs:7:1 + --> $DIR/malformed-special-attrs.rs:9:1 | LL | #[derive] | ^^^^^^^^^ help: must be of the form: `#[derive(Trait1, Trait2, ...)]` error: malformed `derive` attribute input - --> $DIR/malformed-special-attrs.rs:10:1 + --> $DIR/malformed-special-attrs.rs:12:1 | LL | #[derive = ""] | ^^^^^^^^^^^^^^ help: must be of the form: `#[derive(Trait1, Trait2, ...)]` diff --git a/tests/ui/match/borrowck-uninhabited.rs b/tests/ui/match/borrowck-uninhabited.rs new file mode 100644 index 000000000000..34f5e323a91e --- /dev/null +++ b/tests/ui/match/borrowck-uninhabited.rs @@ -0,0 +1,55 @@ +// See: rust-lang/rust#146590 + +enum Never {} + +// baseline +fn both_inhabited(x: &mut Result) { + match x { + &mut Ok(ref mut y) => match x { + //~^ ERROR: cannot use `*x` because it was mutably borrowed + &mut Err(ref mut z) => { + let _y = y; + let _z = z; + } + _ => {} + }, + _ => {} + }; +} + +// this used to be accepted, even though it shouldn't +fn ref_uninhabited(x: &mut Result) { + match x { + &mut Ok(ref mut y) => match x { + //~^ ERROR: cannot use `*x` because it was mutably borrowed + &mut Err(ref mut z) => { + let _y = y; + let _z = z; + } + _ => {} + }, + _ => {} + }; +} + +enum Single { + V(String, String), +} + +// arguably this should be rejected as well, but currently it is still accepted +fn single_variant(x: &mut Single) { + match x { + &mut Single::V(ref mut y, _) => { + match x { + &mut Single::V(_, ref mut z) => { + let _y = y; + let _z = z; + } + _ => {} + } + }, + _ => {} + }; +} + +fn main() {} diff --git a/tests/ui/match/borrowck-uninhabited.stderr b/tests/ui/match/borrowck-uninhabited.stderr new file mode 100644 index 000000000000..4bbe6ecea16b --- /dev/null +++ b/tests/ui/match/borrowck-uninhabited.stderr @@ -0,0 +1,25 @@ +error[E0503]: cannot use `*x` because it was mutably borrowed + --> $DIR/borrowck-uninhabited.rs:8:37 + | +LL | &mut Ok(ref mut y) => match x { + | --------- ^ use of borrowed `x.0` + | | + | `x.0` is borrowed here +... +LL | let _y = y; + | - borrow later used here + +error[E0503]: cannot use `*x` because it was mutably borrowed + --> $DIR/borrowck-uninhabited.rs:23:37 + | +LL | &mut Ok(ref mut y) => match x { + | --------- ^ use of borrowed `x.0` + | | + | `x.0` is borrowed here +... +LL | let _y = y; + | - borrow later used here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0503`. diff --git a/tests/ui/match/closure-in-match-guard.rs b/tests/ui/match/closure-in-match-guard.rs new file mode 100644 index 000000000000..c3f16dad4bfb --- /dev/null +++ b/tests/ui/match/closure-in-match-guard.rs @@ -0,0 +1,18 @@ +//! regression test for +//@ run-pass +//@ compile-flags:-g + +// In this test we just want to make sure that the code below does not lead to +// a debuginfo verification assertion during compilation. This was caused by the +// closure in the guard being codegened twice due to how match expressions are +// handled. +// +// See https://github.com/rust-lang/rust/issues/34569 for details. + +fn main() { + match 0 { + e if (|| { e == 0 })() => {}, + 1 => {}, + _ => {} + } +} diff --git a/tests/ui/match/issue-82392.stdout b/tests/ui/match/issue-82392.stdout index d7eef0497392..297a6f482790 100644 --- a/tests/ui/match/issue-82392.stdout +++ b/tests/ui/match/issue-82392.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; // https://github.com/rust-lang/rust/issues/82329 //@ compile-flags: -Zunpretty=hir,typed diff --git a/tests/ui/match/issue-92100.stderr b/tests/ui/match/issue-92100.stderr index eb9f4ba1ad69..13aacc4782af 100644 --- a/tests/ui/match/issue-92100.stderr +++ b/tests/ui/match/issue-92100.stderr @@ -4,10 +4,16 @@ error[E0425]: cannot find value `a` in this scope LL | [a.., a] => {} | ^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `a`, use the at operator | LL | [a @ .., a] => {} | + +help: if you meant to destructure a range use a struct pattern + | +LL - [a.., a] => {} +LL + [std::ops::RangeFrom { start: a }, a] => {} + | error: aborting due to 1 previous error diff --git a/tests/ui/match/large-match-mir-gen.rs b/tests/ui/match/large-match-mir-gen.rs new file mode 100644 index 000000000000..bb084a9ef0d0 --- /dev/null +++ b/tests/ui/match/large-match-mir-gen.rs @@ -0,0 +1,318 @@ +//! regression test for +//@ check-pass +#![allow(dead_code)] +// Inefficient MIR matching algorithms generated way +// too much code for this sort of case, leading to OOM. +#![allow(non_snake_case)] + +pub mod KeyboardEventConstants { + pub const DOM_KEY_LOCATION_STANDARD: u32 = 0; + pub const DOM_KEY_LOCATION_LEFT: u32 = 1; + pub const DOM_KEY_LOCATION_RIGHT: u32 = 2; + pub const DOM_KEY_LOCATION_NUMPAD: u32 = 3; +} // mod KeyboardEventConstants + +pub enum Key { + Space, + Apostrophe, + Comma, + Minus, + Period, + Slash, + Num0, + Num1, + Num2, + Num3, + Num4, + Num5, + Num6, + Num7, + Num8, + Num9, + Semicolon, + Equal, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + LeftBracket, + Backslash, + RightBracket, + GraveAccent, + World1, + World2, + + Escape, + Enter, + Tab, + Backspace, + Insert, + Delete, + Right, + Left, + Down, + Up, + PageUp, + PageDown, + Home, + End, + CapsLock, + ScrollLock, + NumLock, + PrintScreen, + Pause, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + F25, + Kp0, + Kp1, + Kp2, + Kp3, + Kp4, + Kp5, + Kp6, + Kp7, + Kp8, + Kp9, + KpDecimal, + KpDivide, + KpMultiply, + KpSubtract, + KpAdd, + KpEnter, + KpEqual, + LeftShift, + LeftControl, + LeftAlt, + LeftSuper, + RightShift, + RightControl, + RightAlt, + RightSuper, + Menu, +} + +fn key_from_string(key_string: &str, location: u32) -> Option { + match key_string { + " " => Some(Key::Space), + "\"" => Some(Key::Apostrophe), + "'" => Some(Key::Apostrophe), + "<" => Some(Key::Comma), + "," => Some(Key::Comma), + "_" => Some(Key::Minus), + "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Minus), + ">" => Some(Key::Period), + "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Period), + "?" => Some(Key::Slash), + "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Slash), + "~" => Some(Key::GraveAccent), + "`" => Some(Key::GraveAccent), + ")" => Some(Key::Num0), + "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num0), + "!" => Some(Key::Num1), + "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num1), + "@" => Some(Key::Num2), + "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num2), + "#" => Some(Key::Num3), + "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num3), + "$" => Some(Key::Num4), + "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num4), + "%" => Some(Key::Num5), + "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num5), + "^" => Some(Key::Num6), + "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num6), + "&" => Some(Key::Num7), + "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num7), + "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8), + "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num8), + "(" => Some(Key::Num9), + "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Num9), + ":" => Some(Key::Semicolon), + ";" => Some(Key::Semicolon), + "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal), + "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD => Some(Key::Equal), + "A" => Some(Key::A), + "a" => Some(Key::A), + "B" => Some(Key::B), + "b" => Some(Key::B), + "C" => Some(Key::C), + "c" => Some(Key::C), + "D" => Some(Key::D), + "d" => Some(Key::D), + "E" => Some(Key::E), + "e" => Some(Key::E), + "F" => Some(Key::F), + "f" => Some(Key::F), + "G" => Some(Key::G), + "g" => Some(Key::G), + "H" => Some(Key::H), + "h" => Some(Key::H), + "I" => Some(Key::I), + "i" => Some(Key::I), + "J" => Some(Key::J), + "j" => Some(Key::J), + "K" => Some(Key::K), + "k" => Some(Key::K), + "L" => Some(Key::L), + "l" => Some(Key::L), + "M" => Some(Key::M), + "m" => Some(Key::M), + "N" => Some(Key::N), + "n" => Some(Key::N), + "O" => Some(Key::O), + "o" => Some(Key::O), + "P" => Some(Key::P), + "p" => Some(Key::P), + "Q" => Some(Key::Q), + "q" => Some(Key::Q), + "R" => Some(Key::R), + "r" => Some(Key::R), + "S" => Some(Key::S), + "s" => Some(Key::S), + "T" => Some(Key::T), + "t" => Some(Key::T), + "U" => Some(Key::U), + "u" => Some(Key::U), + "V" => Some(Key::V), + "v" => Some(Key::V), + "W" => Some(Key::W), + "w" => Some(Key::W), + "X" => Some(Key::X), + "x" => Some(Key::X), + "Y" => Some(Key::Y), + "y" => Some(Key::Y), + "Z" => Some(Key::Z), + "z" => Some(Key::Z), + "{" => Some(Key::LeftBracket), + "[" => Some(Key::LeftBracket), + "|" => Some(Key::Backslash), + "\\" => Some(Key::Backslash), + "}" => Some(Key::RightBracket), + "]" => Some(Key::RightBracket), + "Escape" => Some(Key::Escape), + "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_STANDARD + => Some(Key::Enter), + "Tab" => Some(Key::Tab), + "Backspace" => Some(Key::Backspace), + "Insert" => Some(Key::Insert), + "Delete" => Some(Key::Delete), + "ArrowRight" => Some(Key::Right), + "ArrowLeft" => Some(Key::Left), + "ArrowDown" => Some(Key::Down), + "ArrowUp" => Some(Key::Up), + "PageUp" => Some(Key::PageUp), + "PageDown" => Some(Key::PageDown), + "Home" => Some(Key::Home), + "End" => Some(Key::End), + "CapsLock" => Some(Key::CapsLock), + "ScrollLock" => Some(Key::ScrollLock), + "NumLock" => Some(Key::NumLock), + "PrintScreen" => Some(Key::PrintScreen), + "Pause" => Some(Key::Pause), + "F1" => Some(Key::F1), + "F2" => Some(Key::F2), + "F3" => Some(Key::F3), + "F4" => Some(Key::F4), + "F5" => Some(Key::F5), + "F6" => Some(Key::F6), + "F7" => Some(Key::F7), + "F8" => Some(Key::F8), + "F9" => Some(Key::F9), + "F10" => Some(Key::F10), + "F11" => Some(Key::F11), + "F12" => Some(Key::F12), + "F13" => Some(Key::F13), + "F14" => Some(Key::F14), + "F15" => Some(Key::F15), + "F16" => Some(Key::F16), + "F17" => Some(Key::F17), + "F18" => Some(Key::F18), + "F19" => Some(Key::F19), + "F20" => Some(Key::F20), + "F21" => Some(Key::F21), + "F22" => Some(Key::F22), + "F23" => Some(Key::F23), + "F24" => Some(Key::F24), + "F25" => Some(Key::F25), + "0" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp0), + "1" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp1), + "2" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp2), + "3" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp3), + "4" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp4), + "5" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp5), + "6" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp6), + "7" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp7), + "8" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp8), + "9" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::Kp9), + "." if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDecimal), + "/" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpDivide), + "*" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpMultiply), + "-" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpSubtract), + "+" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpAdd), + "Enter" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD + => Some(Key::KpEnter), + "=" if location == KeyboardEventConstants::DOM_KEY_LOCATION_NUMPAD => Some(Key::KpEqual), + "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT + => Some(Key::LeftShift), + "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT + => Some(Key::LeftControl), + "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT => Some(Key::LeftAlt), + "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_LEFT + => Some(Key::LeftSuper), + "Shift" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT + => Some(Key::RightShift), + "Control" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT + => Some(Key::RightControl), + "Alt" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT => Some(Key::RightAlt), + "Super" if location == KeyboardEventConstants::DOM_KEY_LOCATION_RIGHT + => Some(Key::RightSuper), + "ContextMenu" => Some(Key::Menu), + _ => None + } +} + +fn main() { } diff --git a/tests/ui/match/match-const-tuple-type-mismatch.rs b/tests/ui/match/match-const-tuple-type-mismatch.rs new file mode 100644 index 000000000000..c9358e3d5faa --- /dev/null +++ b/tests/ui/match/match-const-tuple-type-mismatch.rs @@ -0,0 +1,13 @@ +//! Regression test for issue https://github.com/rust-lang/rust/issues/4968 +//@ dont-require-annotations: NOTE + +const A: (isize, isize) = (4, 2); +fn main() { + match 42 { + A => (), + //~^ ERROR mismatched types + //~| NOTE expected type `{integer}` + //~| NOTE found tuple `(isize, isize)` + //~| NOTE expected integer, found `(isize, isize)` + } +} diff --git a/tests/ui/match/match-const-tuple-type-mismatch.stderr b/tests/ui/match/match-const-tuple-type-mismatch.stderr new file mode 100644 index 000000000000..e7dd97c4e9a6 --- /dev/null +++ b/tests/ui/match/match-const-tuple-type-mismatch.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/match-const-tuple-type-mismatch.rs:7:9 + | +LL | const A: (isize, isize) = (4, 2); + | ----------------------- constant defined here +LL | fn main() { +LL | match 42 { + | -- this expression has type `{integer}` +LL | A => (), + | ^ + | | + | expected integer, found `(isize, isize)` + | `A` is interpreted as a constant, not a new binding + | help: introduce a new binding instead: `other_a` + | + = note: expected type `{integer}` + found tuple `(isize, isize)` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-float.rs b/tests/ui/match/match-float.rs index 70283eaeec52..279bb5927ac4 100644 --- a/tests/ui/match/match-float.rs +++ b/tests/ui/match/match-float.rs @@ -1,12 +1,12 @@ //@ run-pass +//@ compile-flags: --check-cfg=cfg(target_has_reliable_f16,target_has_reliable_f128) // Makes sure we use `==` (not bitwise) semantics for float comparison. +#![feature(cfg_target_has_reliable_f16_f128)] #![feature(f128)] #![feature(f16)] -// FIXME(f16_f128): remove gates when ABI issues are resolved - -#[cfg(all(target_arch = "aarch64", target_os = "linux"))] +#[cfg(target_has_reliable_f16)] fn check_f16() { const F1: f16 = 0.0; const F2: f16 = -0.0; @@ -34,7 +34,7 @@ fn check_f64() { assert!(matches!(F2, F1)); } -#[cfg(all(target_arch = "aarch64", target_os = "linux"))] +#[cfg(target_has_reliable_f128)] fn check_f128() { const F1: f128 = 0.0; const F2: f128 = -0.0; @@ -45,10 +45,10 @@ fn check_f128() { } fn main() { - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f16)] check_f16(); check_f32(); check_f64(); - #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + #[cfg(target_has_reliable_f128)] check_f128(); } diff --git a/tests/ui/match/match-large-array.rs b/tests/ui/match/match-large-array.rs new file mode 100644 index 000000000000..e72777c443c5 --- /dev/null +++ b/tests/ui/match/match-large-array.rs @@ -0,0 +1,14 @@ +//! regression test for +//@ run-pass + +fn main() { + assert_eq!(match [0u8; 1024] { + _ => 42_usize, + }, 42_usize); + + assert_eq!(match [0u8; 1024] { + [1, ..] => 0_usize, + [0, ..] => 1_usize, + _ => 2_usize + }, 1_usize); +} diff --git a/tests/ui/match/match-nested-enum-box-3121.rs b/tests/ui/match/match-nested-enum-box-3121.rs new file mode 100644 index 000000000000..f2ab4bf08075 --- /dev/null +++ b/tests/ui/match/match-nested-enum-box-3121.rs @@ -0,0 +1,37 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3121 + +//@ run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#[derive(Copy, Clone)] +enum side { + mayo, + catsup, + vinegar, +} +#[derive(Copy, Clone)] +enum order { + hamburger, + fries(side), + shake, +} +#[derive(Copy, Clone)] +enum meal { + to_go(order), + for_here(order), +} + +fn foo(m: Box, cond: bool) { + match *m { + meal::to_go(_) => {} + meal::for_here(_) if cond => {} + meal::for_here(order::hamburger) => {} + meal::for_here(order::fries(_s)) => {} + meal::for_here(order::shake) => {} + } +} + +pub fn main() { + foo(Box::new(meal::for_here(order::hamburger)), true) +} diff --git a/tests/ui/match/match-option-result-mismatch.rs b/tests/ui/match/match-option-result-mismatch.rs new file mode 100644 index 000000000000..e7c185cf09b8 --- /dev/null +++ b/tests/ui/match/match-option-result-mismatch.rs @@ -0,0 +1,12 @@ +//! regression test for + +fn main() { + match None { + //~^ NOTE this expression has type `Option<_>` + Err(_) => (), + //~^ ERROR mismatched types + //~| NOTE expected enum `Option<_>` + //~| NOTE found enum `Result<_, _>` + //~| NOTE expected `Option<_>`, found `Result<_, _>` + } +} diff --git a/tests/ui/match/match-option-result-mismatch.stderr b/tests/ui/match/match-option-result-mismatch.stderr new file mode 100644 index 000000000000..212d322fe2d9 --- /dev/null +++ b/tests/ui/match/match-option-result-mismatch.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/match-option-result-mismatch.rs:6:9 + | +LL | match None { + | ---- this expression has type `Option<_>` +LL | +LL | Err(_) => (), + | ^^^^^^ expected `Option<_>`, found `Result<_, _>` + | + = note: expected enum `Option<_>` + found enum `Result<_, _>` +help: try wrapping the pattern in `Some` + | +LL | Some(Err(_)) => (), + | +++++ + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/match-range-char-const.rs b/tests/ui/match/match-range-char-const.rs new file mode 100644 index 000000000000..84881fd56cc0 --- /dev/null +++ b/tests/ui/match/match-range-char-const.rs @@ -0,0 +1,13 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18464 +//@ run-pass +#![deny(dead_code)] + +const LOW_RANGE: char = '0'; +const HIGH_RANGE: char = '9'; + +fn main() { + match '5' { + LOW_RANGE..=HIGH_RANGE => (), + _ => (), + }; +} diff --git a/tests/ui/match/match-ref-option-pattern.rs b/tests/ui/match/match-ref-option-pattern.rs new file mode 100644 index 000000000000..a6de2361503a --- /dev/null +++ b/tests/ui/match/match-ref-option-pattern.rs @@ -0,0 +1,10 @@ +//! regression test for issue #3500 +//@ run-pass + +pub fn main() { + let x = &Some(1); + match x { + &Some(_) => (), + &None => (), + } +} diff --git a/tests/ui/match/match-stack-overflow-72933-.rs b/tests/ui/match/match-stack-overflow-72933-.rs new file mode 100644 index 000000000000..0883278be839 --- /dev/null +++ b/tests/ui/match/match-stack-overflow-72933-.rs @@ -0,0 +1,5209 @@ +//! regression test for issue #72933 +//@ build-pass +// ignore-tidy-filelength +#![crate_type = "rlib"] + +fn banana(v: &str) -> u32 { + match v { + "0" => 0, + "1" => 1, + "2" => 2, + "3" => 3, + "4" => 4, + "5" => 5, + "6" => 6, + "7" => 7, + "8" => 8, + "9" => 9, + "10" => 10, + "11" => 11, + "12" => 12, + "13" => 13, + "14" => 14, + "15" => 15, + "16" => 16, + "17" => 17, + "18" => 18, + "19" => 19, + "20" => 20, + "21" => 21, + "22" => 22, + "23" => 23, + "24" => 24, + "25" => 25, + "26" => 26, + "27" => 27, + "28" => 28, + "29" => 29, + "30" => 30, + "31" => 31, + "32" => 32, + "33" => 33, + "34" => 34, + "35" => 35, + "36" => 36, + "37" => 37, + "38" => 38, + "39" => 39, + "40" => 40, + "41" => 41, + "42" => 42, + "43" => 43, + "44" => 44, + "45" => 45, + "46" => 46, + "47" => 47, + "48" => 48, + "49" => 49, + "50" => 50, + "51" => 51, + "52" => 52, + "53" => 53, + "54" => 54, + "55" => 55, + "56" => 56, + "57" => 57, + "58" => 58, + "59" => 59, + "60" => 60, + "61" => 61, + "62" => 62, + "63" => 63, + "64" => 64, + "65" => 65, + "66" => 66, + "67" => 67, + "68" => 68, + "69" => 69, + "70" => 70, + "71" => 71, + "72" => 72, + "73" => 73, + "74" => 74, + "75" => 75, + "76" => 76, + "77" => 77, + "78" => 78, + "79" => 79, + "80" => 80, + "81" => 81, + "82" => 82, + "83" => 83, + "84" => 84, + "85" => 85, + "86" => 86, + "87" => 87, + "88" => 88, + "89" => 89, + "90" => 90, + "91" => 91, + "92" => 92, + "93" => 93, + "94" => 94, + "95" => 95, + "96" => 96, + "97" => 97, + "98" => 98, + "99" => 99, + "100" => 100, + "101" => 101, + "102" => 102, + "103" => 103, + "104" => 104, + "105" => 105, + "106" => 106, + "107" => 107, + "108" => 108, + "109" => 109, + "110" => 110, + "111" => 111, + "112" => 112, + "113" => 113, + "114" => 114, + "115" => 115, + "116" => 116, + "117" => 117, + "118" => 118, + "119" => 119, + "120" => 120, + "121" => 121, + "122" => 122, + "123" => 123, + "124" => 124, + "125" => 125, + "126" => 126, + "127" => 127, + "128" => 128, + "129" => 129, + "130" => 130, + "131" => 131, + "132" => 132, + "133" => 133, + "134" => 134, + "135" => 135, + "136" => 136, + "137" => 137, + "138" => 138, + "139" => 139, + "140" => 140, + "141" => 141, + "142" => 142, + "143" => 143, + "144" => 144, + "145" => 145, + "146" => 146, + "147" => 147, + "148" => 148, + "149" => 149, + "150" => 150, + "151" => 151, + "152" => 152, + "153" => 153, + "154" => 154, + "155" => 155, + "156" => 156, + "157" => 157, + "158" => 158, + "159" => 159, + "160" => 160, + "161" => 161, + "162" => 162, + "163" => 163, + "164" => 164, + "165" => 165, + "166" => 166, + "167" => 167, + "168" => 168, + "169" => 169, + "170" => 170, + "171" => 171, + "172" => 172, + "173" => 173, + "174" => 174, + "175" => 175, + "176" => 176, + "177" => 177, + "178" => 178, + "179" => 179, + "180" => 180, + "181" => 181, + "182" => 182, + "183" => 183, + "184" => 184, + "185" => 185, + "186" => 186, + "187" => 187, + "188" => 188, + "189" => 189, + "190" => 190, + "191" => 191, + "192" => 192, + "193" => 193, + "194" => 194, + "195" => 195, + "196" => 196, + "197" => 197, + "198" => 198, + "199" => 199, + "200" => 200, + "201" => 201, + "202" => 202, + "203" => 203, + "204" => 204, + "205" => 205, + "206" => 206, + "207" => 207, + "208" => 208, + "209" => 209, + "210" => 210, + "211" => 211, + "212" => 212, + "213" => 213, + "214" => 214, + "215" => 215, + "216" => 216, + "217" => 217, + "218" => 218, + "219" => 219, + "220" => 220, + "221" => 221, + "222" => 222, + "223" => 223, + "224" => 224, + "225" => 225, + "226" => 226, + "227" => 227, + "228" => 228, + "229" => 229, + "230" => 230, + "231" => 231, + "232" => 232, + "233" => 233, + "234" => 234, + "235" => 235, + "236" => 236, + "237" => 237, + "238" => 238, + "239" => 239, + "240" => 240, + "241" => 241, + "242" => 242, + "243" => 243, + "244" => 244, + "245" => 245, + "246" => 246, + "247" => 247, + "248" => 248, + "249" => 249, + "250" => 250, + "251" => 251, + "252" => 252, + "253" => 253, + "254" => 254, + "255" => 255, + "256" => 256, + "257" => 257, + "258" => 258, + "259" => 259, + "260" => 260, + "261" => 261, + "262" => 262, + "263" => 263, + "264" => 264, + "265" => 265, + "266" => 266, + "267" => 267, + "268" => 268, + "269" => 269, + "270" => 270, + "271" => 271, + "272" => 272, + "273" => 273, + "274" => 274, + "275" => 275, + "276" => 276, + "277" => 277, + "278" => 278, + "279" => 279, + "280" => 280, + "281" => 281, + "282" => 282, + "283" => 283, + "284" => 284, + "285" => 285, + "286" => 286, + "287" => 287, + "288" => 288, + "289" => 289, + "290" => 290, + "291" => 291, + "292" => 292, + "293" => 293, + "294" => 294, + "295" => 295, + "296" => 296, + "297" => 297, + "298" => 298, + "299" => 299, + "300" => 300, + "301" => 301, + "302" => 302, + "303" => 303, + "304" => 304, + "305" => 305, + "306" => 306, + "307" => 307, + "308" => 308, + "309" => 309, + "310" => 310, + "311" => 311, + "312" => 312, + "313" => 313, + "314" => 314, + "315" => 315, + "316" => 316, + "317" => 317, + "318" => 318, + "319" => 319, + "320" => 320, + "321" => 321, + "322" => 322, + "323" => 323, + "324" => 324, + "325" => 325, + "326" => 326, + "327" => 327, + "328" => 328, + "329" => 329, + "330" => 330, + "331" => 331, + "332" => 332, + "333" => 333, + "334" => 334, + "335" => 335, + "336" => 336, + "337" => 337, + "338" => 338, + "339" => 339, + "340" => 340, + "341" => 341, + "342" => 342, + "343" => 343, + "344" => 344, + "345" => 345, + "346" => 346, + "347" => 347, + "348" => 348, + "349" => 349, + "350" => 350, + "351" => 351, + "352" => 352, + "353" => 353, + "354" => 354, + "355" => 355, + "356" => 356, + "357" => 357, + "358" => 358, + "359" => 359, + "360" => 360, + "361" => 361, + "362" => 362, + "363" => 363, + "364" => 364, + "365" => 365, + "366" => 366, + "367" => 367, + "368" => 368, + "369" => 369, + "370" => 370, + "371" => 371, + "372" => 372, + "373" => 373, + "374" => 374, + "375" => 375, + "376" => 376, + "377" => 377, + "378" => 378, + "379" => 379, + "380" => 380, + "381" => 381, + "382" => 382, + "383" => 383, + "384" => 384, + "385" => 385, + "386" => 386, + "387" => 387, + "388" => 388, + "389" => 389, + "390" => 390, + "391" => 391, + "392" => 392, + "393" => 393, + "394" => 394, + "395" => 395, + "396" => 396, + "397" => 397, + "398" => 398, + "399" => 399, + "400" => 400, + "401" => 401, + "402" => 402, + "403" => 403, + "404" => 404, + "405" => 405, + "406" => 406, + "407" => 407, + "408" => 408, + "409" => 409, + "410" => 410, + "411" => 411, + "412" => 412, + "413" => 413, + "414" => 414, + "415" => 415, + "416" => 416, + "417" => 417, + "418" => 418, + "419" => 419, + "420" => 420, + "421" => 421, + "422" => 422, + "423" => 423, + "424" => 424, + "425" => 425, + "426" => 426, + "427" => 427, + "428" => 428, + "429" => 429, + "430" => 430, + "431" => 431, + "432" => 432, + "433" => 433, + "434" => 434, + "435" => 435, + "436" => 436, + "437" => 437, + "438" => 438, + "439" => 439, + "440" => 440, + "441" => 441, + "442" => 442, + "443" => 443, + "444" => 444, + "445" => 445, + "446" => 446, + "447" => 447, + "448" => 448, + "449" => 449, + "450" => 450, + "451" => 451, + "452" => 452, + "453" => 453, + "454" => 454, + "455" => 455, + "456" => 456, + "457" => 457, + "458" => 458, + "459" => 459, + "460" => 460, + "461" => 461, + "462" => 462, + "463" => 463, + "464" => 464, + "465" => 465, + "466" => 466, + "467" => 467, + "468" => 468, + "469" => 469, + "470" => 470, + "471" => 471, + "472" => 472, + "473" => 473, + "474" => 474, + "475" => 475, + "476" => 476, + "477" => 477, + "478" => 478, + "479" => 479, + "480" => 480, + "481" => 481, + "482" => 482, + "483" => 483, + "484" => 484, + "485" => 485, + "486" => 486, + "487" => 487, + "488" => 488, + "489" => 489, + "490" => 490, + "491" => 491, + "492" => 492, + "493" => 493, + "494" => 494, + "495" => 495, + "496" => 496, + "497" => 497, + "498" => 498, + "499" => 499, + "500" => 500, + "501" => 501, + "502" => 502, + "503" => 503, + "504" => 504, + "505" => 505, + "506" => 506, + "507" => 507, + "508" => 508, + "509" => 509, + "510" => 510, + "511" => 511, + "512" => 512, + "513" => 513, + "514" => 514, + "515" => 515, + "516" => 516, + "517" => 517, + "518" => 518, + "519" => 519, + "520" => 520, + "521" => 521, + "522" => 522, + "523" => 523, + "524" => 524, + "525" => 525, + "526" => 526, + "527" => 527, + "528" => 528, + "529" => 529, + "530" => 530, + "531" => 531, + "532" => 532, + "533" => 533, + "534" => 534, + "535" => 535, + "536" => 536, + "537" => 537, + "538" => 538, + "539" => 539, + "540" => 540, + "541" => 541, + "542" => 542, + "543" => 543, + "544" => 544, + "545" => 545, + "546" => 546, + "547" => 547, + "548" => 548, + "549" => 549, + "550" => 550, + "551" => 551, + "552" => 552, + "553" => 553, + "554" => 554, + "555" => 555, + "556" => 556, + "557" => 557, + "558" => 558, + "559" => 559, + "560" => 560, + "561" => 561, + "562" => 562, + "563" => 563, + "564" => 564, + "565" => 565, + "566" => 566, + "567" => 567, + "568" => 568, + "569" => 569, + "570" => 570, + "571" => 571, + "572" => 572, + "573" => 573, + "574" => 574, + "575" => 575, + "576" => 576, + "577" => 577, + "578" => 578, + "579" => 579, + "580" => 580, + "581" => 581, + "582" => 582, + "583" => 583, + "584" => 584, + "585" => 585, + "586" => 586, + "587" => 587, + "588" => 588, + "589" => 589, + "590" => 590, + "591" => 591, + "592" => 592, + "593" => 593, + "594" => 594, + "595" => 595, + "596" => 596, + "597" => 597, + "598" => 598, + "599" => 599, + "600" => 600, + "601" => 601, + "602" => 602, + "603" => 603, + "604" => 604, + "605" => 605, + "606" => 606, + "607" => 607, + "608" => 608, + "609" => 609, + "610" => 610, + "611" => 611, + "612" => 612, + "613" => 613, + "614" => 614, + "615" => 615, + "616" => 616, + "617" => 617, + "618" => 618, + "619" => 619, + "620" => 620, + "621" => 621, + "622" => 622, + "623" => 623, + "624" => 624, + "625" => 625, + "626" => 626, + "627" => 627, + "628" => 628, + "629" => 629, + "630" => 630, + "631" => 631, + "632" => 632, + "633" => 633, + "634" => 634, + "635" => 635, + "636" => 636, + "637" => 637, + "638" => 638, + "639" => 639, + "640" => 640, + "641" => 641, + "642" => 642, + "643" => 643, + "644" => 644, + "645" => 645, + "646" => 646, + "647" => 647, + "648" => 648, + "649" => 649, + "650" => 650, + "651" => 651, + "652" => 652, + "653" => 653, + "654" => 654, + "655" => 655, + "656" => 656, + "657" => 657, + "658" => 658, + "659" => 659, + "660" => 660, + "661" => 661, + "662" => 662, + "663" => 663, + "664" => 664, + "665" => 665, + "666" => 666, + "667" => 667, + "668" => 668, + "669" => 669, + "670" => 670, + "671" => 671, + "672" => 672, + "673" => 673, + "674" => 674, + "675" => 675, + "676" => 676, + "677" => 677, + "678" => 678, + "679" => 679, + "680" => 680, + "681" => 681, + "682" => 682, + "683" => 683, + "684" => 684, + "685" => 685, + "686" => 686, + "687" => 687, + "688" => 688, + "689" => 689, + "690" => 690, + "691" => 691, + "692" => 692, + "693" => 693, + "694" => 694, + "695" => 695, + "696" => 696, + "697" => 697, + "698" => 698, + "699" => 699, + "700" => 700, + "701" => 701, + "702" => 702, + "703" => 703, + "704" => 704, + "705" => 705, + "706" => 706, + "707" => 707, + "708" => 708, + "709" => 709, + "710" => 710, + "711" => 711, + "712" => 712, + "713" => 713, + "714" => 714, + "715" => 715, + "716" => 716, + "717" => 717, + "718" => 718, + "719" => 719, + "720" => 720, + "721" => 721, + "722" => 722, + "723" => 723, + "724" => 724, + "725" => 725, + "726" => 726, + "727" => 727, + "728" => 728, + "729" => 729, + "730" => 730, + "731" => 731, + "732" => 732, + "733" => 733, + "734" => 734, + "735" => 735, + "736" => 736, + "737" => 737, + "738" => 738, + "739" => 739, + "740" => 740, + "741" => 741, + "742" => 742, + "743" => 743, + "744" => 744, + "745" => 745, + "746" => 746, + "747" => 747, + "748" => 748, + "749" => 749, + "750" => 750, + "751" => 751, + "752" => 752, + "753" => 753, + "754" => 754, + "755" => 755, + "756" => 756, + "757" => 757, + "758" => 758, + "759" => 759, + "760" => 760, + "761" => 761, + "762" => 762, + "763" => 763, + "764" => 764, + "765" => 765, + "766" => 766, + "767" => 767, + "768" => 768, + "769" => 769, + "770" => 770, + "771" => 771, + "772" => 772, + "773" => 773, + "774" => 774, + "775" => 775, + "776" => 776, + "777" => 777, + "778" => 778, + "779" => 779, + "780" => 780, + "781" => 781, + "782" => 782, + "783" => 783, + "784" => 784, + "785" => 785, + "786" => 786, + "787" => 787, + "788" => 788, + "789" => 789, + "790" => 790, + "791" => 791, + "792" => 792, + "793" => 793, + "794" => 794, + "795" => 795, + "796" => 796, + "797" => 797, + "798" => 798, + "799" => 799, + "800" => 800, + "801" => 801, + "802" => 802, + "803" => 803, + "804" => 804, + "805" => 805, + "806" => 806, + "807" => 807, + "808" => 808, + "809" => 809, + "810" => 810, + "811" => 811, + "812" => 812, + "813" => 813, + "814" => 814, + "815" => 815, + "816" => 816, + "817" => 817, + "818" => 818, + "819" => 819, + "820" => 820, + "821" => 821, + "822" => 822, + "823" => 823, + "824" => 824, + "825" => 825, + "826" => 826, + "827" => 827, + "828" => 828, + "829" => 829, + "830" => 830, + "831" => 831, + "832" => 832, + "833" => 833, + "834" => 834, + "835" => 835, + "836" => 836, + "837" => 837, + "838" => 838, + "839" => 839, + "840" => 840, + "841" => 841, + "842" => 842, + "843" => 843, + "844" => 844, + "845" => 845, + "846" => 846, + "847" => 847, + "848" => 848, + "849" => 849, + "850" => 850, + "851" => 851, + "852" => 852, + "853" => 853, + "854" => 854, + "855" => 855, + "856" => 856, + "857" => 857, + "858" => 858, + "859" => 859, + "860" => 860, + "861" => 861, + "862" => 862, + "863" => 863, + "864" => 864, + "865" => 865, + "866" => 866, + "867" => 867, + "868" => 868, + "869" => 869, + "870" => 870, + "871" => 871, + "872" => 872, + "873" => 873, + "874" => 874, + "875" => 875, + "876" => 876, + "877" => 877, + "878" => 878, + "879" => 879, + "880" => 880, + "881" => 881, + "882" => 882, + "883" => 883, + "884" => 884, + "885" => 885, + "886" => 886, + "887" => 887, + "888" => 888, + "889" => 889, + "890" => 890, + "891" => 891, + "892" => 892, + "893" => 893, + "894" => 894, + "895" => 895, + "896" => 896, + "897" => 897, + "898" => 898, + "899" => 899, + "900" => 900, + "901" => 901, + "902" => 902, + "903" => 903, + "904" => 904, + "905" => 905, + "906" => 906, + "907" => 907, + "908" => 908, + "909" => 909, + "910" => 910, + "911" => 911, + "912" => 912, + "913" => 913, + "914" => 914, + "915" => 915, + "916" => 916, + "917" => 917, + "918" => 918, + "919" => 919, + "920" => 920, + "921" => 921, + "922" => 922, + "923" => 923, + "924" => 924, + "925" => 925, + "926" => 926, + "927" => 927, + "928" => 928, + "929" => 929, + "930" => 930, + "931" => 931, + "932" => 932, + "933" => 933, + "934" => 934, + "935" => 935, + "936" => 936, + "937" => 937, + "938" => 938, + "939" => 939, + "940" => 940, + "941" => 941, + "942" => 942, + "943" => 943, + "944" => 944, + "945" => 945, + "946" => 946, + "947" => 947, + "948" => 948, + "949" => 949, + "950" => 950, + "951" => 951, + "952" => 952, + "953" => 953, + "954" => 954, + "955" => 955, + "956" => 956, + "957" => 957, + "958" => 958, + "959" => 959, + "960" => 960, + "961" => 961, + "962" => 962, + "963" => 963, + "964" => 964, + "965" => 965, + "966" => 966, + "967" => 967, + "968" => 968, + "969" => 969, + "970" => 970, + "971" => 971, + "972" => 972, + "973" => 973, + "974" => 974, + "975" => 975, + "976" => 976, + "977" => 977, + "978" => 978, + "979" => 979, + "980" => 980, + "981" => 981, + "982" => 982, + "983" => 983, + "984" => 984, + "985" => 985, + "986" => 986, + "987" => 987, + "988" => 988, + "989" => 989, + "990" => 990, + "991" => 991, + "992" => 992, + "993" => 993, + "994" => 994, + "995" => 995, + "996" => 996, + "997" => 997, + "998" => 998, + "999" => 999, + "1000" => 1000, + "1001" => 1001, + "1002" => 1002, + "1003" => 1003, + "1004" => 1004, + "1005" => 1005, + "1006" => 1006, + "1007" => 1007, + "1008" => 1008, + "1009" => 1009, + "1010" => 1010, + "1011" => 1011, + "1012" => 1012, + "1013" => 1013, + "1014" => 1014, + "1015" => 1015, + "1016" => 1016, + "1017" => 1017, + "1018" => 1018, + "1019" => 1019, + "1020" => 1020, + "1021" => 1021, + "1022" => 1022, + "1023" => 1023, + "1024" => 1024, + "1025" => 1025, + "1026" => 1026, + "1027" => 1027, + "1028" => 1028, + "1029" => 1029, + "1030" => 1030, + "1031" => 1031, + "1032" => 1032, + "1033" => 1033, + "1034" => 1034, + "1035" => 1035, + "1036" => 1036, + "1037" => 1037, + "1038" => 1038, + "1039" => 1039, + "1040" => 1040, + "1041" => 1041, + "1042" => 1042, + "1043" => 1043, + "1044" => 1044, + "1045" => 1045, + "1046" => 1046, + "1047" => 1047, + "1048" => 1048, + "1049" => 1049, + "1050" => 1050, + "1051" => 1051, + "1052" => 1052, + "1053" => 1053, + "1054" => 1054, + "1055" => 1055, + "1056" => 1056, + "1057" => 1057, + "1058" => 1058, + "1059" => 1059, + "1060" => 1060, + "1061" => 1061, + "1062" => 1062, + "1063" => 1063, + "1064" => 1064, + "1065" => 1065, + "1066" => 1066, + "1067" => 1067, + "1068" => 1068, + "1069" => 1069, + "1070" => 1070, + "1071" => 1071, + "1072" => 1072, + "1073" => 1073, + "1074" => 1074, + "1075" => 1075, + "1076" => 1076, + "1077" => 1077, + "1078" => 1078, + "1079" => 1079, + "1080" => 1080, + "1081" => 1081, + "1082" => 1082, + "1083" => 1083, + "1084" => 1084, + "1085" => 1085, + "1086" => 1086, + "1087" => 1087, + "1088" => 1088, + "1089" => 1089, + "1090" => 1090, + "1091" => 1091, + "1092" => 1092, + "1093" => 1093, + "1094" => 1094, + "1095" => 1095, + "1096" => 1096, + "1097" => 1097, + "1098" => 1098, + "1099" => 1099, + "1100" => 1100, + "1101" => 1101, + "1102" => 1102, + "1103" => 1103, + "1104" => 1104, + "1105" => 1105, + "1106" => 1106, + "1107" => 1107, + "1108" => 1108, + "1109" => 1109, + "1110" => 1110, + "1111" => 1111, + "1112" => 1112, + "1113" => 1113, + "1114" => 1114, + "1115" => 1115, + "1116" => 1116, + "1117" => 1117, + "1118" => 1118, + "1119" => 1119, + "1120" => 1120, + "1121" => 1121, + "1122" => 1122, + "1123" => 1123, + "1124" => 1124, + "1125" => 1125, + "1126" => 1126, + "1127" => 1127, + "1128" => 1128, + "1129" => 1129, + "1130" => 1130, + "1131" => 1131, + "1132" => 1132, + "1133" => 1133, + "1134" => 1134, + "1135" => 1135, + "1136" => 1136, + "1137" => 1137, + "1138" => 1138, + "1139" => 1139, + "1140" => 1140, + "1141" => 1141, + "1142" => 1142, + "1143" => 1143, + "1144" => 1144, + "1145" => 1145, + "1146" => 1146, + "1147" => 1147, + "1148" => 1148, + "1149" => 1149, + "1150" => 1150, + "1151" => 1151, + "1152" => 1152, + "1153" => 1153, + "1154" => 1154, + "1155" => 1155, + "1156" => 1156, + "1157" => 1157, + "1158" => 1158, + "1159" => 1159, + "1160" => 1160, + "1161" => 1161, + "1162" => 1162, + "1163" => 1163, + "1164" => 1164, + "1165" => 1165, + "1166" => 1166, + "1167" => 1167, + "1168" => 1168, + "1169" => 1169, + "1170" => 1170, + "1171" => 1171, + "1172" => 1172, + "1173" => 1173, + "1174" => 1174, + "1175" => 1175, + "1176" => 1176, + "1177" => 1177, + "1178" => 1178, + "1179" => 1179, + "1180" => 1180, + "1181" => 1181, + "1182" => 1182, + "1183" => 1183, + "1184" => 1184, + "1185" => 1185, + "1186" => 1186, + "1187" => 1187, + "1188" => 1188, + "1189" => 1189, + "1190" => 1190, + "1191" => 1191, + "1192" => 1192, + "1193" => 1193, + "1194" => 1194, + "1195" => 1195, + "1196" => 1196, + "1197" => 1197, + "1198" => 1198, + "1199" => 1199, + "1200" => 1200, + "1201" => 1201, + "1202" => 1202, + "1203" => 1203, + "1204" => 1204, + "1205" => 1205, + "1206" => 1206, + "1207" => 1207, + "1208" => 1208, + "1209" => 1209, + "1210" => 1210, + "1211" => 1211, + "1212" => 1212, + "1213" => 1213, + "1214" => 1214, + "1215" => 1215, + "1216" => 1216, + "1217" => 1217, + "1218" => 1218, + "1219" => 1219, + "1220" => 1220, + "1221" => 1221, + "1222" => 1222, + "1223" => 1223, + "1224" => 1224, + "1225" => 1225, + "1226" => 1226, + "1227" => 1227, + "1228" => 1228, + "1229" => 1229, + "1230" => 1230, + "1231" => 1231, + "1232" => 1232, + "1233" => 1233, + "1234" => 1234, + "1235" => 1235, + "1236" => 1236, + "1237" => 1237, + "1238" => 1238, + "1239" => 1239, + "1240" => 1240, + "1241" => 1241, + "1242" => 1242, + "1243" => 1243, + "1244" => 1244, + "1245" => 1245, + "1246" => 1246, + "1247" => 1247, + "1248" => 1248, + "1249" => 1249, + "1250" => 1250, + "1251" => 1251, + "1252" => 1252, + "1253" => 1253, + "1254" => 1254, + "1255" => 1255, + "1256" => 1256, + "1257" => 1257, + "1258" => 1258, + "1259" => 1259, + "1260" => 1260, + "1261" => 1261, + "1262" => 1262, + "1263" => 1263, + "1264" => 1264, + "1265" => 1265, + "1266" => 1266, + "1267" => 1267, + "1268" => 1268, + "1269" => 1269, + "1270" => 1270, + "1271" => 1271, + "1272" => 1272, + "1273" => 1273, + "1274" => 1274, + "1275" => 1275, + "1276" => 1276, + "1277" => 1277, + "1278" => 1278, + "1279" => 1279, + "1280" => 1280, + "1281" => 1281, + "1282" => 1282, + "1283" => 1283, + "1284" => 1284, + "1285" => 1285, + "1286" => 1286, + "1287" => 1287, + "1288" => 1288, + "1289" => 1289, + "1290" => 1290, + "1291" => 1291, + "1292" => 1292, + "1293" => 1293, + "1294" => 1294, + "1295" => 1295, + "1296" => 1296, + "1297" => 1297, + "1298" => 1298, + "1299" => 1299, + "1300" => 1300, + "1301" => 1301, + "1302" => 1302, + "1303" => 1303, + "1304" => 1304, + "1305" => 1305, + "1306" => 1306, + "1307" => 1307, + "1308" => 1308, + "1309" => 1309, + "1310" => 1310, + "1311" => 1311, + "1312" => 1312, + "1313" => 1313, + "1314" => 1314, + "1315" => 1315, + "1316" => 1316, + "1317" => 1317, + "1318" => 1318, + "1319" => 1319, + "1320" => 1320, + "1321" => 1321, + "1322" => 1322, + "1323" => 1323, + "1324" => 1324, + "1325" => 1325, + "1326" => 1326, + "1327" => 1327, + "1328" => 1328, + "1329" => 1329, + "1330" => 1330, + "1331" => 1331, + "1332" => 1332, + "1333" => 1333, + "1334" => 1334, + "1335" => 1335, + "1336" => 1336, + "1337" => 1337, + "1338" => 1338, + "1339" => 1339, + "1340" => 1340, + "1341" => 1341, + "1342" => 1342, + "1343" => 1343, + "1344" => 1344, + "1345" => 1345, + "1346" => 1346, + "1347" => 1347, + "1348" => 1348, + "1349" => 1349, + "1350" => 1350, + "1351" => 1351, + "1352" => 1352, + "1353" => 1353, + "1354" => 1354, + "1355" => 1355, + "1356" => 1356, + "1357" => 1357, + "1358" => 1358, + "1359" => 1359, + "1360" => 1360, + "1361" => 1361, + "1362" => 1362, + "1363" => 1363, + "1364" => 1364, + "1365" => 1365, + "1366" => 1366, + "1367" => 1367, + "1368" => 1368, + "1369" => 1369, + "1370" => 1370, + "1371" => 1371, + "1372" => 1372, + "1373" => 1373, + "1374" => 1374, + "1375" => 1375, + "1376" => 1376, + "1377" => 1377, + "1378" => 1378, + "1379" => 1379, + "1380" => 1380, + "1381" => 1381, + "1382" => 1382, + "1383" => 1383, + "1384" => 1384, + "1385" => 1385, + "1386" => 1386, + "1387" => 1387, + "1388" => 1388, + "1389" => 1389, + "1390" => 1390, + "1391" => 1391, + "1392" => 1392, + "1393" => 1393, + "1394" => 1394, + "1395" => 1395, + "1396" => 1396, + "1397" => 1397, + "1398" => 1398, + "1399" => 1399, + "1400" => 1400, + "1401" => 1401, + "1402" => 1402, + "1403" => 1403, + "1404" => 1404, + "1405" => 1405, + "1406" => 1406, + "1407" => 1407, + "1408" => 1408, + "1409" => 1409, + "1410" => 1410, + "1411" => 1411, + "1412" => 1412, + "1413" => 1413, + "1414" => 1414, + "1415" => 1415, + "1416" => 1416, + "1417" => 1417, + "1418" => 1418, + "1419" => 1419, + "1420" => 1420, + "1421" => 1421, + "1422" => 1422, + "1423" => 1423, + "1424" => 1424, + "1425" => 1425, + "1426" => 1426, + "1427" => 1427, + "1428" => 1428, + "1429" => 1429, + "1430" => 1430, + "1431" => 1431, + "1432" => 1432, + "1433" => 1433, + "1434" => 1434, + "1435" => 1435, + "1436" => 1436, + "1437" => 1437, + "1438" => 1438, + "1439" => 1439, + "1440" => 1440, + "1441" => 1441, + "1442" => 1442, + "1443" => 1443, + "1444" => 1444, + "1445" => 1445, + "1446" => 1446, + "1447" => 1447, + "1448" => 1448, + "1449" => 1449, + "1450" => 1450, + "1451" => 1451, + "1452" => 1452, + "1453" => 1453, + "1454" => 1454, + "1455" => 1455, + "1456" => 1456, + "1457" => 1457, + "1458" => 1458, + "1459" => 1459, + "1460" => 1460, + "1461" => 1461, + "1462" => 1462, + "1463" => 1463, + "1464" => 1464, + "1465" => 1465, + "1466" => 1466, + "1467" => 1467, + "1468" => 1468, + "1469" => 1469, + "1470" => 1470, + "1471" => 1471, + "1472" => 1472, + "1473" => 1473, + "1474" => 1474, + "1475" => 1475, + "1476" => 1476, + "1477" => 1477, + "1478" => 1478, + "1479" => 1479, + "1480" => 1480, + "1481" => 1481, + "1482" => 1482, + "1483" => 1483, + "1484" => 1484, + "1485" => 1485, + "1486" => 1486, + "1487" => 1487, + "1488" => 1488, + "1489" => 1489, + "1490" => 1490, + "1491" => 1491, + "1492" => 1492, + "1493" => 1493, + "1494" => 1494, + "1495" => 1495, + "1496" => 1496, + "1497" => 1497, + "1498" => 1498, + "1499" => 1499, + "1500" => 1500, + "1501" => 1501, + "1502" => 1502, + "1503" => 1503, + "1504" => 1504, + "1505" => 1505, + "1506" => 1506, + "1507" => 1507, + "1508" => 1508, + "1509" => 1509, + "1510" => 1510, + "1511" => 1511, + "1512" => 1512, + "1513" => 1513, + "1514" => 1514, + "1515" => 1515, + "1516" => 1516, + "1517" => 1517, + "1518" => 1518, + "1519" => 1519, + "1520" => 1520, + "1521" => 1521, + "1522" => 1522, + "1523" => 1523, + "1524" => 1524, + "1525" => 1525, + "1526" => 1526, + "1527" => 1527, + "1528" => 1528, + "1529" => 1529, + "1530" => 1530, + "1531" => 1531, + "1532" => 1532, + "1533" => 1533, + "1534" => 1534, + "1535" => 1535, + "1536" => 1536, + "1537" => 1537, + "1538" => 1538, + "1539" => 1539, + "1540" => 1540, + "1541" => 1541, + "1542" => 1542, + "1543" => 1543, + "1544" => 1544, + "1545" => 1545, + "1546" => 1546, + "1547" => 1547, + "1548" => 1548, + "1549" => 1549, + "1550" => 1550, + "1551" => 1551, + "1552" => 1552, + "1553" => 1553, + "1554" => 1554, + "1555" => 1555, + "1556" => 1556, + "1557" => 1557, + "1558" => 1558, + "1559" => 1559, + "1560" => 1560, + "1561" => 1561, + "1562" => 1562, + "1563" => 1563, + "1564" => 1564, + "1565" => 1565, + "1566" => 1566, + "1567" => 1567, + "1568" => 1568, + "1569" => 1569, + "1570" => 1570, + "1571" => 1571, + "1572" => 1572, + "1573" => 1573, + "1574" => 1574, + "1575" => 1575, + "1576" => 1576, + "1577" => 1577, + "1578" => 1578, + "1579" => 1579, + "1580" => 1580, + "1581" => 1581, + "1582" => 1582, + "1583" => 1583, + "1584" => 1584, + "1585" => 1585, + "1586" => 1586, + "1587" => 1587, + "1588" => 1588, + "1589" => 1589, + "1590" => 1590, + "1591" => 1591, + "1592" => 1592, + "1593" => 1593, + "1594" => 1594, + "1595" => 1595, + "1596" => 1596, + "1597" => 1597, + "1598" => 1598, + "1599" => 1599, + "1600" => 1600, + "1601" => 1601, + "1602" => 1602, + "1603" => 1603, + "1604" => 1604, + "1605" => 1605, + "1606" => 1606, + "1607" => 1607, + "1608" => 1608, + "1609" => 1609, + "1610" => 1610, + "1611" => 1611, + "1612" => 1612, + "1613" => 1613, + "1614" => 1614, + "1615" => 1615, + "1616" => 1616, + "1617" => 1617, + "1618" => 1618, + "1619" => 1619, + "1620" => 1620, + "1621" => 1621, + "1622" => 1622, + "1623" => 1623, + "1624" => 1624, + "1625" => 1625, + "1626" => 1626, + "1627" => 1627, + "1628" => 1628, + "1629" => 1629, + "1630" => 1630, + "1631" => 1631, + "1632" => 1632, + "1633" => 1633, + "1634" => 1634, + "1635" => 1635, + "1636" => 1636, + "1637" => 1637, + "1638" => 1638, + "1639" => 1639, + "1640" => 1640, + "1641" => 1641, + "1642" => 1642, + "1643" => 1643, + "1644" => 1644, + "1645" => 1645, + "1646" => 1646, + "1647" => 1647, + "1648" => 1648, + "1649" => 1649, + "1650" => 1650, + "1651" => 1651, + "1652" => 1652, + "1653" => 1653, + "1654" => 1654, + "1655" => 1655, + "1656" => 1656, + "1657" => 1657, + "1658" => 1658, + "1659" => 1659, + "1660" => 1660, + "1661" => 1661, + "1662" => 1662, + "1663" => 1663, + "1664" => 1664, + "1665" => 1665, + "1666" => 1666, + "1667" => 1667, + "1668" => 1668, + "1669" => 1669, + "1670" => 1670, + "1671" => 1671, + "1672" => 1672, + "1673" => 1673, + "1674" => 1674, + "1675" => 1675, + "1676" => 1676, + "1677" => 1677, + "1678" => 1678, + "1679" => 1679, + "1680" => 1680, + "1681" => 1681, + "1682" => 1682, + "1683" => 1683, + "1684" => 1684, + "1685" => 1685, + "1686" => 1686, + "1687" => 1687, + "1688" => 1688, + "1689" => 1689, + "1690" => 1690, + "1691" => 1691, + "1692" => 1692, + "1693" => 1693, + "1694" => 1694, + "1695" => 1695, + "1696" => 1696, + "1697" => 1697, + "1698" => 1698, + "1699" => 1699, + "1700" => 1700, + "1701" => 1701, + "1702" => 1702, + "1703" => 1703, + "1704" => 1704, + "1705" => 1705, + "1706" => 1706, + "1707" => 1707, + "1708" => 1708, + "1709" => 1709, + "1710" => 1710, + "1711" => 1711, + "1712" => 1712, + "1713" => 1713, + "1714" => 1714, + "1715" => 1715, + "1716" => 1716, + "1717" => 1717, + "1718" => 1718, + "1719" => 1719, + "1720" => 1720, + "1721" => 1721, + "1722" => 1722, + "1723" => 1723, + "1724" => 1724, + "1725" => 1725, + "1726" => 1726, + "1727" => 1727, + "1728" => 1728, + "1729" => 1729, + "1730" => 1730, + "1731" => 1731, + "1732" => 1732, + "1733" => 1733, + "1734" => 1734, + "1735" => 1735, + "1736" => 1736, + "1737" => 1737, + "1738" => 1738, + "1739" => 1739, + "1740" => 1740, + "1741" => 1741, + "1742" => 1742, + "1743" => 1743, + "1744" => 1744, + "1745" => 1745, + "1746" => 1746, + "1747" => 1747, + "1748" => 1748, + "1749" => 1749, + "1750" => 1750, + "1751" => 1751, + "1752" => 1752, + "1753" => 1753, + "1754" => 1754, + "1755" => 1755, + "1756" => 1756, + "1757" => 1757, + "1758" => 1758, + "1759" => 1759, + "1760" => 1760, + "1761" => 1761, + "1762" => 1762, + "1763" => 1763, + "1764" => 1764, + "1765" => 1765, + "1766" => 1766, + "1767" => 1767, + "1768" => 1768, + "1769" => 1769, + "1770" => 1770, + "1771" => 1771, + "1772" => 1772, + "1773" => 1773, + "1774" => 1774, + "1775" => 1775, + "1776" => 1776, + "1777" => 1777, + "1778" => 1778, + "1779" => 1779, + "1780" => 1780, + "1781" => 1781, + "1782" => 1782, + "1783" => 1783, + "1784" => 1784, + "1785" => 1785, + "1786" => 1786, + "1787" => 1787, + "1788" => 1788, + "1789" => 1789, + "1790" => 1790, + "1791" => 1791, + "1792" => 1792, + "1793" => 1793, + "1794" => 1794, + "1795" => 1795, + "1796" => 1796, + "1797" => 1797, + "1798" => 1798, + "1799" => 1799, + "1800" => 1800, + "1801" => 1801, + "1802" => 1802, + "1803" => 1803, + "1804" => 1804, + "1805" => 1805, + "1806" => 1806, + "1807" => 1807, + "1808" => 1808, + "1809" => 1809, + "1810" => 1810, + "1811" => 1811, + "1812" => 1812, + "1813" => 1813, + "1814" => 1814, + "1815" => 1815, + "1816" => 1816, + "1817" => 1817, + "1818" => 1818, + "1819" => 1819, + "1820" => 1820, + "1821" => 1821, + "1822" => 1822, + "1823" => 1823, + "1824" => 1824, + "1825" => 1825, + "1826" => 1826, + "1827" => 1827, + "1828" => 1828, + "1829" => 1829, + "1830" => 1830, + "1831" => 1831, + "1832" => 1832, + "1833" => 1833, + "1834" => 1834, + "1835" => 1835, + "1836" => 1836, + "1837" => 1837, + "1838" => 1838, + "1839" => 1839, + "1840" => 1840, + "1841" => 1841, + "1842" => 1842, + "1843" => 1843, + "1844" => 1844, + "1845" => 1845, + "1846" => 1846, + "1847" => 1847, + "1848" => 1848, + "1849" => 1849, + "1850" => 1850, + "1851" => 1851, + "1852" => 1852, + "1853" => 1853, + "1854" => 1854, + "1855" => 1855, + "1856" => 1856, + "1857" => 1857, + "1858" => 1858, + "1859" => 1859, + "1860" => 1860, + "1861" => 1861, + "1862" => 1862, + "1863" => 1863, + "1864" => 1864, + "1865" => 1865, + "1866" => 1866, + "1867" => 1867, + "1868" => 1868, + "1869" => 1869, + "1870" => 1870, + "1871" => 1871, + "1872" => 1872, + "1873" => 1873, + "1874" => 1874, + "1875" => 1875, + "1876" => 1876, + "1877" => 1877, + "1878" => 1878, + "1879" => 1879, + "1880" => 1880, + "1881" => 1881, + "1882" => 1882, + "1883" => 1883, + "1884" => 1884, + "1885" => 1885, + "1886" => 1886, + "1887" => 1887, + "1888" => 1888, + "1889" => 1889, + "1890" => 1890, + "1891" => 1891, + "1892" => 1892, + "1893" => 1893, + "1894" => 1894, + "1895" => 1895, + "1896" => 1896, + "1897" => 1897, + "1898" => 1898, + "1899" => 1899, + "1900" => 1900, + "1901" => 1901, + "1902" => 1902, + "1903" => 1903, + "1904" => 1904, + "1905" => 1905, + "1906" => 1906, + "1907" => 1907, + "1908" => 1908, + "1909" => 1909, + "1910" => 1910, + "1911" => 1911, + "1912" => 1912, + "1913" => 1913, + "1914" => 1914, + "1915" => 1915, + "1916" => 1916, + "1917" => 1917, + "1918" => 1918, + "1919" => 1919, + "1920" => 1920, + "1921" => 1921, + "1922" => 1922, + "1923" => 1923, + "1924" => 1924, + "1925" => 1925, + "1926" => 1926, + "1927" => 1927, + "1928" => 1928, + "1929" => 1929, + "1930" => 1930, + "1931" => 1931, + "1932" => 1932, + "1933" => 1933, + "1934" => 1934, + "1935" => 1935, + "1936" => 1936, + "1937" => 1937, + "1938" => 1938, + "1939" => 1939, + "1940" => 1940, + "1941" => 1941, + "1942" => 1942, + "1943" => 1943, + "1944" => 1944, + "1945" => 1945, + "1946" => 1946, + "1947" => 1947, + "1948" => 1948, + "1949" => 1949, + "1950" => 1950, + "1951" => 1951, + "1952" => 1952, + "1953" => 1953, + "1954" => 1954, + "1955" => 1955, + "1956" => 1956, + "1957" => 1957, + "1958" => 1958, + "1959" => 1959, + "1960" => 1960, + "1961" => 1961, + "1962" => 1962, + "1963" => 1963, + "1964" => 1964, + "1965" => 1965, + "1966" => 1966, + "1967" => 1967, + "1968" => 1968, + "1969" => 1969, + "1970" => 1970, + "1971" => 1971, + "1972" => 1972, + "1973" => 1973, + "1974" => 1974, + "1975" => 1975, + "1976" => 1976, + "1977" => 1977, + "1978" => 1978, + "1979" => 1979, + "1980" => 1980, + "1981" => 1981, + "1982" => 1982, + "1983" => 1983, + "1984" => 1984, + "1985" => 1985, + "1986" => 1986, + "1987" => 1987, + "1988" => 1988, + "1989" => 1989, + "1990" => 1990, + "1991" => 1991, + "1992" => 1992, + "1993" => 1993, + "1994" => 1994, + "1995" => 1995, + "1996" => 1996, + "1997" => 1997, + "1998" => 1998, + "1999" => 1999, + "2000" => 2000, + "2001" => 2001, + "2002" => 2002, + "2003" => 2003, + "2004" => 2004, + "2005" => 2005, + "2006" => 2006, + "2007" => 2007, + "2008" => 2008, + "2009" => 2009, + "2010" => 2010, + "2011" => 2011, + "2012" => 2012, + "2013" => 2013, + "2014" => 2014, + "2015" => 2015, + "2016" => 2016, + "2017" => 2017, + "2018" => 2018, + "2019" => 2019, + "2020" => 2020, + "2021" => 2021, + "2022" => 2022, + "2023" => 2023, + "2024" => 2024, + "2025" => 2025, + "2026" => 2026, + "2027" => 2027, + "2028" => 2028, + "2029" => 2029, + "2030" => 2030, + "2031" => 2031, + "2032" => 2032, + "2033" => 2033, + "2034" => 2034, + "2035" => 2035, + "2036" => 2036, + "2037" => 2037, + "2038" => 2038, + "2039" => 2039, + "2040" => 2040, + "2041" => 2041, + "2042" => 2042, + "2043" => 2043, + "2044" => 2044, + "2045" => 2045, + "2046" => 2046, + "2047" => 2047, + "2048" => 2048, + "2049" => 2049, + "2050" => 2050, + "2051" => 2051, + "2052" => 2052, + "2053" => 2053, + "2054" => 2054, + "2055" => 2055, + "2056" => 2056, + "2057" => 2057, + "2058" => 2058, + "2059" => 2059, + "2060" => 2060, + "2061" => 2061, + "2062" => 2062, + "2063" => 2063, + "2064" => 2064, + "2065" => 2065, + "2066" => 2066, + "2067" => 2067, + "2068" => 2068, + "2069" => 2069, + "2070" => 2070, + "2071" => 2071, + "2072" => 2072, + "2073" => 2073, + "2074" => 2074, + "2075" => 2075, + "2076" => 2076, + "2077" => 2077, + "2078" => 2078, + "2079" => 2079, + "2080" => 2080, + "2081" => 2081, + "2082" => 2082, + "2083" => 2083, + "2084" => 2084, + "2085" => 2085, + "2086" => 2086, + "2087" => 2087, + "2088" => 2088, + "2089" => 2089, + "2090" => 2090, + "2091" => 2091, + "2092" => 2092, + "2093" => 2093, + "2094" => 2094, + "2095" => 2095, + "2096" => 2096, + "2097" => 2097, + "2098" => 2098, + "2099" => 2099, + "2100" => 2100, + "2101" => 2101, + "2102" => 2102, + "2103" => 2103, + "2104" => 2104, + "2105" => 2105, + "2106" => 2106, + "2107" => 2107, + "2108" => 2108, + "2109" => 2109, + "2110" => 2110, + "2111" => 2111, + "2112" => 2112, + "2113" => 2113, + "2114" => 2114, + "2115" => 2115, + "2116" => 2116, + "2117" => 2117, + "2118" => 2118, + "2119" => 2119, + "2120" => 2120, + "2121" => 2121, + "2122" => 2122, + "2123" => 2123, + "2124" => 2124, + "2125" => 2125, + "2126" => 2126, + "2127" => 2127, + "2128" => 2128, + "2129" => 2129, + "2130" => 2130, + "2131" => 2131, + "2132" => 2132, + "2133" => 2133, + "2134" => 2134, + "2135" => 2135, + "2136" => 2136, + "2137" => 2137, + "2138" => 2138, + "2139" => 2139, + "2140" => 2140, + "2141" => 2141, + "2142" => 2142, + "2143" => 2143, + "2144" => 2144, + "2145" => 2145, + "2146" => 2146, + "2147" => 2147, + "2148" => 2148, + "2149" => 2149, + "2150" => 2150, + "2151" => 2151, + "2152" => 2152, + "2153" => 2153, + "2154" => 2154, + "2155" => 2155, + "2156" => 2156, + "2157" => 2157, + "2158" => 2158, + "2159" => 2159, + "2160" => 2160, + "2161" => 2161, + "2162" => 2162, + "2163" => 2163, + "2164" => 2164, + "2165" => 2165, + "2166" => 2166, + "2167" => 2167, + "2168" => 2168, + "2169" => 2169, + "2170" => 2170, + "2171" => 2171, + "2172" => 2172, + "2173" => 2173, + "2174" => 2174, + "2175" => 2175, + "2176" => 2176, + "2177" => 2177, + "2178" => 2178, + "2179" => 2179, + "2180" => 2180, + "2181" => 2181, + "2182" => 2182, + "2183" => 2183, + "2184" => 2184, + "2185" => 2185, + "2186" => 2186, + "2187" => 2187, + "2188" => 2188, + "2189" => 2189, + "2190" => 2190, + "2191" => 2191, + "2192" => 2192, + "2193" => 2193, + "2194" => 2194, + "2195" => 2195, + "2196" => 2196, + "2197" => 2197, + "2198" => 2198, + "2199" => 2199, + "2200" => 2200, + "2201" => 2201, + "2202" => 2202, + "2203" => 2203, + "2204" => 2204, + "2205" => 2205, + "2206" => 2206, + "2207" => 2207, + "2208" => 2208, + "2209" => 2209, + "2210" => 2210, + "2211" => 2211, + "2212" => 2212, + "2213" => 2213, + "2214" => 2214, + "2215" => 2215, + "2216" => 2216, + "2217" => 2217, + "2218" => 2218, + "2219" => 2219, + "2220" => 2220, + "2221" => 2221, + "2222" => 2222, + "2223" => 2223, + "2224" => 2224, + "2225" => 2225, + "2226" => 2226, + "2227" => 2227, + "2228" => 2228, + "2229" => 2229, + "2230" => 2230, + "2231" => 2231, + "2232" => 2232, + "2233" => 2233, + "2234" => 2234, + "2235" => 2235, + "2236" => 2236, + "2237" => 2237, + "2238" => 2238, + "2239" => 2239, + "2240" => 2240, + "2241" => 2241, + "2242" => 2242, + "2243" => 2243, + "2244" => 2244, + "2245" => 2245, + "2246" => 2246, + "2247" => 2247, + "2248" => 2248, + "2249" => 2249, + "2250" => 2250, + "2251" => 2251, + "2252" => 2252, + "2253" => 2253, + "2254" => 2254, + "2255" => 2255, + "2256" => 2256, + "2257" => 2257, + "2258" => 2258, + "2259" => 2259, + "2260" => 2260, + "2261" => 2261, + "2262" => 2262, + "2263" => 2263, + "2264" => 2264, + "2265" => 2265, + "2266" => 2266, + "2267" => 2267, + "2268" => 2268, + "2269" => 2269, + "2270" => 2270, + "2271" => 2271, + "2272" => 2272, + "2273" => 2273, + "2274" => 2274, + "2275" => 2275, + "2276" => 2276, + "2277" => 2277, + "2278" => 2278, + "2279" => 2279, + "2280" => 2280, + "2281" => 2281, + "2282" => 2282, + "2283" => 2283, + "2284" => 2284, + "2285" => 2285, + "2286" => 2286, + "2287" => 2287, + "2288" => 2288, + "2289" => 2289, + "2290" => 2290, + "2291" => 2291, + "2292" => 2292, + "2293" => 2293, + "2294" => 2294, + "2295" => 2295, + "2296" => 2296, + "2297" => 2297, + "2298" => 2298, + "2299" => 2299, + "2300" => 2300, + "2301" => 2301, + "2302" => 2302, + "2303" => 2303, + "2304" => 2304, + "2305" => 2305, + "2306" => 2306, + "2307" => 2307, + "2308" => 2308, + "2309" => 2309, + "2310" => 2310, + "2311" => 2311, + "2312" => 2312, + "2313" => 2313, + "2314" => 2314, + "2315" => 2315, + "2316" => 2316, + "2317" => 2317, + "2318" => 2318, + "2319" => 2319, + "2320" => 2320, + "2321" => 2321, + "2322" => 2322, + "2323" => 2323, + "2324" => 2324, + "2325" => 2325, + "2326" => 2326, + "2327" => 2327, + "2328" => 2328, + "2329" => 2329, + "2330" => 2330, + "2331" => 2331, + "2332" => 2332, + "2333" => 2333, + "2334" => 2334, + "2335" => 2335, + "2336" => 2336, + "2337" => 2337, + "2338" => 2338, + "2339" => 2339, + "2340" => 2340, + "2341" => 2341, + "2342" => 2342, + "2343" => 2343, + "2344" => 2344, + "2345" => 2345, + "2346" => 2346, + "2347" => 2347, + "2348" => 2348, + "2349" => 2349, + "2350" => 2350, + "2351" => 2351, + "2352" => 2352, + "2353" => 2353, + "2354" => 2354, + "2355" => 2355, + "2356" => 2356, + "2357" => 2357, + "2358" => 2358, + "2359" => 2359, + "2360" => 2360, + "2361" => 2361, + "2362" => 2362, + "2363" => 2363, + "2364" => 2364, + "2365" => 2365, + "2366" => 2366, + "2367" => 2367, + "2368" => 2368, + "2369" => 2369, + "2370" => 2370, + "2371" => 2371, + "2372" => 2372, + "2373" => 2373, + "2374" => 2374, + "2375" => 2375, + "2376" => 2376, + "2377" => 2377, + "2378" => 2378, + "2379" => 2379, + "2380" => 2380, + "2381" => 2381, + "2382" => 2382, + "2383" => 2383, + "2384" => 2384, + "2385" => 2385, + "2386" => 2386, + "2387" => 2387, + "2388" => 2388, + "2389" => 2389, + "2390" => 2390, + "2391" => 2391, + "2392" => 2392, + "2393" => 2393, + "2394" => 2394, + "2395" => 2395, + "2396" => 2396, + "2397" => 2397, + "2398" => 2398, + "2399" => 2399, + "2400" => 2400, + "2401" => 2401, + "2402" => 2402, + "2403" => 2403, + "2404" => 2404, + "2405" => 2405, + "2406" => 2406, + "2407" => 2407, + "2408" => 2408, + "2409" => 2409, + "2410" => 2410, + "2411" => 2411, + "2412" => 2412, + "2413" => 2413, + "2414" => 2414, + "2415" => 2415, + "2416" => 2416, + "2417" => 2417, + "2418" => 2418, + "2419" => 2419, + "2420" => 2420, + "2421" => 2421, + "2422" => 2422, + "2423" => 2423, + "2424" => 2424, + "2425" => 2425, + "2426" => 2426, + "2427" => 2427, + "2428" => 2428, + "2429" => 2429, + "2430" => 2430, + "2431" => 2431, + "2432" => 2432, + "2433" => 2433, + "2434" => 2434, + "2435" => 2435, + "2436" => 2436, + "2437" => 2437, + "2438" => 2438, + "2439" => 2439, + "2440" => 2440, + "2441" => 2441, + "2442" => 2442, + "2443" => 2443, + "2444" => 2444, + "2445" => 2445, + "2446" => 2446, + "2447" => 2447, + "2448" => 2448, + "2449" => 2449, + "2450" => 2450, + "2451" => 2451, + "2452" => 2452, + "2453" => 2453, + "2454" => 2454, + "2455" => 2455, + "2456" => 2456, + "2457" => 2457, + "2458" => 2458, + "2459" => 2459, + "2460" => 2460, + "2461" => 2461, + "2462" => 2462, + "2463" => 2463, + "2464" => 2464, + "2465" => 2465, + "2466" => 2466, + "2467" => 2467, + "2468" => 2468, + "2469" => 2469, + "2470" => 2470, + "2471" => 2471, + "2472" => 2472, + "2473" => 2473, + "2474" => 2474, + "2475" => 2475, + "2476" => 2476, + "2477" => 2477, + "2478" => 2478, + "2479" => 2479, + "2480" => 2480, + "2481" => 2481, + "2482" => 2482, + "2483" => 2483, + "2484" => 2484, + "2485" => 2485, + "2486" => 2486, + "2487" => 2487, + "2488" => 2488, + "2489" => 2489, + "2490" => 2490, + "2491" => 2491, + "2492" => 2492, + "2493" => 2493, + "2494" => 2494, + "2495" => 2495, + "2496" => 2496, + "2497" => 2497, + "2498" => 2498, + "2499" => 2499, + "2500" => 2500, + "2501" => 2501, + "2502" => 2502, + "2503" => 2503, + "2504" => 2504, + "2505" => 2505, + "2506" => 2506, + "2507" => 2507, + "2508" => 2508, + "2509" => 2509, + "2510" => 2510, + "2511" => 2511, + "2512" => 2512, + "2513" => 2513, + "2514" => 2514, + "2515" => 2515, + "2516" => 2516, + "2517" => 2517, + "2518" => 2518, + "2519" => 2519, + "2520" => 2520, + "2521" => 2521, + "2522" => 2522, + "2523" => 2523, + "2524" => 2524, + "2525" => 2525, + "2526" => 2526, + "2527" => 2527, + "2528" => 2528, + "2529" => 2529, + "2530" => 2530, + "2531" => 2531, + "2532" => 2532, + "2533" => 2533, + "2534" => 2534, + "2535" => 2535, + "2536" => 2536, + "2537" => 2537, + "2538" => 2538, + "2539" => 2539, + "2540" => 2540, + "2541" => 2541, + "2542" => 2542, + "2543" => 2543, + "2544" => 2544, + "2545" => 2545, + "2546" => 2546, + "2547" => 2547, + "2548" => 2548, + "2549" => 2549, + "2550" => 2550, + "2551" => 2551, + "2552" => 2552, + "2553" => 2553, + "2554" => 2554, + "2555" => 2555, + "2556" => 2556, + "2557" => 2557, + "2558" => 2558, + "2559" => 2559, + "2560" => 2560, + "2561" => 2561, + "2562" => 2562, + "2563" => 2563, + "2564" => 2564, + "2565" => 2565, + "2566" => 2566, + "2567" => 2567, + "2568" => 2568, + "2569" => 2569, + "2570" => 2570, + "2571" => 2571, + "2572" => 2572, + "2573" => 2573, + "2574" => 2574, + "2575" => 2575, + "2576" => 2576, + "2577" => 2577, + "2578" => 2578, + "2579" => 2579, + "2580" => 2580, + "2581" => 2581, + "2582" => 2582, + "2583" => 2583, + "2584" => 2584, + "2585" => 2585, + "2586" => 2586, + "2587" => 2587, + "2588" => 2588, + "2589" => 2589, + "2590" => 2590, + "2591" => 2591, + "2592" => 2592, + "2593" => 2593, + "2594" => 2594, + "2595" => 2595, + "2596" => 2596, + "2597" => 2597, + "2598" => 2598, + "2599" => 2599, + "2600" => 2600, + "2601" => 2601, + "2602" => 2602, + "2603" => 2603, + "2604" => 2604, + "2605" => 2605, + "2606" => 2606, + "2607" => 2607, + "2608" => 2608, + "2609" => 2609, + "2610" => 2610, + "2611" => 2611, + "2612" => 2612, + "2613" => 2613, + "2614" => 2614, + "2615" => 2615, + "2616" => 2616, + "2617" => 2617, + "2618" => 2618, + "2619" => 2619, + "2620" => 2620, + "2621" => 2621, + "2622" => 2622, + "2623" => 2623, + "2624" => 2624, + "2625" => 2625, + "2626" => 2626, + "2627" => 2627, + "2628" => 2628, + "2629" => 2629, + "2630" => 2630, + "2631" => 2631, + "2632" => 2632, + "2633" => 2633, + "2634" => 2634, + "2635" => 2635, + "2636" => 2636, + "2637" => 2637, + "2638" => 2638, + "2639" => 2639, + "2640" => 2640, + "2641" => 2641, + "2642" => 2642, + "2643" => 2643, + "2644" => 2644, + "2645" => 2645, + "2646" => 2646, + "2647" => 2647, + "2648" => 2648, + "2649" => 2649, + "2650" => 2650, + "2651" => 2651, + "2652" => 2652, + "2653" => 2653, + "2654" => 2654, + "2655" => 2655, + "2656" => 2656, + "2657" => 2657, + "2658" => 2658, + "2659" => 2659, + "2660" => 2660, + "2661" => 2661, + "2662" => 2662, + "2663" => 2663, + "2664" => 2664, + "2665" => 2665, + "2666" => 2666, + "2667" => 2667, + "2668" => 2668, + "2669" => 2669, + "2670" => 2670, + "2671" => 2671, + "2672" => 2672, + "2673" => 2673, + "2674" => 2674, + "2675" => 2675, + "2676" => 2676, + "2677" => 2677, + "2678" => 2678, + "2679" => 2679, + "2680" => 2680, + "2681" => 2681, + "2682" => 2682, + "2683" => 2683, + "2684" => 2684, + "2685" => 2685, + "2686" => 2686, + "2687" => 2687, + "2688" => 2688, + "2689" => 2689, + "2690" => 2690, + "2691" => 2691, + "2692" => 2692, + "2693" => 2693, + "2694" => 2694, + "2695" => 2695, + "2696" => 2696, + "2697" => 2697, + "2698" => 2698, + "2699" => 2699, + "2700" => 2700, + "2701" => 2701, + "2702" => 2702, + "2703" => 2703, + "2704" => 2704, + "2705" => 2705, + "2706" => 2706, + "2707" => 2707, + "2708" => 2708, + "2709" => 2709, + "2710" => 2710, + "2711" => 2711, + "2712" => 2712, + "2713" => 2713, + "2714" => 2714, + "2715" => 2715, + "2716" => 2716, + "2717" => 2717, + "2718" => 2718, + "2719" => 2719, + "2720" => 2720, + "2721" => 2721, + "2722" => 2722, + "2723" => 2723, + "2724" => 2724, + "2725" => 2725, + "2726" => 2726, + "2727" => 2727, + "2728" => 2728, + "2729" => 2729, + "2730" => 2730, + "2731" => 2731, + "2732" => 2732, + "2733" => 2733, + "2734" => 2734, + "2735" => 2735, + "2736" => 2736, + "2737" => 2737, + "2738" => 2738, + "2739" => 2739, + "2740" => 2740, + "2741" => 2741, + "2742" => 2742, + "2743" => 2743, + "2744" => 2744, + "2745" => 2745, + "2746" => 2746, + "2747" => 2747, + "2748" => 2748, + "2749" => 2749, + "2750" => 2750, + "2751" => 2751, + "2752" => 2752, + "2753" => 2753, + "2754" => 2754, + "2755" => 2755, + "2756" => 2756, + "2757" => 2757, + "2758" => 2758, + "2759" => 2759, + "2760" => 2760, + "2761" => 2761, + "2762" => 2762, + "2763" => 2763, + "2764" => 2764, + "2765" => 2765, + "2766" => 2766, + "2767" => 2767, + "2768" => 2768, + "2769" => 2769, + "2770" => 2770, + "2771" => 2771, + "2772" => 2772, + "2773" => 2773, + "2774" => 2774, + "2775" => 2775, + "2776" => 2776, + "2777" => 2777, + "2778" => 2778, + "2779" => 2779, + "2780" => 2780, + "2781" => 2781, + "2782" => 2782, + "2783" => 2783, + "2784" => 2784, + "2785" => 2785, + "2786" => 2786, + "2787" => 2787, + "2788" => 2788, + "2789" => 2789, + "2790" => 2790, + "2791" => 2791, + "2792" => 2792, + "2793" => 2793, + "2794" => 2794, + "2795" => 2795, + "2796" => 2796, + "2797" => 2797, + "2798" => 2798, + "2799" => 2799, + "2800" => 2800, + "2801" => 2801, + "2802" => 2802, + "2803" => 2803, + "2804" => 2804, + "2805" => 2805, + "2806" => 2806, + "2807" => 2807, + "2808" => 2808, + "2809" => 2809, + "2810" => 2810, + "2811" => 2811, + "2812" => 2812, + "2813" => 2813, + "2814" => 2814, + "2815" => 2815, + "2816" => 2816, + "2817" => 2817, + "2818" => 2818, + "2819" => 2819, + "2820" => 2820, + "2821" => 2821, + "2822" => 2822, + "2823" => 2823, + "2824" => 2824, + "2825" => 2825, + "2826" => 2826, + "2827" => 2827, + "2828" => 2828, + "2829" => 2829, + "2830" => 2830, + "2831" => 2831, + "2832" => 2832, + "2833" => 2833, + "2834" => 2834, + "2835" => 2835, + "2836" => 2836, + "2837" => 2837, + "2838" => 2838, + "2839" => 2839, + "2840" => 2840, + "2841" => 2841, + "2842" => 2842, + "2843" => 2843, + "2844" => 2844, + "2845" => 2845, + "2846" => 2846, + "2847" => 2847, + "2848" => 2848, + "2849" => 2849, + "2850" => 2850, + "2851" => 2851, + "2852" => 2852, + "2853" => 2853, + "2854" => 2854, + "2855" => 2855, + "2856" => 2856, + "2857" => 2857, + "2858" => 2858, + "2859" => 2859, + "2860" => 2860, + "2861" => 2861, + "2862" => 2862, + "2863" => 2863, + "2864" => 2864, + "2865" => 2865, + "2866" => 2866, + "2867" => 2867, + "2868" => 2868, + "2869" => 2869, + "2870" => 2870, + "2871" => 2871, + "2872" => 2872, + "2873" => 2873, + "2874" => 2874, + "2875" => 2875, + "2876" => 2876, + "2877" => 2877, + "2878" => 2878, + "2879" => 2879, + "2880" => 2880, + "2881" => 2881, + "2882" => 2882, + "2883" => 2883, + "2884" => 2884, + "2885" => 2885, + "2886" => 2886, + "2887" => 2887, + "2888" => 2888, + "2889" => 2889, + "2890" => 2890, + "2891" => 2891, + "2892" => 2892, + "2893" => 2893, + "2894" => 2894, + "2895" => 2895, + "2896" => 2896, + "2897" => 2897, + "2898" => 2898, + "2899" => 2899, + "2900" => 2900, + "2901" => 2901, + "2902" => 2902, + "2903" => 2903, + "2904" => 2904, + "2905" => 2905, + "2906" => 2906, + "2907" => 2907, + "2908" => 2908, + "2909" => 2909, + "2910" => 2910, + "2911" => 2911, + "2912" => 2912, + "2913" => 2913, + "2914" => 2914, + "2915" => 2915, + "2916" => 2916, + "2917" => 2917, + "2918" => 2918, + "2919" => 2919, + "2920" => 2920, + "2921" => 2921, + "2922" => 2922, + "2923" => 2923, + "2924" => 2924, + "2925" => 2925, + "2926" => 2926, + "2927" => 2927, + "2928" => 2928, + "2929" => 2929, + "2930" => 2930, + "2931" => 2931, + "2932" => 2932, + "2933" => 2933, + "2934" => 2934, + "2935" => 2935, + "2936" => 2936, + "2937" => 2937, + "2938" => 2938, + "2939" => 2939, + "2940" => 2940, + "2941" => 2941, + "2942" => 2942, + "2943" => 2943, + "2944" => 2944, + "2945" => 2945, + "2946" => 2946, + "2947" => 2947, + "2948" => 2948, + "2949" => 2949, + "2950" => 2950, + "2951" => 2951, + "2952" => 2952, + "2953" => 2953, + "2954" => 2954, + "2955" => 2955, + "2956" => 2956, + "2957" => 2957, + "2958" => 2958, + "2959" => 2959, + "2960" => 2960, + "2961" => 2961, + "2962" => 2962, + "2963" => 2963, + "2964" => 2964, + "2965" => 2965, + "2966" => 2966, + "2967" => 2967, + "2968" => 2968, + "2969" => 2969, + "2970" => 2970, + "2971" => 2971, + "2972" => 2972, + "2973" => 2973, + "2974" => 2974, + "2975" => 2975, + "2976" => 2976, + "2977" => 2977, + "2978" => 2978, + "2979" => 2979, + "2980" => 2980, + "2981" => 2981, + "2982" => 2982, + "2983" => 2983, + "2984" => 2984, + "2985" => 2985, + "2986" => 2986, + "2987" => 2987, + "2988" => 2988, + "2989" => 2989, + "2990" => 2990, + "2991" => 2991, + "2992" => 2992, + "2993" => 2993, + "2994" => 2994, + "2995" => 2995, + "2996" => 2996, + "2997" => 2997, + "2998" => 2998, + "2999" => 2999, + "3000" => 3000, + "3001" => 3001, + "3002" => 3002, + "3003" => 3003, + "3004" => 3004, + "3005" => 3005, + "3006" => 3006, + "3007" => 3007, + "3008" => 3008, + "3009" => 3009, + "3010" => 3010, + "3011" => 3011, + "3012" => 3012, + "3013" => 3013, + "3014" => 3014, + "3015" => 3015, + "3016" => 3016, + "3017" => 3017, + "3018" => 3018, + "3019" => 3019, + "3020" => 3020, + "3021" => 3021, + "3022" => 3022, + "3023" => 3023, + "3024" => 3024, + "3025" => 3025, + "3026" => 3026, + "3027" => 3027, + "3028" => 3028, + "3029" => 3029, + "3030" => 3030, + "3031" => 3031, + "3032" => 3032, + "3033" => 3033, + "3034" => 3034, + "3035" => 3035, + "3036" => 3036, + "3037" => 3037, + "3038" => 3038, + "3039" => 3039, + "3040" => 3040, + "3041" => 3041, + "3042" => 3042, + "3043" => 3043, + "3044" => 3044, + "3045" => 3045, + "3046" => 3046, + "3047" => 3047, + "3048" => 3048, + "3049" => 3049, + "3050" => 3050, + "3051" => 3051, + "3052" => 3052, + "3053" => 3053, + "3054" => 3054, + "3055" => 3055, + "3056" => 3056, + "3057" => 3057, + "3058" => 3058, + "3059" => 3059, + "3060" => 3060, + "3061" => 3061, + "3062" => 3062, + "3063" => 3063, + "3064" => 3064, + "3065" => 3065, + "3066" => 3066, + "3067" => 3067, + "3068" => 3068, + "3069" => 3069, + "3070" => 3070, + "3071" => 3071, + "3072" => 3072, + "3073" => 3073, + "3074" => 3074, + "3075" => 3075, + "3076" => 3076, + "3077" => 3077, + "3078" => 3078, + "3079" => 3079, + "3080" => 3080, + "3081" => 3081, + "3082" => 3082, + "3083" => 3083, + "3084" => 3084, + "3085" => 3085, + "3086" => 3086, + "3087" => 3087, + "3088" => 3088, + "3089" => 3089, + "3090" => 3090, + "3091" => 3091, + "3092" => 3092, + "3093" => 3093, + "3094" => 3094, + "3095" => 3095, + "3096" => 3096, + "3097" => 3097, + "3098" => 3098, + "3099" => 3099, + "3100" => 3100, + "3101" => 3101, + "3102" => 3102, + "3103" => 3103, + "3104" => 3104, + "3105" => 3105, + "3106" => 3106, + "3107" => 3107, + "3108" => 3108, + "3109" => 3109, + "3110" => 3110, + "3111" => 3111, + "3112" => 3112, + "3113" => 3113, + "3114" => 3114, + "3115" => 3115, + "3116" => 3116, + "3117" => 3117, + "3118" => 3118, + "3119" => 3119, + "3120" => 3120, + "3121" => 3121, + "3122" => 3122, + "3123" => 3123, + "3124" => 3124, + "3125" => 3125, + "3126" => 3126, + "3127" => 3127, + "3128" => 3128, + "3129" => 3129, + "3130" => 3130, + "3131" => 3131, + "3132" => 3132, + "3133" => 3133, + "3134" => 3134, + "3135" => 3135, + "3136" => 3136, + "3137" => 3137, + "3138" => 3138, + "3139" => 3139, + "3140" => 3140, + "3141" => 3141, + "3142" => 3142, + "3143" => 3143, + "3144" => 3144, + "3145" => 3145, + "3146" => 3146, + "3147" => 3147, + "3148" => 3148, + "3149" => 3149, + "3150" => 3150, + "3151" => 3151, + "3152" => 3152, + "3153" => 3153, + "3154" => 3154, + "3155" => 3155, + "3156" => 3156, + "3157" => 3157, + "3158" => 3158, + "3159" => 3159, + "3160" => 3160, + "3161" => 3161, + "3162" => 3162, + "3163" => 3163, + "3164" => 3164, + "3165" => 3165, + "3166" => 3166, + "3167" => 3167, + "3168" => 3168, + "3169" => 3169, + "3170" => 3170, + "3171" => 3171, + "3172" => 3172, + "3173" => 3173, + "3174" => 3174, + "3175" => 3175, + "3176" => 3176, + "3177" => 3177, + "3178" => 3178, + "3179" => 3179, + "3180" => 3180, + "3181" => 3181, + "3182" => 3182, + "3183" => 3183, + "3184" => 3184, + "3185" => 3185, + "3186" => 3186, + "3187" => 3187, + "3188" => 3188, + "3189" => 3189, + "3190" => 3190, + "3191" => 3191, + "3192" => 3192, + "3193" => 3193, + "3194" => 3194, + "3195" => 3195, + "3196" => 3196, + "3197" => 3197, + "3198" => 3198, + "3199" => 3199, + "3200" => 3200, + "3201" => 3201, + "3202" => 3202, + "3203" => 3203, + "3204" => 3204, + "3205" => 3205, + "3206" => 3206, + "3207" => 3207, + "3208" => 3208, + "3209" => 3209, + "3210" => 3210, + "3211" => 3211, + "3212" => 3212, + "3213" => 3213, + "3214" => 3214, + "3215" => 3215, + "3216" => 3216, + "3217" => 3217, + "3218" => 3218, + "3219" => 3219, + "3220" => 3220, + "3221" => 3221, + "3222" => 3222, + "3223" => 3223, + "3224" => 3224, + "3225" => 3225, + "3226" => 3226, + "3227" => 3227, + "3228" => 3228, + "3229" => 3229, + "3230" => 3230, + "3231" => 3231, + "3232" => 3232, + "3233" => 3233, + "3234" => 3234, + "3235" => 3235, + "3236" => 3236, + "3237" => 3237, + "3238" => 3238, + "3239" => 3239, + "3240" => 3240, + "3241" => 3241, + "3242" => 3242, + "3243" => 3243, + "3244" => 3244, + "3245" => 3245, + "3246" => 3246, + "3247" => 3247, + "3248" => 3248, + "3249" => 3249, + "3250" => 3250, + "3251" => 3251, + "3252" => 3252, + "3253" => 3253, + "3254" => 3254, + "3255" => 3255, + "3256" => 3256, + "3257" => 3257, + "3258" => 3258, + "3259" => 3259, + "3260" => 3260, + "3261" => 3261, + "3262" => 3262, + "3263" => 3263, + "3264" => 3264, + "3265" => 3265, + "3266" => 3266, + "3267" => 3267, + "3268" => 3268, + "3269" => 3269, + "3270" => 3270, + "3271" => 3271, + "3272" => 3272, + "3273" => 3273, + "3274" => 3274, + "3275" => 3275, + "3276" => 3276, + "3277" => 3277, + "3278" => 3278, + "3279" => 3279, + "3280" => 3280, + "3281" => 3281, + "3282" => 3282, + "3283" => 3283, + "3284" => 3284, + "3285" => 3285, + "3286" => 3286, + "3287" => 3287, + "3288" => 3288, + "3289" => 3289, + "3290" => 3290, + "3291" => 3291, + "3292" => 3292, + "3293" => 3293, + "3294" => 3294, + "3295" => 3295, + "3296" => 3296, + "3297" => 3297, + "3298" => 3298, + "3299" => 3299, + "3300" => 3300, + "3301" => 3301, + "3302" => 3302, + "3303" => 3303, + "3304" => 3304, + "3305" => 3305, + "3306" => 3306, + "3307" => 3307, + "3308" => 3308, + "3309" => 3309, + "3310" => 3310, + "3311" => 3311, + "3312" => 3312, + "3313" => 3313, + "3314" => 3314, + "3315" => 3315, + "3316" => 3316, + "3317" => 3317, + "3318" => 3318, + "3319" => 3319, + "3320" => 3320, + "3321" => 3321, + "3322" => 3322, + "3323" => 3323, + "3324" => 3324, + "3325" => 3325, + "3326" => 3326, + "3327" => 3327, + "3328" => 3328, + "3329" => 3329, + "3330" => 3330, + "3331" => 3331, + "3332" => 3332, + "3333" => 3333, + "3334" => 3334, + "3335" => 3335, + "3336" => 3336, + "3337" => 3337, + "3338" => 3338, + "3339" => 3339, + "3340" => 3340, + "3341" => 3341, + "3342" => 3342, + "3343" => 3343, + "3344" => 3344, + "3345" => 3345, + "3346" => 3346, + "3347" => 3347, + "3348" => 3348, + "3349" => 3349, + "3350" => 3350, + "3351" => 3351, + "3352" => 3352, + "3353" => 3353, + "3354" => 3354, + "3355" => 3355, + "3356" => 3356, + "3357" => 3357, + "3358" => 3358, + "3359" => 3359, + "3360" => 3360, + "3361" => 3361, + "3362" => 3362, + "3363" => 3363, + "3364" => 3364, + "3365" => 3365, + "3366" => 3366, + "3367" => 3367, + "3368" => 3368, + "3369" => 3369, + "3370" => 3370, + "3371" => 3371, + "3372" => 3372, + "3373" => 3373, + "3374" => 3374, + "3375" => 3375, + "3376" => 3376, + "3377" => 3377, + "3378" => 3378, + "3379" => 3379, + "3380" => 3380, + "3381" => 3381, + "3382" => 3382, + "3383" => 3383, + "3384" => 3384, + "3385" => 3385, + "3386" => 3386, + "3387" => 3387, + "3388" => 3388, + "3389" => 3389, + "3390" => 3390, + "3391" => 3391, + "3392" => 3392, + "3393" => 3393, + "3394" => 3394, + "3395" => 3395, + "3396" => 3396, + "3397" => 3397, + "3398" => 3398, + "3399" => 3399, + "3400" => 3400, + "3401" => 3401, + "3402" => 3402, + "3403" => 3403, + "3404" => 3404, + "3405" => 3405, + "3406" => 3406, + "3407" => 3407, + "3408" => 3408, + "3409" => 3409, + "3410" => 3410, + "3411" => 3411, + "3412" => 3412, + "3413" => 3413, + "3414" => 3414, + "3415" => 3415, + "3416" => 3416, + "3417" => 3417, + "3418" => 3418, + "3419" => 3419, + "3420" => 3420, + "3421" => 3421, + "3422" => 3422, + "3423" => 3423, + "3424" => 3424, + "3425" => 3425, + "3426" => 3426, + "3427" => 3427, + "3428" => 3428, + "3429" => 3429, + "3430" => 3430, + "3431" => 3431, + "3432" => 3432, + "3433" => 3433, + "3434" => 3434, + "3435" => 3435, + "3436" => 3436, + "3437" => 3437, + "3438" => 3438, + "3439" => 3439, + "3440" => 3440, + "3441" => 3441, + "3442" => 3442, + "3443" => 3443, + "3444" => 3444, + "3445" => 3445, + "3446" => 3446, + "3447" => 3447, + "3448" => 3448, + "3449" => 3449, + "3450" => 3450, + "3451" => 3451, + "3452" => 3452, + "3453" => 3453, + "3454" => 3454, + "3455" => 3455, + "3456" => 3456, + "3457" => 3457, + "3458" => 3458, + "3459" => 3459, + "3460" => 3460, + "3461" => 3461, + "3462" => 3462, + "3463" => 3463, + "3464" => 3464, + "3465" => 3465, + "3466" => 3466, + "3467" => 3467, + "3468" => 3468, + "3469" => 3469, + "3470" => 3470, + "3471" => 3471, + "3472" => 3472, + "3473" => 3473, + "3474" => 3474, + "3475" => 3475, + "3476" => 3476, + "3477" => 3477, + "3478" => 3478, + "3479" => 3479, + "3480" => 3480, + "3481" => 3481, + "3482" => 3482, + "3483" => 3483, + "3484" => 3484, + "3485" => 3485, + "3486" => 3486, + "3487" => 3487, + "3488" => 3488, + "3489" => 3489, + "3490" => 3490, + "3491" => 3491, + "3492" => 3492, + "3493" => 3493, + "3494" => 3494, + "3495" => 3495, + "3496" => 3496, + "3497" => 3497, + "3498" => 3498, + "3499" => 3499, + "3500" => 3500, + "3501" => 3501, + "3502" => 3502, + "3503" => 3503, + "3504" => 3504, + "3505" => 3505, + "3506" => 3506, + "3507" => 3507, + "3508" => 3508, + "3509" => 3509, + "3510" => 3510, + "3511" => 3511, + "3512" => 3512, + "3513" => 3513, + "3514" => 3514, + "3515" => 3515, + "3516" => 3516, + "3517" => 3517, + "3518" => 3518, + "3519" => 3519, + "3520" => 3520, + "3521" => 3521, + "3522" => 3522, + "3523" => 3523, + "3524" => 3524, + "3525" => 3525, + "3526" => 3526, + "3527" => 3527, + "3528" => 3528, + "3529" => 3529, + "3530" => 3530, + "3531" => 3531, + "3532" => 3532, + "3533" => 3533, + "3534" => 3534, + "3535" => 3535, + "3536" => 3536, + "3537" => 3537, + "3538" => 3538, + "3539" => 3539, + "3540" => 3540, + "3541" => 3541, + "3542" => 3542, + "3543" => 3543, + "3544" => 3544, + "3545" => 3545, + "3546" => 3546, + "3547" => 3547, + "3548" => 3548, + "3549" => 3549, + "3550" => 3550, + "3551" => 3551, + "3552" => 3552, + "3553" => 3553, + "3554" => 3554, + "3555" => 3555, + "3556" => 3556, + "3557" => 3557, + "3558" => 3558, + "3559" => 3559, + "3560" => 3560, + "3561" => 3561, + "3562" => 3562, + "3563" => 3563, + "3564" => 3564, + "3565" => 3565, + "3566" => 3566, + "3567" => 3567, + "3568" => 3568, + "3569" => 3569, + "3570" => 3570, + "3571" => 3571, + "3572" => 3572, + "3573" => 3573, + "3574" => 3574, + "3575" => 3575, + "3576" => 3576, + "3577" => 3577, + "3578" => 3578, + "3579" => 3579, + "3580" => 3580, + "3581" => 3581, + "3582" => 3582, + "3583" => 3583, + "3584" => 3584, + "3585" => 3585, + "3586" => 3586, + "3587" => 3587, + "3588" => 3588, + "3589" => 3589, + "3590" => 3590, + "3591" => 3591, + "3592" => 3592, + "3593" => 3593, + "3594" => 3594, + "3595" => 3595, + "3596" => 3596, + "3597" => 3597, + "3598" => 3598, + "3599" => 3599, + "3600" => 3600, + "3601" => 3601, + "3602" => 3602, + "3603" => 3603, + "3604" => 3604, + "3605" => 3605, + "3606" => 3606, + "3607" => 3607, + "3608" => 3608, + "3609" => 3609, + "3610" => 3610, + "3611" => 3611, + "3612" => 3612, + "3613" => 3613, + "3614" => 3614, + "3615" => 3615, + "3616" => 3616, + "3617" => 3617, + "3618" => 3618, + "3619" => 3619, + "3620" => 3620, + "3621" => 3621, + "3622" => 3622, + "3623" => 3623, + "3624" => 3624, + "3625" => 3625, + "3626" => 3626, + "3627" => 3627, + "3628" => 3628, + "3629" => 3629, + "3630" => 3630, + "3631" => 3631, + "3632" => 3632, + "3633" => 3633, + "3634" => 3634, + "3635" => 3635, + "3636" => 3636, + "3637" => 3637, + "3638" => 3638, + "3639" => 3639, + "3640" => 3640, + "3641" => 3641, + "3642" => 3642, + "3643" => 3643, + "3644" => 3644, + "3645" => 3645, + "3646" => 3646, + "3647" => 3647, + "3648" => 3648, + "3649" => 3649, + "3650" => 3650, + "3651" => 3651, + "3652" => 3652, + "3653" => 3653, + "3654" => 3654, + "3655" => 3655, + "3656" => 3656, + "3657" => 3657, + "3658" => 3658, + "3659" => 3659, + "3660" => 3660, + "3661" => 3661, + "3662" => 3662, + "3663" => 3663, + "3664" => 3664, + "3665" => 3665, + "3666" => 3666, + "3667" => 3667, + "3668" => 3668, + "3669" => 3669, + "3670" => 3670, + "3671" => 3671, + "3672" => 3672, + "3673" => 3673, + "3674" => 3674, + "3675" => 3675, + "3676" => 3676, + "3677" => 3677, + "3678" => 3678, + "3679" => 3679, + "3680" => 3680, + "3681" => 3681, + "3682" => 3682, + "3683" => 3683, + "3684" => 3684, + "3685" => 3685, + "3686" => 3686, + "3687" => 3687, + "3688" => 3688, + "3689" => 3689, + "3690" => 3690, + "3691" => 3691, + "3692" => 3692, + "3693" => 3693, + "3694" => 3694, + "3695" => 3695, + "3696" => 3696, + "3697" => 3697, + "3698" => 3698, + "3699" => 3699, + "3700" => 3700, + "3701" => 3701, + "3702" => 3702, + "3703" => 3703, + "3704" => 3704, + "3705" => 3705, + "3706" => 3706, + "3707" => 3707, + "3708" => 3708, + "3709" => 3709, + "3710" => 3710, + "3711" => 3711, + "3712" => 3712, + "3713" => 3713, + "3714" => 3714, + "3715" => 3715, + "3716" => 3716, + "3717" => 3717, + "3718" => 3718, + "3719" => 3719, + "3720" => 3720, + "3721" => 3721, + "3722" => 3722, + "3723" => 3723, + "3724" => 3724, + "3725" => 3725, + "3726" => 3726, + "3727" => 3727, + "3728" => 3728, + "3729" => 3729, + "3730" => 3730, + "3731" => 3731, + "3732" => 3732, + "3733" => 3733, + "3734" => 3734, + "3735" => 3735, + "3736" => 3736, + "3737" => 3737, + "3738" => 3738, + "3739" => 3739, + "3740" => 3740, + "3741" => 3741, + "3742" => 3742, + "3743" => 3743, + "3744" => 3744, + "3745" => 3745, + "3746" => 3746, + "3747" => 3747, + "3748" => 3748, + "3749" => 3749, + "3750" => 3750, + "3751" => 3751, + "3752" => 3752, + "3753" => 3753, + "3754" => 3754, + "3755" => 3755, + "3756" => 3756, + "3757" => 3757, + "3758" => 3758, + "3759" => 3759, + "3760" => 3760, + "3761" => 3761, + "3762" => 3762, + "3763" => 3763, + "3764" => 3764, + "3765" => 3765, + "3766" => 3766, + "3767" => 3767, + "3768" => 3768, + "3769" => 3769, + "3770" => 3770, + "3771" => 3771, + "3772" => 3772, + "3773" => 3773, + "3774" => 3774, + "3775" => 3775, + "3776" => 3776, + "3777" => 3777, + "3778" => 3778, + "3779" => 3779, + "3780" => 3780, + "3781" => 3781, + "3782" => 3782, + "3783" => 3783, + "3784" => 3784, + "3785" => 3785, + "3786" => 3786, + "3787" => 3787, + "3788" => 3788, + "3789" => 3789, + "3790" => 3790, + "3791" => 3791, + "3792" => 3792, + "3793" => 3793, + "3794" => 3794, + "3795" => 3795, + "3796" => 3796, + "3797" => 3797, + "3798" => 3798, + "3799" => 3799, + "3800" => 3800, + "3801" => 3801, + "3802" => 3802, + "3803" => 3803, + "3804" => 3804, + "3805" => 3805, + "3806" => 3806, + "3807" => 3807, + "3808" => 3808, + "3809" => 3809, + "3810" => 3810, + "3811" => 3811, + "3812" => 3812, + "3813" => 3813, + "3814" => 3814, + "3815" => 3815, + "3816" => 3816, + "3817" => 3817, + "3818" => 3818, + "3819" => 3819, + "3820" => 3820, + "3821" => 3821, + "3822" => 3822, + "3823" => 3823, + "3824" => 3824, + "3825" => 3825, + "3826" => 3826, + "3827" => 3827, + "3828" => 3828, + "3829" => 3829, + "3830" => 3830, + "3831" => 3831, + "3832" => 3832, + "3833" => 3833, + "3834" => 3834, + "3835" => 3835, + "3836" => 3836, + "3837" => 3837, + "3838" => 3838, + "3839" => 3839, + "3840" => 3840, + "3841" => 3841, + "3842" => 3842, + "3843" => 3843, + "3844" => 3844, + "3845" => 3845, + "3846" => 3846, + "3847" => 3847, + "3848" => 3848, + "3849" => 3849, + "3850" => 3850, + "3851" => 3851, + "3852" => 3852, + "3853" => 3853, + "3854" => 3854, + "3855" => 3855, + "3856" => 3856, + "3857" => 3857, + "3858" => 3858, + "3859" => 3859, + "3860" => 3860, + "3861" => 3861, + "3862" => 3862, + "3863" => 3863, + "3864" => 3864, + "3865" => 3865, + "3866" => 3866, + "3867" => 3867, + "3868" => 3868, + "3869" => 3869, + "3870" => 3870, + "3871" => 3871, + "3872" => 3872, + "3873" => 3873, + "3874" => 3874, + "3875" => 3875, + "3876" => 3876, + "3877" => 3877, + "3878" => 3878, + "3879" => 3879, + "3880" => 3880, + "3881" => 3881, + "3882" => 3882, + "3883" => 3883, + "3884" => 3884, + "3885" => 3885, + "3886" => 3886, + "3887" => 3887, + "3888" => 3888, + "3889" => 3889, + "3890" => 3890, + "3891" => 3891, + "3892" => 3892, + "3893" => 3893, + "3894" => 3894, + "3895" => 3895, + "3896" => 3896, + "3897" => 3897, + "3898" => 3898, + "3899" => 3899, + "3900" => 3900, + "3901" => 3901, + "3902" => 3902, + "3903" => 3903, + "3904" => 3904, + "3905" => 3905, + "3906" => 3906, + "3907" => 3907, + "3908" => 3908, + "3909" => 3909, + "3910" => 3910, + "3911" => 3911, + "3912" => 3912, + "3913" => 3913, + "3914" => 3914, + "3915" => 3915, + "3916" => 3916, + "3917" => 3917, + "3918" => 3918, + "3919" => 3919, + "3920" => 3920, + "3921" => 3921, + "3922" => 3922, + "3923" => 3923, + "3924" => 3924, + "3925" => 3925, + "3926" => 3926, + "3927" => 3927, + "3928" => 3928, + "3929" => 3929, + "3930" => 3930, + "3931" => 3931, + "3932" => 3932, + "3933" => 3933, + "3934" => 3934, + "3935" => 3935, + "3936" => 3936, + "3937" => 3937, + "3938" => 3938, + "3939" => 3939, + "3940" => 3940, + "3941" => 3941, + "3942" => 3942, + "3943" => 3943, + "3944" => 3944, + "3945" => 3945, + "3946" => 3946, + "3947" => 3947, + "3948" => 3948, + "3949" => 3949, + "3950" => 3950, + "3951" => 3951, + "3952" => 3952, + "3953" => 3953, + "3954" => 3954, + "3955" => 3955, + "3956" => 3956, + "3957" => 3957, + "3958" => 3958, + "3959" => 3959, + "3960" => 3960, + "3961" => 3961, + "3962" => 3962, + "3963" => 3963, + "3964" => 3964, + "3965" => 3965, + "3966" => 3966, + "3967" => 3967, + "3968" => 3968, + "3969" => 3969, + "3970" => 3970, + "3971" => 3971, + "3972" => 3972, + "3973" => 3973, + "3974" => 3974, + "3975" => 3975, + "3976" => 3976, + "3977" => 3977, + "3978" => 3978, + "3979" => 3979, + "3980" => 3980, + "3981" => 3981, + "3982" => 3982, + "3983" => 3983, + "3984" => 3984, + "3985" => 3985, + "3986" => 3986, + "3987" => 3987, + "3988" => 3988, + "3989" => 3989, + "3990" => 3990, + "3991" => 3991, + "3992" => 3992, + "3993" => 3993, + "3994" => 3994, + "3995" => 3995, + "3996" => 3996, + "3997" => 3997, + "3998" => 3998, + "3999" => 3999, + "4000" => 4000, + "4001" => 4001, + "4002" => 4002, + "4003" => 4003, + "4004" => 4004, + "4005" => 4005, + "4006" => 4006, + "4007" => 4007, + "4008" => 4008, + "4009" => 4009, + "4010" => 4010, + "4011" => 4011, + "4012" => 4012, + "4013" => 4013, + "4014" => 4014, + "4015" => 4015, + "4016" => 4016, + "4017" => 4017, + "4018" => 4018, + "4019" => 4019, + "4020" => 4020, + "4021" => 4021, + "4022" => 4022, + "4023" => 4023, + "4024" => 4024, + "4025" => 4025, + "4026" => 4026, + "4027" => 4027, + "4028" => 4028, + "4029" => 4029, + "4030" => 4030, + "4031" => 4031, + "4032" => 4032, + "4033" => 4033, + "4034" => 4034, + "4035" => 4035, + "4036" => 4036, + "4037" => 4037, + "4038" => 4038, + "4039" => 4039, + "4040" => 4040, + "4041" => 4041, + "4042" => 4042, + "4043" => 4043, + "4044" => 4044, + "4045" => 4045, + "4046" => 4046, + "4047" => 4047, + "4048" => 4048, + "4049" => 4049, + "4050" => 4050, + "4051" => 4051, + "4052" => 4052, + "4053" => 4053, + "4054" => 4054, + "4055" => 4055, + "4056" => 4056, + "4057" => 4057, + "4058" => 4058, + "4059" => 4059, + "4060" => 4060, + "4061" => 4061, + "4062" => 4062, + "4063" => 4063, + "4064" => 4064, + "4065" => 4065, + "4066" => 4066, + "4067" => 4067, + "4068" => 4068, + "4069" => 4069, + "4070" => 4070, + "4071" => 4071, + "4072" => 4072, + "4073" => 4073, + "4074" => 4074, + "4075" => 4075, + "4076" => 4076, + "4077" => 4077, + "4078" => 4078, + "4079" => 4079, + "4080" => 4080, + "4081" => 4081, + "4082" => 4082, + "4083" => 4083, + "4084" => 4084, + "4085" => 4085, + "4086" => 4086, + "4087" => 4087, + "4088" => 4088, + "4089" => 4089, + "4090" => 4090, + "4091" => 4091, + "4092" => 4092, + "4093" => 4093, + "4094" => 4094, + "4095" => 4095, + "4096" => 4096, + "4097" => 4097, + "4098" => 4098, + "4099" => 4099, + "4100" => 4100, + "4101" => 4101, + "4102" => 4102, + "4103" => 4103, + "4104" => 4104, + "4105" => 4105, + "4106" => 4106, + "4107" => 4107, + "4108" => 4108, + "4109" => 4109, + "4110" => 4110, + "4111" => 4111, + "4112" => 4112, + "4113" => 4113, + "4114" => 4114, + "4115" => 4115, + "4116" => 4116, + "4117" => 4117, + "4118" => 4118, + "4119" => 4119, + "4120" => 4120, + "4121" => 4121, + "4122" => 4122, + "4123" => 4123, + "4124" => 4124, + "4125" => 4125, + "4126" => 4126, + "4127" => 4127, + "4128" => 4128, + "4129" => 4129, + "4130" => 4130, + "4131" => 4131, + "4132" => 4132, + "4133" => 4133, + "4134" => 4134, + "4135" => 4135, + "4136" => 4136, + "4137" => 4137, + "4138" => 4138, + "4139" => 4139, + "4140" => 4140, + "4141" => 4141, + "4142" => 4142, + "4143" => 4143, + "4144" => 4144, + "4145" => 4145, + "4146" => 4146, + "4147" => 4147, + "4148" => 4148, + "4149" => 4149, + "4150" => 4150, + "4151" => 4151, + "4152" => 4152, + "4153" => 4153, + "4154" => 4154, + "4155" => 4155, + "4156" => 4156, + "4157" => 4157, + "4158" => 4158, + "4159" => 4159, + "4160" => 4160, + "4161" => 4161, + "4162" => 4162, + "4163" => 4163, + "4164" => 4164, + "4165" => 4165, + "4166" => 4166, + "4167" => 4167, + "4168" => 4168, + "4169" => 4169, + "4170" => 4170, + "4171" => 4171, + "4172" => 4172, + "4173" => 4173, + "4174" => 4174, + "4175" => 4175, + "4176" => 4176, + "4177" => 4177, + "4178" => 4178, + "4179" => 4179, + "4180" => 4180, + "4181" => 4181, + "4182" => 4182, + "4183" => 4183, + "4184" => 4184, + "4185" => 4185, + "4186" => 4186, + "4187" => 4187, + "4188" => 4188, + "4189" => 4189, + "4190" => 4190, + "4191" => 4191, + "4192" => 4192, + "4193" => 4193, + "4194" => 4194, + "4195" => 4195, + "4196" => 4196, + "4197" => 4197, + "4198" => 4198, + "4199" => 4199, + "4200" => 4200, + "4201" => 4201, + "4202" => 4202, + "4203" => 4203, + "4204" => 4204, + "4205" => 4205, + "4206" => 4206, + "4207" => 4207, + "4208" => 4208, + "4209" => 4209, + "4210" => 4210, + "4211" => 4211, + "4212" => 4212, + "4213" => 4213, + "4214" => 4214, + "4215" => 4215, + "4216" => 4216, + "4217" => 4217, + "4218" => 4218, + "4219" => 4219, + "4220" => 4220, + "4221" => 4221, + "4222" => 4222, + "4223" => 4223, + "4224" => 4224, + "4225" => 4225, + "4226" => 4226, + "4227" => 4227, + "4228" => 4228, + "4229" => 4229, + "4230" => 4230, + "4231" => 4231, + "4232" => 4232, + "4233" => 4233, + "4234" => 4234, + "4235" => 4235, + "4236" => 4236, + "4237" => 4237, + "4238" => 4238, + "4239" => 4239, + "4240" => 4240, + "4241" => 4241, + "4242" => 4242, + "4243" => 4243, + "4244" => 4244, + "4245" => 4245, + "4246" => 4246, + "4247" => 4247, + "4248" => 4248, + "4249" => 4249, + "4250" => 4250, + "4251" => 4251, + "4252" => 4252, + "4253" => 4253, + "4254" => 4254, + "4255" => 4255, + "4256" => 4256, + "4257" => 4257, + "4258" => 4258, + "4259" => 4259, + "4260" => 4260, + "4261" => 4261, + "4262" => 4262, + "4263" => 4263, + "4264" => 4264, + "4265" => 4265, + "4266" => 4266, + "4267" => 4267, + "4268" => 4268, + "4269" => 4269, + "4270" => 4270, + "4271" => 4271, + "4272" => 4272, + "4273" => 4273, + "4274" => 4274, + "4275" => 4275, + "4276" => 4276, + "4277" => 4277, + "4278" => 4278, + "4279" => 4279, + "4280" => 4280, + "4281" => 4281, + "4282" => 4282, + "4283" => 4283, + "4284" => 4284, + "4285" => 4285, + "4286" => 4286, + "4287" => 4287, + "4288" => 4288, + "4289" => 4289, + "4290" => 4290, + "4291" => 4291, + "4292" => 4292, + "4293" => 4293, + "4294" => 4294, + "4295" => 4295, + "4296" => 4296, + "4297" => 4297, + "4298" => 4298, + "4299" => 4299, + "4300" => 4300, + "4301" => 4301, + "4302" => 4302, + "4303" => 4303, + "4304" => 4304, + "4305" => 4305, + "4306" => 4306, + "4307" => 4307, + "4308" => 4308, + "4309" => 4309, + "4310" => 4310, + "4311" => 4311, + "4312" => 4312, + "4313" => 4313, + "4314" => 4314, + "4315" => 4315, + "4316" => 4316, + "4317" => 4317, + "4318" => 4318, + "4319" => 4319, + "4320" => 4320, + "4321" => 4321, + "4322" => 4322, + "4323" => 4323, + "4324" => 4324, + "4325" => 4325, + "4326" => 4326, + "4327" => 4327, + "4328" => 4328, + "4329" => 4329, + "4330" => 4330, + "4331" => 4331, + "4332" => 4332, + "4333" => 4333, + "4334" => 4334, + "4335" => 4335, + "4336" => 4336, + "4337" => 4337, + "4338" => 4338, + "4339" => 4339, + "4340" => 4340, + "4341" => 4341, + "4342" => 4342, + "4343" => 4343, + "4344" => 4344, + "4345" => 4345, + "4346" => 4346, + "4347" => 4347, + "4348" => 4348, + "4349" => 4349, + "4350" => 4350, + "4351" => 4351, + "4352" => 4352, + "4353" => 4353, + "4354" => 4354, + "4355" => 4355, + "4356" => 4356, + "4357" => 4357, + "4358" => 4358, + "4359" => 4359, + "4360" => 4360, + "4361" => 4361, + "4362" => 4362, + "4363" => 4363, + "4364" => 4364, + "4365" => 4365, + "4366" => 4366, + "4367" => 4367, + "4368" => 4368, + "4369" => 4369, + "4370" => 4370, + "4371" => 4371, + "4372" => 4372, + "4373" => 4373, + "4374" => 4374, + "4375" => 4375, + "4376" => 4376, + "4377" => 4377, + "4378" => 4378, + "4379" => 4379, + "4380" => 4380, + "4381" => 4381, + "4382" => 4382, + "4383" => 4383, + "4384" => 4384, + "4385" => 4385, + "4386" => 4386, + "4387" => 4387, + "4388" => 4388, + "4389" => 4389, + "4390" => 4390, + "4391" => 4391, + "4392" => 4392, + "4393" => 4393, + "4394" => 4394, + "4395" => 4395, + "4396" => 4396, + "4397" => 4397, + "4398" => 4398, + "4399" => 4399, + "4400" => 4400, + "4401" => 4401, + "4402" => 4402, + "4403" => 4403, + "4404" => 4404, + "4405" => 4405, + "4406" => 4406, + "4407" => 4407, + "4408" => 4408, + "4409" => 4409, + "4410" => 4410, + "4411" => 4411, + "4412" => 4412, + "4413" => 4413, + "4414" => 4414, + "4415" => 4415, + "4416" => 4416, + "4417" => 4417, + "4418" => 4418, + "4419" => 4419, + "4420" => 4420, + "4421" => 4421, + "4422" => 4422, + "4423" => 4423, + "4424" => 4424, + "4425" => 4425, + "4426" => 4426, + "4427" => 4427, + "4428" => 4428, + "4429" => 4429, + "4430" => 4430, + "4431" => 4431, + "4432" => 4432, + "4433" => 4433, + "4434" => 4434, + "4435" => 4435, + "4436" => 4436, + "4437" => 4437, + "4438" => 4438, + "4439" => 4439, + "4440" => 4440, + "4441" => 4441, + "4442" => 4442, + "4443" => 4443, + "4444" => 4444, + "4445" => 4445, + "4446" => 4446, + "4447" => 4447, + "4448" => 4448, + "4449" => 4449, + "4450" => 4450, + "4451" => 4451, + "4452" => 4452, + "4453" => 4453, + "4454" => 4454, + "4455" => 4455, + "4456" => 4456, + "4457" => 4457, + "4458" => 4458, + "4459" => 4459, + "4460" => 4460, + "4461" => 4461, + "4462" => 4462, + "4463" => 4463, + "4464" => 4464, + "4465" => 4465, + "4466" => 4466, + "4467" => 4467, + "4468" => 4468, + "4469" => 4469, + "4470" => 4470, + "4471" => 4471, + "4472" => 4472, + "4473" => 4473, + "4474" => 4474, + "4475" => 4475, + "4476" => 4476, + "4477" => 4477, + "4478" => 4478, + "4479" => 4479, + "4480" => 4480, + "4481" => 4481, + "4482" => 4482, + "4483" => 4483, + "4484" => 4484, + "4485" => 4485, + "4486" => 4486, + "4487" => 4487, + "4488" => 4488, + "4489" => 4489, + "4490" => 4490, + "4491" => 4491, + "4492" => 4492, + "4493" => 4493, + "4494" => 4494, + "4495" => 4495, + "4496" => 4496, + "4497" => 4497, + "4498" => 4498, + "4499" => 4499, + "4500" => 4500, + "4501" => 4501, + "4502" => 4502, + "4503" => 4503, + "4504" => 4504, + "4505" => 4505, + "4506" => 4506, + "4507" => 4507, + "4508" => 4508, + "4509" => 4509, + "4510" => 4510, + "4511" => 4511, + "4512" => 4512, + "4513" => 4513, + "4514" => 4514, + "4515" => 4515, + "4516" => 4516, + "4517" => 4517, + "4518" => 4518, + "4519" => 4519, + "4520" => 4520, + "4521" => 4521, + "4522" => 4522, + "4523" => 4523, + "4524" => 4524, + "4525" => 4525, + "4526" => 4526, + "4527" => 4527, + "4528" => 4528, + "4529" => 4529, + "4530" => 4530, + "4531" => 4531, + "4532" => 4532, + "4533" => 4533, + "4534" => 4534, + "4535" => 4535, + "4536" => 4536, + "4537" => 4537, + "4538" => 4538, + "4539" => 4539, + "4540" => 4540, + "4541" => 4541, + "4542" => 4542, + "4543" => 4543, + "4544" => 4544, + "4545" => 4545, + "4546" => 4546, + "4547" => 4547, + "4548" => 4548, + "4549" => 4549, + "4550" => 4550, + "4551" => 4551, + "4552" => 4552, + "4553" => 4553, + "4554" => 4554, + "4555" => 4555, + "4556" => 4556, + "4557" => 4557, + "4558" => 4558, + "4559" => 4559, + "4560" => 4560, + "4561" => 4561, + "4562" => 4562, + "4563" => 4563, + "4564" => 4564, + "4565" => 4565, + "4566" => 4566, + "4567" => 4567, + "4568" => 4568, + "4569" => 4569, + "4570" => 4570, + "4571" => 4571, + "4572" => 4572, + "4573" => 4573, + "4574" => 4574, + "4575" => 4575, + "4576" => 4576, + "4577" => 4577, + "4578" => 4578, + "4579" => 4579, + "4580" => 4580, + "4581" => 4581, + "4582" => 4582, + "4583" => 4583, + "4584" => 4584, + "4585" => 4585, + "4586" => 4586, + "4587" => 4587, + "4588" => 4588, + "4589" => 4589, + "4590" => 4590, + "4591" => 4591, + "4592" => 4592, + "4593" => 4593, + "4594" => 4594, + "4595" => 4595, + "4596" => 4596, + "4597" => 4597, + "4598" => 4598, + "4599" => 4599, + "4600" => 4600, + "4601" => 4601, + "4602" => 4602, + "4603" => 4603, + "4604" => 4604, + "4605" => 4605, + "4606" => 4606, + "4607" => 4607, + "4608" => 4608, + "4609" => 4609, + "4610" => 4610, + "4611" => 4611, + "4612" => 4612, + "4613" => 4613, + "4614" => 4614, + "4615" => 4615, + "4616" => 4616, + "4617" => 4617, + "4618" => 4618, + "4619" => 4619, + "4620" => 4620, + "4621" => 4621, + "4622" => 4622, + "4623" => 4623, + "4624" => 4624, + "4625" => 4625, + "4626" => 4626, + "4627" => 4627, + "4628" => 4628, + "4629" => 4629, + "4630" => 4630, + "4631" => 4631, + "4632" => 4632, + "4633" => 4633, + "4634" => 4634, + "4635" => 4635, + "4636" => 4636, + "4637" => 4637, + "4638" => 4638, + "4639" => 4639, + "4640" => 4640, + "4641" => 4641, + "4642" => 4642, + "4643" => 4643, + "4644" => 4644, + "4645" => 4645, + "4646" => 4646, + "4647" => 4647, + "4648" => 4648, + "4649" => 4649, + "4650" => 4650, + "4651" => 4651, + "4652" => 4652, + "4653" => 4653, + "4654" => 4654, + "4655" => 4655, + "4656" => 4656, + "4657" => 4657, + "4658" => 4658, + "4659" => 4659, + "4660" => 4660, + "4661" => 4661, + "4662" => 4662, + "4663" => 4663, + "4664" => 4664, + "4665" => 4665, + "4666" => 4666, + "4667" => 4667, + "4668" => 4668, + "4669" => 4669, + "4670" => 4670, + "4671" => 4671, + "4672" => 4672, + "4673" => 4673, + "4674" => 4674, + "4675" => 4675, + "4676" => 4676, + "4677" => 4677, + "4678" => 4678, + "4679" => 4679, + "4680" => 4680, + "4681" => 4681, + "4682" => 4682, + "4683" => 4683, + "4684" => 4684, + "4685" => 4685, + "4686" => 4686, + "4687" => 4687, + "4688" => 4688, + "4689" => 4689, + "4690" => 4690, + "4691" => 4691, + "4692" => 4692, + "4693" => 4693, + "4694" => 4694, + "4695" => 4695, + "4696" => 4696, + "4697" => 4697, + "4698" => 4698, + "4699" => 4699, + "4700" => 4700, + "4701" => 4701, + "4702" => 4702, + "4703" => 4703, + "4704" => 4704, + "4705" => 4705, + "4706" => 4706, + "4707" => 4707, + "4708" => 4708, + "4709" => 4709, + "4710" => 4710, + "4711" => 4711, + "4712" => 4712, + "4713" => 4713, + "4714" => 4714, + "4715" => 4715, + "4716" => 4716, + "4717" => 4717, + "4718" => 4718, + "4719" => 4719, + "4720" => 4720, + "4721" => 4721, + "4722" => 4722, + "4723" => 4723, + "4724" => 4724, + "4725" => 4725, + "4726" => 4726, + "4727" => 4727, + "4728" => 4728, + "4729" => 4729, + "4730" => 4730, + "4731" => 4731, + "4732" => 4732, + "4733" => 4733, + "4734" => 4734, + "4735" => 4735, + "4736" => 4736, + "4737" => 4737, + "4738" => 4738, + "4739" => 4739, + "4740" => 4740, + "4741" => 4741, + "4742" => 4742, + "4743" => 4743, + "4744" => 4744, + "4745" => 4745, + "4746" => 4746, + "4747" => 4747, + "4748" => 4748, + "4749" => 4749, + "4750" => 4750, + "4751" => 4751, + "4752" => 4752, + "4753" => 4753, + "4754" => 4754, + "4755" => 4755, + "4756" => 4756, + "4757" => 4757, + "4758" => 4758, + "4759" => 4759, + "4760" => 4760, + "4761" => 4761, + "4762" => 4762, + "4763" => 4763, + "4764" => 4764, + "4765" => 4765, + "4766" => 4766, + "4767" => 4767, + "4768" => 4768, + "4769" => 4769, + "4770" => 4770, + "4771" => 4771, + "4772" => 4772, + "4773" => 4773, + "4774" => 4774, + "4775" => 4775, + "4776" => 4776, + "4777" => 4777, + "4778" => 4778, + "4779" => 4779, + "4780" => 4780, + "4781" => 4781, + "4782" => 4782, + "4783" => 4783, + "4784" => 4784, + "4785" => 4785, + "4786" => 4786, + "4787" => 4787, + "4788" => 4788, + "4789" => 4789, + "4790" => 4790, + "4791" => 4791, + "4792" => 4792, + "4793" => 4793, + "4794" => 4794, + "4795" => 4795, + "4796" => 4796, + "4797" => 4797, + "4798" => 4798, + "4799" => 4799, + "4800" => 4800, + "4801" => 4801, + "4802" => 4802, + "4803" => 4803, + "4804" => 4804, + "4805" => 4805, + "4806" => 4806, + "4807" => 4807, + "4808" => 4808, + "4809" => 4809, + "4810" => 4810, + "4811" => 4811, + "4812" => 4812, + "4813" => 4813, + "4814" => 4814, + "4815" => 4815, + "4816" => 4816, + "4817" => 4817, + "4818" => 4818, + "4819" => 4819, + "4820" => 4820, + "4821" => 4821, + "4822" => 4822, + "4823" => 4823, + "4824" => 4824, + "4825" => 4825, + "4826" => 4826, + "4827" => 4827, + "4828" => 4828, + "4829" => 4829, + "4830" => 4830, + "4831" => 4831, + "4832" => 4832, + "4833" => 4833, + "4834" => 4834, + "4835" => 4835, + "4836" => 4836, + "4837" => 4837, + "4838" => 4838, + "4839" => 4839, + "4840" => 4840, + "4841" => 4841, + "4842" => 4842, + "4843" => 4843, + "4844" => 4844, + "4845" => 4845, + "4846" => 4846, + "4847" => 4847, + "4848" => 4848, + "4849" => 4849, + "4850" => 4850, + "4851" => 4851, + "4852" => 4852, + "4853" => 4853, + "4854" => 4854, + "4855" => 4855, + "4856" => 4856, + "4857" => 4857, + "4858" => 4858, + "4859" => 4859, + "4860" => 4860, + "4861" => 4861, + "4862" => 4862, + "4863" => 4863, + "4864" => 4864, + "4865" => 4865, + "4866" => 4866, + "4867" => 4867, + "4868" => 4868, + "4869" => 4869, + "4870" => 4870, + "4871" => 4871, + "4872" => 4872, + "4873" => 4873, + "4874" => 4874, + "4875" => 4875, + "4876" => 4876, + "4877" => 4877, + "4878" => 4878, + "4879" => 4879, + "4880" => 4880, + "4881" => 4881, + "4882" => 4882, + "4883" => 4883, + "4884" => 4884, + "4885" => 4885, + "4886" => 4886, + "4887" => 4887, + "4888" => 4888, + "4889" => 4889, + "4890" => 4890, + "4891" => 4891, + "4892" => 4892, + "4893" => 4893, + "4894" => 4894, + "4895" => 4895, + "4896" => 4896, + "4897" => 4897, + "4898" => 4898, + "4899" => 4899, + "4900" => 4900, + "4901" => 4901, + "4902" => 4902, + "4903" => 4903, + "4904" => 4904, + "4905" => 4905, + "4906" => 4906, + "4907" => 4907, + "4908" => 4908, + "4909" => 4909, + "4910" => 4910, + "4911" => 4911, + "4912" => 4912, + "4913" => 4913, + "4914" => 4914, + "4915" => 4915, + "4916" => 4916, + "4917" => 4917, + "4918" => 4918, + "4919" => 4919, + "4920" => 4920, + "4921" => 4921, + "4922" => 4922, + "4923" => 4923, + "4924" => 4924, + "4925" => 4925, + "4926" => 4926, + "4927" => 4927, + "4928" => 4928, + "4929" => 4929, + "4930" => 4930, + "4931" => 4931, + "4932" => 4932, + "4933" => 4933, + "4934" => 4934, + "4935" => 4935, + "4936" => 4936, + "4937" => 4937, + "4938" => 4938, + "4939" => 4939, + "4940" => 4940, + "4941" => 4941, + "4942" => 4942, + "4943" => 4943, + "4944" => 4944, + "4945" => 4945, + "4946" => 4946, + "4947" => 4947, + "4948" => 4948, + "4949" => 4949, + "4950" => 4950, + "4951" => 4951, + "4952" => 4952, + "4953" => 4953, + "4954" => 4954, + "4955" => 4955, + "4956" => 4956, + "4957" => 4957, + "4958" => 4958, + "4959" => 4959, + "4960" => 4960, + "4961" => 4961, + "4962" => 4962, + "4963" => 4963, + "4964" => 4964, + "4965" => 4965, + "4966" => 4966, + "4967" => 4967, + "4968" => 4968, + "4969" => 4969, + "4970" => 4970, + "4971" => 4971, + "4972" => 4972, + "4973" => 4973, + "4974" => 4974, + "4975" => 4975, + "4976" => 4976, + "4977" => 4977, + "4978" => 4978, + "4979" => 4979, + "4980" => 4980, + "4981" => 4981, + "4982" => 4982, + "4983" => 4983, + "4984" => 4984, + "4985" => 4985, + "4986" => 4986, + "4987" => 4987, + "4988" => 4988, + "4989" => 4989, + "4990" => 4990, + "4991" => 4991, + "4992" => 4992, + "4993" => 4993, + "4994" => 4994, + "4995" => 4995, + "4996" => 4996, + "4997" => 4997, + "4998" => 4998, + "4999" => 4999, + "5000" => 5000, + "5001" => 5001, + "5002" => 5002, + "5003" => 5003, + "5004" => 5004, + "5005" => 5005, + "5006" => 5006, + "5007" => 5007, + "5008" => 5008, + "5009" => 5009, + "5010" => 5010, + "5011" => 5011, + "5012" => 5012, + "5013" => 5013, + "5014" => 5014, + "5015" => 5015, + "5016" => 5016, + "5017" => 5017, + "5018" => 5018, + "5019" => 5019, + "5020" => 5020, + "5021" => 5021, + "5022" => 5022, + "5023" => 5023, + "5024" => 5024, + "5025" => 5025, + "5026" => 5026, + "5027" => 5027, + "5028" => 5028, + "5029" => 5029, + "5030" => 5030, + "5031" => 5031, + "5032" => 5032, + "5033" => 5033, + "5034" => 5034, + "5035" => 5035, + "5036" => 5036, + "5037" => 5037, + "5038" => 5038, + "5039" => 5039, + "5040" => 5040, + "5041" => 5041, + "5042" => 5042, + "5043" => 5043, + "5044" => 5044, + "5045" => 5045, + "5046" => 5046, + "5047" => 5047, + "5048" => 5048, + "5049" => 5049, + "5050" => 5050, + "5051" => 5051, + "5052" => 5052, + "5053" => 5053, + "5054" => 5054, + "5055" => 5055, + "5056" => 5056, + "5057" => 5057, + "5058" => 5058, + "5059" => 5059, + "5060" => 5060, + "5061" => 5061, + "5062" => 5062, + "5063" => 5063, + "5064" => 5064, + "5065" => 5065, + "5066" => 5066, + "5067" => 5067, + "5068" => 5068, + "5069" => 5069, + "5070" => 5070, + "5071" => 5071, + "5072" => 5072, + "5073" => 5073, + "5074" => 5074, + "5075" => 5075, + "5076" => 5076, + "5077" => 5077, + "5078" => 5078, + "5079" => 5079, + "5080" => 5080, + "5081" => 5081, + "5082" => 5082, + "5083" => 5083, + "5084" => 5084, + "5085" => 5085, + "5086" => 5086, + "5087" => 5087, + "5088" => 5088, + "5089" => 5089, + "5090" => 5090, + "5091" => 5091, + "5092" => 5092, + "5093" => 5093, + "5094" => 5094, + "5095" => 5095, + "5096" => 5096, + "5097" => 5097, + "5098" => 5098, + "5099" => 5099, + "5100" => 5100, + "5101" => 5101, + "5102" => 5102, + "5103" => 5103, + "5104" => 5104, + "5105" => 5105, + "5106" => 5106, + "5107" => 5107, + "5108" => 5108, + "5109" => 5109, + "5110" => 5110, + "5111" => 5111, + "5112" => 5112, + "5113" => 5113, + "5114" => 5114, + "5115" => 5115, + "5116" => 5116, + "5117" => 5117, + "5118" => 5118, + "5119" => 5119, + "5120" => 5120, + "5121" => 5121, + "5122" => 5122, + "5123" => 5123, + "5124" => 5124, + "5125" => 5125, + "5126" => 5126, + "5127" => 5127, + "5128" => 5128, + "5129" => 5129, + "5130" => 5130, + "5131" => 5131, + "5132" => 5132, + "5133" => 5133, + "5134" => 5134, + "5135" => 5135, + "5136" => 5136, + "5137" => 5137, + "5138" => 5138, + "5139" => 5139, + "5140" => 5140, + "5141" => 5141, + "5142" => 5142, + "5143" => 5143, + "5144" => 5144, + "5145" => 5145, + "5146" => 5146, + "5147" => 5147, + "5148" => 5148, + "5149" => 5149, + "5150" => 5150, + "5151" => 5151, + "5152" => 5152, + "5153" => 5153, + "5154" => 5154, + "5155" => 5155, + "5156" => 5156, + "5157" => 5157, + "5158" => 5158, + "5159" => 5159, + "5160" => 5160, + "5161" => 5161, + "5162" => 5162, + "5163" => 5163, + "5164" => 5164, + "5165" => 5165, + "5166" => 5166, + "5167" => 5167, + "5168" => 5168, + "5169" => 5169, + "5170" => 5170, + "5171" => 5171, + "5172" => 5172, + "5173" => 5173, + "5174" => 5174, + "5175" => 5175, + "5176" => 5176, + "5177" => 5177, + "5178" => 5178, + "5179" => 5179, + "5180" => 5180, + "5181" => 5181, + "5182" => 5182, + "5183" => 5183, + "5184" => 5184, + "5185" => 5185, + "5186" => 5186, + "5187" => 5187, + "5188" => 5188, + "5189" => 5189, + "5190" => 5190, + "5191" => 5191, + "5192" => 5192, + "5193" => 5193, + "5194" => 5194, + "5195" => 5195, + "5196" => 5196, + "5197" => 5197, + "5198" => 5198, + _ => 5199, + } +} diff --git a/tests/ui/match/match-static-pattern.rs b/tests/ui/match/match-static-pattern.rs new file mode 100644 index 000000000000..5d367f9ec17c --- /dev/null +++ b/tests/ui/match/match-static-pattern.rs @@ -0,0 +1,10 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/17933 +pub static X: usize = 1; + +fn main() { + match 1 { + self::X => {} + //~^ ERROR expected unit struct, unit variant or constant, found static `self::X` + _ => {} + } +} diff --git a/tests/ui/match/match-static-pattern.stderr b/tests/ui/match/match-static-pattern.stderr new file mode 100644 index 000000000000..1b111fbcc2de --- /dev/null +++ b/tests/ui/match/match-static-pattern.stderr @@ -0,0 +1,9 @@ +error[E0532]: expected unit struct, unit variant or constant, found static `self::X` + --> $DIR/match-static-pattern.rs:6:9 + | +LL | self::X => {} + | ^^^^^^^ not a unit struct, unit variant or constant + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0532`. diff --git a/tests/ui/match/match-tuple-slice.rs b/tests/ui/match/match-tuple-slice.rs new file mode 100644 index 000000000000..aaebf4401d09 --- /dev/null +++ b/tests/ui/match/match-tuple-slice.rs @@ -0,0 +1,12 @@ +//! regression test for +//@ run-pass +fn main() { + let x: (isize, &[isize]) = (2, &[1, 2]); + assert_eq!(match x { + (0, &[_, _]) => 0, + (1, _) => 1, + (2, &[_, _]) => 2, + (2, _) => 3, + _ => 4 + }, 2); +} diff --git a/tests/ui/match/match-usize-min-max-pattern.rs b/tests/ui/match/match-usize-min-max-pattern.rs new file mode 100644 index 000000000000..6a801406895d --- /dev/null +++ b/tests/ui/match/match-usize-min-max-pattern.rs @@ -0,0 +1,8 @@ +//! regression test for +//@ run-pass +fn main() { + match (0, 0) { + (usize::MIN, usize::MAX) => {} + _ => {} + } +} diff --git a/tests/ui/match/uninhabited-granular-moves.rs b/tests/ui/match/uninhabited-granular-moves.rs new file mode 100644 index 000000000000..f836aedbebc7 --- /dev/null +++ b/tests/ui/match/uninhabited-granular-moves.rs @@ -0,0 +1,46 @@ +// See rust-lang/rust#146590, as well as Zulip discussion: +// +// https://rust-lang.zulipchat.com/#narrow/channel/513289-t-patterns/topic/Question.20about.20patterns.20and.20moves/with/558638455 +// +// Whether pattern matching performs a discriminant read shouldn't depend on whether +// you explicitly write down an uninhabited branch, or leave it implicit. + +enum Emp { } + +enum Foo { + Bar(A), + Qux(Emp), +} + +fn test1(thefoo: Foo<(Box, Box)>) { + match thefoo { + Foo::Bar((a, _)) => { } + } + + match thefoo { //~ ERROR: use of partially moved value: `thefoo` + Foo::Bar((_, a)) => { } + } +} + +fn test2(thefoo: Foo<(Box, Box)>) { + match thefoo { + Foo::Bar((a, _)) => { } + Foo::Qux(_) => { } + } + match thefoo { //~ ERROR: use of partially moved value: `thefoo` + Foo::Bar((_, a)) => { } + Foo::Qux(_) => { } + } +} + +fn test3(thefoo: Foo<(Box, Box)>) { + match thefoo { + Foo::Bar((a, _)) => { } + Foo::Qux(_) => { } + } + match thefoo { //~ ERROR: use of partially moved value: `thefoo` + Foo::Bar((_, a)) => { } + } +} + +fn main() {} diff --git a/tests/ui/match/uninhabited-granular-moves.stderr b/tests/ui/match/uninhabited-granular-moves.stderr new file mode 100644 index 000000000000..e3a66db526d4 --- /dev/null +++ b/tests/ui/match/uninhabited-granular-moves.stderr @@ -0,0 +1,48 @@ +error[E0382]: use of partially moved value: `thefoo` + --> $DIR/uninhabited-granular-moves.rs:20:11 + | +LL | Foo::Bar((a, _)) => { } + | - value partially moved here +... +LL | match thefoo { + | ^^^^^^ value used here after partial move + | + = note: partial move occurs because value has type `Box`, which does not implement the `Copy` trait +help: borrow this binding in the pattern to avoid moving the value + | +LL | Foo::Bar((ref a, _)) => { } + | +++ + +error[E0382]: use of partially moved value: `thefoo` + --> $DIR/uninhabited-granular-moves.rs:30:11 + | +LL | Foo::Bar((a, _)) => { } + | - value partially moved here +... +LL | match thefoo { + | ^^^^^^ value used here after partial move + | + = note: partial move occurs because value has type `Box`, which does not implement the `Copy` trait +help: borrow this binding in the pattern to avoid moving the value + | +LL | Foo::Bar((ref a, _)) => { } + | +++ + +error[E0382]: use of partially moved value: `thefoo` + --> $DIR/uninhabited-granular-moves.rs:41:11 + | +LL | Foo::Bar((a, _)) => { } + | - value partially moved here +... +LL | match thefoo { + | ^^^^^^ value used here after partial move + | + = note: partial move occurs because value has type `Box`, which does not implement the `Copy` trait +help: borrow this binding in the pattern to avoid moving the value + | +LL | Foo::Bar((ref a, _)) => { } + | +++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/methods/assc-func-issue-149038.rs b/tests/ui/methods/assc-func-issue-149038.rs new file mode 100644 index 000000000000..4fb4bd72fcc3 --- /dev/null +++ b/tests/ui/methods/assc-func-issue-149038.rs @@ -0,0 +1,10 @@ +struct S; +impl S { + fn foo() {} + fn bar(&self) { + self.foo(); //~ ERROR no method named `foo` found for reference `&S` in the current scope + let f: fn() = self.foo; //~ ERROR no field `foo` on type `&S` + } +} + +fn main() {} diff --git a/tests/ui/methods/assc-func-issue-149038.stderr b/tests/ui/methods/assc-func-issue-149038.stderr new file mode 100644 index 000000000000..55b762bc0ee0 --- /dev/null +++ b/tests/ui/methods/assc-func-issue-149038.stderr @@ -0,0 +1,43 @@ +error[E0599]: no method named `foo` found for reference `&S` in the current scope + --> $DIR/assc-func-issue-149038.rs:5:14 + | +LL | self.foo(); + | ^^^ this is an associated function, not a method + | + = note: found the following associated functions; to be used as methods, functions must have a `self` parameter +note: the candidate is defined in an impl for the type `S` + --> $DIR/assc-func-issue-149038.rs:3:5 + | +LL | fn foo() {} + | ^^^^^^^^ +help: use associated function syntax instead + | +LL - self.foo(); +LL + S::foo(); + | + +error[E0609]: no field `foo` on type `&S` + --> $DIR/assc-func-issue-149038.rs:6:28 + | +LL | let f: fn() = self.foo; + | ^^^ + | | + | this is an associated function, not a method + | unknown field + | + = note: found the following associated function; to be used as method, it must have a `self` parameter +note: the candidate is defined in an impl for the type `S` + --> $DIR/assc-func-issue-149038.rs:3:5 + | +LL | fn foo() {} + | ^^^^^^^^ +help: use associated function syntax instead + | +LL - let f: fn() = self.foo; +LL + let f: fn() = S::foo; + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0599, E0609. +For more information about an error, try `rustc --explain E0599`. diff --git a/tests/ui/methods/call_method_unknown_pointee.rs b/tests/ui/methods/call_method_unknown_pointee.rs index a144e855ae3c..8927576239a8 100644 --- a/tests/ui/methods/call_method_unknown_pointee.rs +++ b/tests/ui/methods/call_method_unknown_pointee.rs @@ -3,26 +3,39 @@ // tests that the pointee type of a raw pointer must be known to call methods on it // see also: `tests/ui/editions/edition-raw-pointer-method-2018.rs` -fn main() { - let val = 1_u32; - let ptr = &val as *const u32; +fn a() { + let ptr = &1u32 as *const u32; unsafe { let _a: i32 = (ptr as *const _).read(); //~^ ERROR type annotations needed + } +} + +fn b() { + let ptr = &1u32 as *const u32; + unsafe { let b = ptr as *const _; //~^ ERROR type annotations needed let _b: u8 = b.read(); - let _c = (ptr as *const u8).read(); // we know the type here - } - - let mut val = 2_u32; - let ptr = &mut val as *mut u32; - unsafe { - let _a: i32 = (ptr as *mut _).read(); - //~^ ERROR type annotations needed - let b = ptr as *mut _; - //~^ ERROR type annotations needed - b.write(10); - (ptr as *mut i32).write(1000); // we know the type here } } + + +fn c() { + let ptr = &mut 2u32 as *mut u32; + unsafe { + let _c: i32 = (ptr as *mut _).read(); + //~^ ERROR type annotations needed + } +} + +fn d() { + let ptr = &mut 2u32 as *mut u32; + unsafe { + let d = ptr as *mut _; + //~^ ERROR type annotations needed + let _d: u8 = d.read(); + } +} + +fn main() {} diff --git a/tests/ui/methods/call_method_unknown_pointee.stderr b/tests/ui/methods/call_method_unknown_pointee.stderr index e20c6f8e8a17..c123533b51bc 100644 --- a/tests/ui/methods/call_method_unknown_pointee.stderr +++ b/tests/ui/methods/call_method_unknown_pointee.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_pointee.rs:10:23 + --> $DIR/call_method_unknown_pointee.rs:9:23 | LL | let _a: i32 = (ptr as *const _).read(); | ^^^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type @@ -7,7 +7,7 @@ LL | let _a: i32 = (ptr as *const _).read(); | cannot infer type error[E0282]: type annotations needed for `*const _` - --> $DIR/call_method_unknown_pointee.rs:12:13 + --> $DIR/call_method_unknown_pointee.rs:17:13 | LL | let b = ptr as *const _; | ^ @@ -21,25 +21,25 @@ LL | let b: *const _ = ptr as *const _; | ++++++++++ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_pointee.rs:21:23 + --> $DIR/call_method_unknown_pointee.rs:27:23 | -LL | let _a: i32 = (ptr as *mut _).read(); +LL | let _c: i32 = (ptr as *mut _).read(); | ^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type | | | cannot infer type error[E0282]: type annotations needed for `*mut _` - --> $DIR/call_method_unknown_pointee.rs:23:13 + --> $DIR/call_method_unknown_pointee.rs:35:13 | -LL | let b = ptr as *mut _; +LL | let d = ptr as *mut _; | ^ LL | -LL | b.write(10); - | ----- cannot call a method on a raw pointer with an unknown pointee type +LL | let _d: u8 = d.read(); + | ---- cannot call a method on a raw pointer with an unknown pointee type | -help: consider giving `b` an explicit type, where the placeholders `_` are specified +help: consider giving `d` an explicit type, where the placeholders `_` are specified | -LL | let b: *mut _ = ptr as *mut _; +LL | let d: *mut _ = ptr as *mut _; | ++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/methods/call_method_unknown_referent.rs b/tests/ui/methods/call_method_unknown_referent.rs index b26ecc74175b..54b8653a2109 100644 --- a/tests/ui/methods/call_method_unknown_referent.rs +++ b/tests/ui/methods/call_method_unknown_referent.rs @@ -14,20 +14,22 @@ impl SmartPtr { fn foo(&self) {} } -fn main() { - let val = 1_u32; - let ptr = &val; +fn a() { + let ptr = &1u32; let _a: i32 = (ptr as &_).read(); //~^ ERROR type annotations needed +} +fn b() { // Same again, but with a smart pointer type - let val2 = 1_u32; - let rc = std::rc::Rc::new(val2); + let rc = std::rc::Rc::new(1u32); let _b = (rc as std::rc::Rc<_>).read(); //~^ ERROR type annotations needed +} +fn c() { // Same again, but with a smart pointer type - let ptr = SmartPtr(val); + let ptr = SmartPtr(1u32); // We can call unambiguous outer-type methods on this (ptr as SmartPtr<_>).foo(); @@ -46,3 +48,5 @@ fn main() { let _c = (ptr as SmartPtr<_>).read(); //~^ ERROR no method named `read` found for struct `SmartPtr` } + +fn main() {} diff --git a/tests/ui/methods/call_method_unknown_referent.stderr b/tests/ui/methods/call_method_unknown_referent.stderr index 35c7d9caf3ef..92fb32b987df 100644 --- a/tests/ui/methods/call_method_unknown_referent.stderr +++ b/tests/ui/methods/call_method_unknown_referent.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_referent.rs:20:19 + --> $DIR/call_method_unknown_referent.rs:19:19 | LL | let _a: i32 = (ptr as &_).read(); | ^^^^^^^^^^^ cannot infer type @@ -11,7 +11,7 @@ LL | let _b = (rc as std::rc::Rc<_>).read(); | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type error[E0599]: no method named `read` found for struct `SmartPtr` in the current scope - --> $DIR/call_method_unknown_referent.rs:46:35 + --> $DIR/call_method_unknown_referent.rs:48:35 | LL | struct SmartPtr(T); | ------------------ method `read` not found for this struct diff --git a/tests/ui/methods/filter-relevant-fn-bounds.rs b/tests/ui/methods/filter-relevant-fn-bounds.rs index 6233c9db53a0..7945eaa0daa2 100644 --- a/tests/ui/methods/filter-relevant-fn-bounds.rs +++ b/tests/ui/methods/filter-relevant-fn-bounds.rs @@ -9,8 +9,6 @@ impl Wrapper { //~^ ERROR the trait bound `for<'a> F: Output<'a>` is not satisfied where F: for<'a> FnOnce(>::Type), - //~^ ERROR the trait bound `for<'a> F: Output<'a>` is not satisfied - //~| ERROR the trait bound `for<'a> F: Output<'a>` is not satisfied { } } diff --git a/tests/ui/methods/filter-relevant-fn-bounds.stderr b/tests/ui/methods/filter-relevant-fn-bounds.stderr index 82103e62ddfe..4efe40ae0903 100644 --- a/tests/ui/methods/filter-relevant-fn-bounds.stderr +++ b/tests/ui/methods/filter-relevant-fn-bounds.stderr @@ -12,37 +12,15 @@ help: consider further restricting type parameter `F` with trait `Output` LL | F: for<'a> FnOnce(>::Type) + for<'a> Output<'a>, | ++++++++++++++++++++ -error[E0277]: the trait bound `for<'a> F: Output<'a>` is not satisfied - --> $DIR/filter-relevant-fn-bounds.rs:11:12 - | -LL | F: for<'a> FnOnce(>::Type), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Output<'a>` is not implemented for `F` - | -help: consider further restricting type parameter `F` with trait `Output` - | -LL | F: for<'a> FnOnce(>::Type) + for<'a> Output<'a>, - | ++++++++++++++++++++ - -error[E0277]: the trait bound `for<'a> F: Output<'a>` is not satisfied - --> $DIR/filter-relevant-fn-bounds.rs:11:20 - | -LL | F: for<'a> FnOnce(>::Type), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Output<'a>` is not implemented for `F` - | -help: consider further restricting type parameter `F` with trait `Output` - | -LL | F: for<'a> FnOnce(>::Type) + for<'a> Output<'a>, - | ++++++++++++++++++++ - -error[E0277]: expected a `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41}` - --> $DIR/filter-relevant-fn-bounds.rs:20:34 +error[E0277]: expected a `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41}` + --> $DIR/filter-relevant-fn-bounds.rs:18:34 | LL | wrapper.do_something_wrapper(|value| ()); - | -------------------- ^^^^^^^^^^ expected an `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41}` + | -------------------- ^^^^^^^^^^ expected an `FnOnce(<{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41} as Output<'a>>::Type)` closure, found `{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41}` | | | required by a bound introduced by this call | - = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/filter-relevant-fn-bounds.rs:20:34: 20:41}` + = help: the trait `for<'a> Output<'a>` is not implemented for closure `{closure@$DIR/filter-relevant-fn-bounds.rs:18:34: 18:41}` help: this trait has no implementations, consider adding one --> $DIR/filter-relevant-fn-bounds.rs:1:1 | @@ -57,6 +35,6 @@ LL | fn do_something_wrapper(self, _: F) LL | F: for<'a> FnOnce(>::Type), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper::do_something_wrapper` -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/methods/issue-3707.stderr b/tests/ui/methods/issue-3707.stderr index b3d4dfe5aaa8..c163ccc81899 100644 --- a/tests/ui/methods/issue-3707.stderr +++ b/tests/ui/methods/issue-3707.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `boom` found for reference `&Obj` in the current s --> $DIR/issue-3707.rs:10:14 | LL | self.boom(); - | -----^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `Obj::boom()` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Obj` @@ -13,6 +10,11 @@ note: the candidate is defined in an impl for the type `Obj` | LL | pub fn boom() -> bool { | ^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - self.boom(); +LL + Obj::boom(); + | error: aborting due to 1 previous error diff --git a/tests/ui/methods/method-normalize-bounds-issue-20604.rs b/tests/ui/methods/method-normalize-bounds-issue-20604.rs index ea18fe14d157..9f20f99b97fc 100644 --- a/tests/ui/methods/method-normalize-bounds-issue-20604.rs +++ b/tests/ui/methods/method-normalize-bounds-issue-20604.rs @@ -1,7 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -#![allow(stable_features)] // Test that we handle projection types which wind up important for // resolving methods. This test was reduced from a larger example; the @@ -10,8 +9,6 @@ // type projection. -#![feature(associated_types)] - trait Hasher { type Output; fn finish(&self) -> Self::Output; diff --git a/tests/ui/methods/method-not-found-on-struct.rs b/tests/ui/methods/method-not-found-on-struct.rs new file mode 100644 index 000000000000..b2a457ed19e5 --- /dev/null +++ b/tests/ui/methods/method-not-found-on-struct.rs @@ -0,0 +1,10 @@ +//! regression test for + +struct Homura; + +fn akemi(homura: Homura) { + let Some(ref madoka) = Some(homura.kaname()); //~ ERROR no method named `kaname` found + madoka.clone(); +} + +fn main() { } diff --git a/tests/ui/methods/method-not-found-on-struct.stderr b/tests/ui/methods/method-not-found-on-struct.stderr new file mode 100644 index 000000000000..3bf775f30a7a --- /dev/null +++ b/tests/ui/methods/method-not-found-on-struct.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `kaname` found for struct `Homura` in the current scope + --> $DIR/method-not-found-on-struct.rs:6:40 + | +LL | struct Homura; + | ------------- method `kaname` not found for this struct +... +LL | let Some(ref madoka) = Some(homura.kaname()); + | ^^^^^^ method not found in `Homura` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/mir/enable_passes_validation.enum_not_in_pass_names.stderr b/tests/ui/mir/enable_passes_validation.enum_not_in_pass_names.stderr new file mode 100644 index 000000000000..89229ebabe84 --- /dev/null +++ b/tests/ui/mir/enable_passes_validation.enum_not_in_pass_names.stderr @@ -0,0 +1,8 @@ +warning: MIR pass `SimplifyCfg` is unknown and will be ignored + +warning: MIR pass `SimplifyCfg` is unknown and will be ignored + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +warning: 2 warnings emitted + diff --git a/tests/ui/mir/enable_passes_validation.rs b/tests/ui/mir/enable_passes_validation.rs index 99b1ba528b0c..d3d22b49ac7f 100644 --- a/tests/ui/mir/enable_passes_validation.rs +++ b/tests/ui/mir/enable_passes_validation.rs @@ -1,4 +1,5 @@ //@ revisions: empty unprefixed all_unknown all_known mixed +//@ revisions: enum_not_in_pass_names enum_in_pass_names //@[empty] compile-flags: -Zmir-enable-passes= @@ -13,6 +14,12 @@ //@[mixed] check-pass //@[mixed] compile-flags: -Zmir-enable-passes=+ThisPassDoesNotExist,+CheckAlignment +//@[enum_not_in_pass_names] check-pass +//@[enum_not_in_pass_names] compile-flags: -Zmir-enable-passes=+SimplifyCfg + +//@[enum_in_pass_names] check-pass +//@[enum_in_pass_names] compile-flags: -Zmir-enable-passes=+AddCallGuards + fn main() {} //[empty]~? ERROR incorrect value `` for unstable option `mir-enable-passes` @@ -23,3 +30,5 @@ fn main() {} //[all_unknown]~? WARN MIR pass `DoesNotExist` is unknown and will be ignored //[all_unknown]~? WARN MIR pass `ThisPass` is unknown and will be ignored //[all_unknown]~? WARN MIR pass `DoesNotExist` is unknown and will be ignored +//[enum_not_in_pass_names]~? WARN MIR pass `SimplifyCfg` is unknown and will be ignored +//[enum_not_in_pass_names]~? WARN MIR pass `SimplifyCfg` is unknown and will be ignored diff --git a/tests/ui/mir/gvn-opt-138225.rs b/tests/ui/mir/gvn-opt-138225.rs new file mode 100644 index 000000000000..46359e044e2e --- /dev/null +++ b/tests/ui/mir/gvn-opt-138225.rs @@ -0,0 +1,16 @@ +//! Regression test for + +pub struct A { + name: NestedOption>, + //~^ ERROR cannot find type `NestedOption` in this scope +} + +impl A { + pub async fn func1() -> &'static A { + //~^ ERROR `async fn` is not permitted in Rust 2015 + static RES: A = A { name: None }; + &RES + } +} + +fn main() {} diff --git a/tests/ui/mir/gvn-opt-138225.stderr b/tests/ui/mir/gvn-opt-138225.stderr new file mode 100644 index 000000000000..b2e3d4476bf8 --- /dev/null +++ b/tests/ui/mir/gvn-opt-138225.stderr @@ -0,0 +1,19 @@ +error[E0670]: `async fn` is not permitted in Rust 2015 + --> $DIR/gvn-opt-138225.rs:9:9 + | +LL | pub async fn func1() -> &'static A { + | ^^^^^ to use `async fn`, switch to Rust 2018 or later + | + = help: pass `--edition 2024` to `rustc` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error[E0425]: cannot find type `NestedOption` in this scope + --> $DIR/gvn-opt-138225.rs:4:11 + | +LL | name: NestedOption>, + | ^^^^^^^^^^^^ not found in this scope + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0425, E0670. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/mir/issue-121103.rs b/tests/ui/mir/issue-121103.rs index 247c644c5bb1..4a3d3f5590f3 100644 --- a/tests/ui/mir/issue-121103.rs +++ b/tests/ui/mir/issue-121103.rs @@ -1,3 +1,5 @@ fn main(_: as lib2::TypeFn>::Output) {} -//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `lib2` -//~| ERROR failed to resolve: use of unresolved module or unlinked crate `lib2` +//~^ ERROR: cannot find +//~| ERROR: cannot find +//~| NOTE: use of unresolved module or unlinked crate `lib2` +//~| NOTE: use of unresolved module or unlinked crate `lib2` diff --git a/tests/ui/mir/issue-121103.stderr b/tests/ui/mir/issue-121103.stderr index 3565f6f0cdef..236a3cbc5806 100644 --- a/tests/ui/mir/issue-121103.stderr +++ b/tests/ui/mir/issue-121103.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `lib2` +error[E0433]: cannot find module or crate `lib2` in this scope --> $DIR/issue-121103.rs:1:38 | LL | fn main(_: as lib2::TypeFn>::Output) {} @@ -6,7 +6,7 @@ LL | fn main(_: as lib2::TypeFn>::Output) {} | = help: you might be missing a crate named `lib2` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `lib2` +error[E0433]: cannot find module or crate `lib2` in this scope --> $DIR/issue-121103.rs:1:13 | LL | fn main(_: as lib2::TypeFn>::Output) {} diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs index 32bd32754ddd..047ceaaf82c6 100644 --- a/tests/ui/mir/lint/storage-live.rs +++ b/tests/ui/mir/lint/storage-live.rs @@ -4,6 +4,7 @@ //@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" //@ normalize-stderr: "storage_live\[....\]" -> "storage_live[HASH]" //@ normalize-stderr: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - " +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ rustc-env:RUST_BACKTRACE=0 #![feature(custom_mir, core_intrinsics)] diff --git a/tests/ui/mir/lint/storage-live.stderr b/tests/ui/mir/lint/storage-live.stderr index 50df9ae061fc..c8d07314f075 100644 --- a/tests/ui/mir/lint/storage-live.stderr +++ b/tests/ui/mir/lint/storage-live.stderr @@ -1,19 +1,19 @@ error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (after pass CheckForceInline) at bb0[1]: StorageLive(_1) which already has storage here - --> $DIR/storage-live.rs:21:13 + --> $DIR/storage-live.rs:22:13 | LL | StorageLive(a); | ^^^^^^^^^^^^^^ | note: delayed at compiler/rustc_mir_transform/src/lint.rs:LL:CC - disabled backtrace - --> $DIR/storage-live.rs:21:13 + --> $DIR/storage-live.rs:22:13 | LL | StorageLive(a); | ^^^^^^^^^^^^^^ aborting due to `-Z treat-err-as-bug=1` -error: the compiler unexpectedly panicked. this is a bug. +error: the compiler unexpectedly panicked. This is a bug query stack during panic: end of query stack diff --git a/tests/ui/mir/mir_fat_ptr_drop.rs b/tests/ui/mir/mir_fat_ptr_drop.rs index ff6a0d70881f..b832d5a4ce9f 100644 --- a/tests/ui/mir/mir_fat_ptr_drop.rs +++ b/tests/ui/mir/mir_fat_ptr_drop.rs @@ -1,10 +1,7 @@ //@ run-pass #![allow(unused_variables)] -#![allow(stable_features)] // test that ordinary fat pointer operations work. - -#![feature(braced_empty_structs)] #![feature(rustc_attrs)] use std::sync::atomic; diff --git a/tests/ui/mir/validate/validate-unsize-cast.stderr b/tests/ui/mir/validate/validate-unsize-cast.stderr index 8449c6a24bd3..66dd5716826f 100644 --- a/tests/ui/mir/validate/validate-unsize-cast.stderr +++ b/tests/ui/mir/validate/validate-unsize-cast.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: Unsize` is not satisfied --> $DIR/validate-unsize-cast.rs:10:42 | LL | impl CastTo for T {} - | ^ the trait `Unsize` is not implemented for `T` + | ^ the nightly-only, unstable trait `Unsize` is not implemented for `T` | = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information note: required by a bound in `CastTo` diff --git a/tests/ui/mismatched_types/array-repeat-unit-struct.rs b/tests/ui/mismatched_types/array-repeat-unit-struct.rs new file mode 100644 index 000000000000..db05e1daedbd --- /dev/null +++ b/tests/ui/mismatched_types/array-repeat-unit-struct.rs @@ -0,0 +1,9 @@ +//! regression test for + +struct S; + +fn main() { + let b = [0; S]; + //~^ ERROR mismatched types + //~| NOTE expected `usize`, found `S` +} diff --git a/tests/ui/mismatched_types/array-repeat-unit-struct.stderr b/tests/ui/mismatched_types/array-repeat-unit-struct.stderr new file mode 100644 index 000000000000..9a9cc946f82a --- /dev/null +++ b/tests/ui/mismatched_types/array-repeat-unit-struct.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/array-repeat-unit-struct.rs:6:17 + | +LL | let b = [0; S]; + | ^ expected `usize`, found `S` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/mismatched_types/binops.stderr b/tests/ui/mismatched_types/binops.stderr index 504b44dfb7f6..ec2a951aac9a 100644 --- a/tests/ui/mismatched_types/binops.stderr +++ b/tests/ui/mismatched_types/binops.stderr @@ -26,13 +26,19 @@ LL | 2 as usize - Some(1); help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Sub` + = note: `usize` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Sub<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Sub` + = note: `&usize` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `{integer}` by `()` diff --git a/tests/ui/mismatched_types/cast-rfc0401.rs b/tests/ui/mismatched_types/cast-rfc0401.rs deleted file mode 100644 index b2ff5b4a0c06..000000000000 --- a/tests/ui/mismatched_types/cast-rfc0401.rs +++ /dev/null @@ -1,72 +0,0 @@ -fn illegal_cast(u: *const U) -> *const V -{ - u as *const V //~ ERROR is invalid -} - -fn illegal_cast_2(u: *const U) -> *const str -{ - u as *const str //~ ERROR is invalid -} - -trait Foo { fn foo(&self) {} } -impl Foo for T {} - -trait Bar { fn foo(&self) {} } -impl Bar for T {} - -enum E { - A, B -} - -fn main() -{ - let f: f32 = 1.2; - let v = core::ptr::null::(); - let fat_v : *const [u8] = unsafe { &*core::ptr::null::<[u8; 1]>()}; - let fat_sv : *const [i8] = unsafe { &*core::ptr::null::<[i8; 1]>()}; - let foo: &dyn Foo = &f; - - let _ = v as &u8; //~ ERROR non-primitive cast - let _ = v as E; //~ ERROR non-primitive cast - let _ = v as fn(); //~ ERROR non-primitive cast - let _ = v as (u32,); //~ ERROR non-primitive cast - let _ = Some(&v) as *const u8; //~ ERROR non-primitive cast - - let _ = v as f32; //~ ERROR is invalid - let _ = main as f64; //~ ERROR is invalid - let _ = &v as usize; //~ ERROR is invalid - let _ = f as *const u8; //~ ERROR is invalid - let _ = 3_i32 as bool; //~ ERROR cannot cast - let _ = E::A as bool; //~ ERROR cannot cast - let _ = 0x61u32 as char; //~ ERROR can be cast as - - let _ = false as f32; //~ ERROR is invalid - let _ = E::A as f32; //~ ERROR is invalid - let _ = 'a' as f32; //~ ERROR is invalid - - let _ = false as *const u8; //~ ERROR is invalid - let _ = E::A as *const u8; //~ ERROR is invalid - let _ = 'a' as *const u8; //~ ERROR is invalid - - let _ = 42usize as *const [u8]; //~ ERROR cannot cast `usize` to a pointer that is wide - let _ = v as *const [u8]; //~ ERROR cannot cast - let _ = fat_v as *const dyn Foo; //~ ERROR the size for values of type - let _ = foo as *const str; //~ ERROR is invalid - let _ = foo as *mut str; //~ ERROR is invalid - let _ = main as *mut str; //~ ERROR is invalid - let _ = &f as *mut f32; //~ ERROR is invalid - let _ = &f as *const f64; //~ ERROR is invalid - let _ = fat_sv as usize; //~ ERROR is invalid - - let a : *const str = "hello"; - let _ = a as *const dyn Foo; //~ ERROR the size for values of type - - // check no error cascade - let _ = main.f as *const u32; //~ ERROR no field - - let cf: *const dyn Foo = &0; - let _ = cf as *const [u16]; //~ ERROR is invalid - let _ = cf as *const dyn Bar; //~ ERROR casting `*const dyn Foo` as `*const dyn Bar` is invalid - - vec![0.0].iter().map(|s| s as f32).collect::>(); //~ ERROR is invalid -} diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr deleted file mode 100644 index a188b7791fdc..000000000000 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ /dev/null @@ -1,257 +0,0 @@ -error[E0606]: casting `*const U` as `*const V` is invalid - --> $DIR/cast-rfc0401.rs:3:5 - | -LL | u as *const V - | ^^^^^^^^^^^^^ - | - = note: the pointers may have different metadata - -error[E0606]: casting `*const U` as `*const str` is invalid - --> $DIR/cast-rfc0401.rs:8:5 - | -LL | u as *const str - | ^^^^^^^^^^^^^^^ - | - = note: the pointers may have different metadata - -error[E0609]: no field `f` on type `fn() {main}` - --> $DIR/cast-rfc0401.rs:65:18 - | -LL | let _ = main.f as *const u32; - | ^ unknown field - -error[E0605]: non-primitive cast: `*const u8` as `&u8` - --> $DIR/cast-rfc0401.rs:29:13 - | -LL | let _ = v as &u8; - | ^^^^^^^^ invalid cast - | -help: consider borrowing the value - | -LL - let _ = v as &u8; -LL + let _ = &*v; - | - -error[E0605]: non-primitive cast: `*const u8` as `E` - --> $DIR/cast-rfc0401.rs:30:13 - | -LL | let _ = v as E; - | ^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object - -error[E0605]: non-primitive cast: `*const u8` as `fn()` - --> $DIR/cast-rfc0401.rs:31:13 - | -LL | let _ = v as fn(); - | ^^^^^^^^^ invalid cast - -error[E0605]: non-primitive cast: `*const u8` as `(u32,)` - --> $DIR/cast-rfc0401.rs:32:13 - | -LL | let _ = v as (u32,); - | ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object - -error[E0605]: non-primitive cast: `Option<&*const u8>` as `*const u8` - --> $DIR/cast-rfc0401.rs:33:13 - | -LL | let _ = Some(&v) as *const u8; - | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object - -error[E0606]: casting `*const u8` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:35:13 - | -LL | let _ = v as f32; - | ^^^^^^^^ - -error[E0606]: casting `fn() {main}` as `f64` is invalid - --> $DIR/cast-rfc0401.rs:36:13 - | -LL | let _ = main as f64; - | ^^^^^^^^^^^ - -error[E0606]: casting `&*const u8` as `usize` is invalid - --> $DIR/cast-rfc0401.rs:37:13 - | -LL | let _ = &v as usize; - | ^^^^^^^^^^^ - | - = help: cast through a raw pointer first - -error[E0606]: casting `f32` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:38:13 - | -LL | let _ = f as *const u8; - | ^^^^^^^^^^^^^^ - -error[E0054]: cannot cast `i32` as `bool` - --> $DIR/cast-rfc0401.rs:39:13 - | -LL | let _ = 3_i32 as bool; - | ^^^^^^^^^^^^^ - | -help: compare with zero instead - | -LL - let _ = 3_i32 as bool; -LL + let _ = 3_i32 != 0; - | - -error[E0054]: cannot cast `E` as `bool` - --> $DIR/cast-rfc0401.rs:40:13 - | -LL | let _ = E::A as bool; - | ^^^^^^^^^^^^ unsupported cast - -error[E0604]: only `u8` can be cast as `char`, not `u32` - --> $DIR/cast-rfc0401.rs:41:13 - | -LL | let _ = 0x61u32 as char; - | ^^^^^^^^^^^^^^^ invalid cast - | -help: consider using `char::from_u32` instead - | -LL - let _ = 0x61u32 as char; -LL + let _ = char::from_u32(0x61u32); - | - -error[E0606]: casting `bool` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:43:13 - | -LL | let _ = false as f32; - | ^^^^^^^^^^^^ - | - = help: cast through an integer first - -error[E0606]: casting `E` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:44:13 - | -LL | let _ = E::A as f32; - | ^^^^^^^^^^^ - | - = help: cast through an integer first - -error[E0606]: casting `char` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:45:13 - | -LL | let _ = 'a' as f32; - | ^^^^^^^^^^ - | - = help: cast through an integer first - -error[E0606]: casting `bool` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:47:13 - | -LL | let _ = false as *const u8; - | ^^^^^^^^^^^^^^^^^^ - -error[E0606]: casting `E` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:48:13 - | -LL | let _ = E::A as *const u8; - | ^^^^^^^^^^^^^^^^^ - -error[E0606]: casting `char` as `*const u8` is invalid - --> $DIR/cast-rfc0401.rs:49:13 - | -LL | let _ = 'a' as *const u8; - | ^^^^^^^^^^^^^^^^ - -error[E0606]: cannot cast `usize` to a pointer that is wide - --> $DIR/cast-rfc0401.rs:51:24 - | -LL | let _ = 42usize as *const [u8]; - | ------- ^^^^^^^^^^^ creating a `*const [u8]` requires both an address and a length - | | - | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` - -error[E0607]: cannot cast thin pointer `*const u8` to wide pointer `*const [u8]` - --> $DIR/cast-rfc0401.rs:52:13 - | -LL | let _ = v as *const [u8]; - | ^^^^^^^^^^^^^^^^ - -error[E0606]: casting `&dyn Foo` as `*const str` is invalid - --> $DIR/cast-rfc0401.rs:54:13 - | -LL | let _ = foo as *const str; - | ^^^^^^^^^^^^^^^^^ - -error[E0606]: casting `&dyn Foo` as `*mut str` is invalid - --> $DIR/cast-rfc0401.rs:55:13 - | -LL | let _ = foo as *mut str; - | ^^^^^^^^^^^^^^^ - -error[E0606]: casting `fn() {main}` as `*mut str` is invalid - --> $DIR/cast-rfc0401.rs:56:13 - | -LL | let _ = main as *mut str; - | ^^^^^^^^^^^^^^^^ - -error[E0606]: casting `&f32` as `*mut f32` is invalid - --> $DIR/cast-rfc0401.rs:57:13 - | -LL | let _ = &f as *mut f32; - | ^^^^^^^^^^^^^^ - -error[E0606]: casting `&f32` as `*const f64` is invalid - --> $DIR/cast-rfc0401.rs:58:13 - | -LL | let _ = &f as *const f64; - | ^^^^^^^^^^^^^^^^ - -error[E0606]: casting `*const [i8]` as `usize` is invalid - --> $DIR/cast-rfc0401.rs:59:13 - | -LL | let _ = fat_sv as usize; - | ^^^^^^^^^^^^^^^ - | - = help: cast through a thin pointer first - -error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid - --> $DIR/cast-rfc0401.rs:68:13 - | -LL | let _ = cf as *const [u16]; - | ^^^^^^^^^^^^^^^^^^ - | - = note: the pointers have different metadata - -error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid - --> $DIR/cast-rfc0401.rs:69:13 - | -LL | let _ = cf as *const dyn Bar; - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: the trait objects may have different vtables - -error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/cast-rfc0401.rs:53:13 - | -LL | let _ = fat_v as *const dyn Foo; - | ^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[u8]` - = note: required for the cast from `*const [u8]` to `*const dyn Foo` - -error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/cast-rfc0401.rs:62:13 - | -LL | let _ = a as *const dyn Foo; - | ^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `str` - = note: required for the cast from `*const str` to `*const dyn Foo` - -error[E0606]: casting `&{float}` as `f32` is invalid - --> $DIR/cast-rfc0401.rs:71:30 - | -LL | vec![0.0].iter().map(|s| s as f32).collect::>(); - | ^^^^^^^^ - | -help: dereference the expression - | -LL | vec![0.0].iter().map(|s| *s as f32).collect::>(); - | + - -error: aborting due to 34 previous errors - -Some errors have detailed explanations: E0054, E0277, E0604, E0605, E0606, E0607, E0609. -For more information about an error, try `rustc --explain E0054`. diff --git a/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr index b2d0ffc4710e..54b536744f75 100644 --- a/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr +++ b/tests/ui/mismatched_types/float-integer-subtraction-error-24352.stderr @@ -8,13 +8,19 @@ LL | 1.0f64 - 1 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | diff --git a/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr b/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr index 2a8f9867abb8..09ba15253dc5 100644 --- a/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr +++ b/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr @@ -4,7 +4,6 @@ error[E0308]: mismatched types LL | x => dbg!(x), | ^^^^^^^ expected `()`, found integer | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might have meant to return this value | LL | x => return dbg!(x), @@ -16,7 +15,6 @@ error[E0308]: mismatched types LL | dbg!(x) | ^^^^^^^ expected `()`, found integer | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might have meant to return this value | LL | return dbg!(x) @@ -28,7 +26,6 @@ error[E0308]: mismatched types LL | _ => dbg!(1) | ^^^^^^^ expected `()`, found integer | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might have meant to return this value | LL | _ => return dbg!(1) @@ -40,7 +37,6 @@ error[E0308]: mismatched types LL | _ => {dbg!(1)} | ^^^^^^^ expected `()`, found integer | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: you might have meant to return this value | LL | _ => {return dbg!(1)} diff --git a/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs b/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs new file mode 100644 index 000000000000..3724a423d0dd --- /dev/null +++ b/tests/ui/mismatched_types/vec-hashset-type-mismatch.rs @@ -0,0 +1,13 @@ +//! regression test for +//@ dont-require-annotations: NOTE + +use std::collections::HashSet; + +fn main() { + let mut v = Vec::new(); + foo(&mut v); + //~^ ERROR mismatched types + //~| NOTE expected `&mut HashSet`, found `&mut Vec<_>` +} + +fn foo(h: &mut HashSet) {} diff --git a/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr b/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr new file mode 100644 index 000000000000..e778422d0064 --- /dev/null +++ b/tests/ui/mismatched_types/vec-hashset-type-mismatch.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/vec-hashset-type-mismatch.rs:8:9 + | +LL | foo(&mut v); + | --- ^^^^^^ expected `&mut HashSet`, found `&mut Vec<_>` + | | + | arguments to this function are incorrect + | + = note: expected mutable reference `&mut HashSet` + found mutable reference `&mut Vec<_>` +note: function defined here + --> $DIR/vec-hashset-type-mismatch.rs:13:4 + | +LL | fn foo(h: &mut HashSet) {} + | ^^^ -------------------- + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/missing-trait-bounds/issue-69725.stderr b/tests/ui/missing-trait-bounds/issue-69725.stderr index f483ea849b0e..20d2213f4f5f 100644 --- a/tests/ui/missing-trait-bounds/issue-69725.stderr +++ b/tests/ui/missing-trait-bounds/issue-69725.stderr @@ -1,17 +1,17 @@ -error[E0599]: the method `clone` exists for struct `Struct`, but its trait bounds were not satisfied +error[E0599]: the method `clone` exists for struct `issue_69725::Struct`, but its trait bounds were not satisfied --> $DIR/issue-69725.rs:9:32 | LL | let _ = Struct::::new().clone(); - | ^^^^^ method cannot be called on `Struct` due to unsatisfied trait bounds + | ^^^^^ method cannot be called on `issue_69725::Struct` due to unsatisfied trait bounds | ::: $DIR/auxiliary/issue-69725.rs:2:1 | LL | pub struct Struct(A); - | -------------------- doesn't satisfy `Struct: Clone` + | -------------------- doesn't satisfy `issue_69725::Struct: Clone` | = note: the following trait bounds were not satisfied: `A: Clone` - which is required by `Struct: Clone` + which is required by `issue_69725::Struct: Clone` help: consider restricting the type parameter to satisfy the trait bound | LL | fn crash() where A: Clone { diff --git a/tests/ui/missing/missing-let.rs b/tests/ui/missing/missing-let.rs new file mode 100644 index 000000000000..595de640470b --- /dev/null +++ b/tests/ui/missing/missing-let.rs @@ -0,0 +1,18 @@ +fn main() { + let x = Some(42); + let y = Some(42); + let z = Some(42); + if let Some(_) = x + && Some(x) = x //~^ ERROR expected expression, found `let` statement + //~| NOTE: only supported directly in conditions of `if` and `while` expressions + {} + + if Some(_) = y && + //~^ NOTE expected `let` expression, found assignment + //~| ERROR let-chain with missing `let` + let Some(_) = z + //~^ ERROR: expected expression, found `let` statement + //~| NOTE: let expression later in the condition + //~| NOTE: only supported directly in conditions of `if` and `while` expressions + {} +} diff --git a/tests/ui/missing/missing-let.stderr b/tests/ui/missing/missing-let.stderr new file mode 100644 index 000000000000..0a6e76b154f7 --- /dev/null +++ b/tests/ui/missing/missing-let.stderr @@ -0,0 +1,42 @@ +error: expected expression, found `let` statement + --> $DIR/missing-let.rs:5:8 + | +LL | if let Some(_) = x + | ^^^^^^^^^^^^^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions +help: you might have meant to continue the let-chain + | +LL | && let Some(x) = x + | +++ +help: you might have meant to compare for equality + | +LL | && Some(x) == x + | + + +error: expected expression, found `let` statement + --> $DIR/missing-let.rs:13:9 + | +LL | let Some(_) = z + | ^^^ + | + = note: only supported directly in conditions of `if` and `while` expressions + +error: let-chain with missing `let` + --> $DIR/missing-let.rs:10:8 + | +LL | if Some(_) = y && + | ^^^^^^^---- + | | + | expected `let` expression, found assignment +... +LL | let Some(_) = z + | --------------- let expression later in the condition + | +help: add `let` before the expression + | +LL | if let Some(_) = y && + | +++ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/modules/issue-107649.rs b/tests/ui/modules/issue-107649.rs index f93fb07e17af..731c2c0592a1 100644 --- a/tests/ui/modules/issue-107649.rs +++ b/tests/ui/modules/issue-107649.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z ui-testing=no +//@ compile-flags: -Z ui-testing=no --diagnostic-width=80 #[path = "auxiliary/dummy_lib.rs"] mod lib; diff --git a/tests/ui/modules/issue-107649.stderr b/tests/ui/modules/issue-107649.stderr index 49d7cb4e0aad..40dda93ad015 100644 --- a/tests/ui/modules/issue-107649.stderr +++ b/tests/ui/modules/issue-107649.stderr @@ -5,7 +5,6 @@ error[E0277]: `Dummy` doesn't implement `Debug` | ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `Dummy` | = note: add `#[derive(Debug)]` to `Dummy` or manually `impl Debug for Dummy` - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Dummy` with `#[derive(Debug)]` --> $DIR/auxiliary/dummy_lib.rs:2:1 | diff --git a/tests/ui/modules/super-at-crate-root.rs b/tests/ui/modules/super-at-crate-root.rs index d605dc0cccb3..0aac3a087570 100644 --- a/tests/ui/modules/super-at-crate-root.rs +++ b/tests/ui/modules/super-at-crate-root.rs @@ -1,6 +1,6 @@ //! Check that `super` keyword used at the crate root (top-level) results in a compilation error //! as there is no parent module to resolve. -use super::f; //~ ERROR there are too many leading `super` keywords +use super::f; //~ ERROR too many leading `super` keywords fn main() {} diff --git a/tests/ui/modules/super-at-crate-root.stderr b/tests/ui/modules/super-at-crate-root.stderr index 027987088646..cb3855cc033d 100644 --- a/tests/ui/modules/super-at-crate-root.stderr +++ b/tests/ui/modules/super-at-crate-root.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: too many leading `super` keywords --> $DIR/super-at-crate-root.rs:4:5 | LL | use super::f; diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.rs b/tests/ui/moves/arc-consumed-in-looped-closure.rs new file mode 100644 index 000000000000..8700c7850847 --- /dev/null +++ b/tests/ui/moves/arc-consumed-in-looped-closure.rs @@ -0,0 +1,37 @@ +use std::thread; +use std::sync::{Arc, Mutex, Condvar}; +use std::collections::VecDeque; + +type Job = Box; + +struct ThreadPool { + workers: Vec>, + queue: Arc<()>, +} + +impl ThreadPool { + fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + panic!() + } +} + +fn main() { + let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE move occurs because + let pool = ThreadPool { + workers: vec![], + queue: Arc::new(()), + }; + + for i in 0..20 { //~ NOTE inside of this loop + // let results = Arc::clone(&results); // Forgot this. + pool.execute(move || { //~ ERROR E0382 + //~^ NOTE value moved into closure here, in previous iteration of loop + //~| HELP consider cloning the value before moving it into the closure + let mut r = results.lock().unwrap(); //~ NOTE use occurs due to use in closure + r.push(i); + }); + } +} diff --git a/tests/ui/moves/arc-consumed-in-looped-closure.stderr b/tests/ui/moves/arc-consumed-in-looped-closure.stderr new file mode 100644 index 000000000000..47d6fd6cbad3 --- /dev/null +++ b/tests/ui/moves/arc-consumed-in-looped-closure.stderr @@ -0,0 +1,27 @@ +error[E0382]: use of moved value: `results` + --> $DIR/arc-consumed-in-looped-closure.rs:30:22 + | +LL | let results = Arc::new(Mutex::new(Vec::new())); + | ------- move occurs because `results` has type `Arc>>`, which does not implement the `Copy` trait +... +LL | for i in 0..20 { + | -------------- inside of this loop +LL | // let results = Arc::clone(&results); // Forgot this. +LL | pool.execute(move || { + | ^^^^^^^ value moved into closure here, in previous iteration of loop +... +LL | let mut r = results.lock().unwrap(); + | ------- use occurs due to use in closure + | +help: consider cloning the value before moving it into the closure + | +LL ~ let value = results.clone(); +LL ~ pool.execute(move || { +LL | +LL | +LL ~ let mut r = value.lock().unwrap(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/moves/array-copy-move.rs b/tests/ui/moves/array-copy-move.rs new file mode 100644 index 000000000000..ea95bc06a369 --- /dev/null +++ b/tests/ui/moves/array-copy-move.rs @@ -0,0 +1,8 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/16783 +//@ run-pass +#![allow(unused_variables)] + +pub fn main() { + let x = [1, 2, 3]; + let y = x; +} diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr index 301f3c3a458d..5de99cc6ca6a 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.current.stderr @@ -13,7 +13,8 @@ note: `HashSet` does not implement `Clone`, so `&HashSet` was cloned i | LL | let mut x: HashSet = v.clone(); | ^ - = help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied +help: `Clone` is not implemented because a trait bound is not satisfied + --> $SRC_DIR/std/src/collections/hash/set.rs:LL:COL help: consider annotating `Day` with `#[derive(Clone)]` | LL + #[derive(Clone)] diff --git a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr index 301f3c3a458d..5de99cc6ca6a 100644 --- a/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr +++ b/tests/ui/moves/assignment-of-clone-call-on-ref-due-to-missing-bound.next.stderr @@ -13,7 +13,8 @@ note: `HashSet` does not implement `Clone`, so `&HashSet` was cloned i | LL | let mut x: HashSet = v.clone(); | ^ - = help: `Clone` is not implemented because the trait bound `Day: Clone` is not satisfied +help: `Clone` is not implemented because a trait bound is not satisfied + --> $SRC_DIR/std/src/collections/hash/set.rs:LL:COL help: consider annotating `Day` with `#[derive(Clone)]` | LL + #[derive(Clone)] diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.rs b/tests/ui/moves/issue-72649-uninit-in-loop.rs index 8f2e01bdf1ab..f115656d7c0d 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.rs +++ b/tests/ui/moves/issue-72649-uninit-in-loop.rs @@ -70,6 +70,7 @@ fn moved_loop_2() { fn uninit_1() { loop { let value: NonCopy; //~ NOTE declared here + //~^ HELP consider assigning a value let _used = value; //~ ERROR binding `value` isn't initialized //~^ NOTE `value` used here but it isn't initialized } @@ -77,6 +78,7 @@ fn uninit_1() { fn uninit_2() { let mut value: NonCopy; //~ NOTE declared here + //~^ HELP consider assigning a value loop { let _used = value; //~ ERROR binding `value` isn't initialized //~^ NOTE `value` used here but it isn't initialized diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.stderr b/tests/ui/moves/issue-72649-uninit-in-loop.stderr index 3a93769ac454..8bde3b5c042d 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/tests/ui/moves/issue-72649-uninit-in-loop.stderr @@ -83,10 +83,11 @@ LL | let _used2 = value; | ----- you could clone this value error[E0381]: used binding `value` isn't initialized - --> $DIR/issue-72649-uninit-in-loop.rs:73:21 + --> $DIR/issue-72649-uninit-in-loop.rs:74:21 | LL | let value: NonCopy; | ----- binding declared here but left uninitialized +LL | LL | let _used = value; | ^^^^^ `value` used here but it isn't initialized | @@ -96,11 +97,11 @@ LL | let value: NonCopy = /* value */; | +++++++++++++ error[E0381]: used binding `value` isn't initialized - --> $DIR/issue-72649-uninit-in-loop.rs:81:21 + --> $DIR/issue-72649-uninit-in-loop.rs:83:21 | LL | let mut value: NonCopy; | --------- binding declared here but left uninitialized -LL | loop { +... LL | let _used = value; | ^^^^^ `value` used here but it isn't initialized | diff --git a/tests/ui/moves/moves-based-on-type-capture-clause-bad.stderr b/tests/ui/moves/moves-based-on-type-capture-clause-bad.stderr index 17049fe67318..ba729493c9b7 100644 --- a/tests/ui/moves/moves-based-on-type-capture-clause-bad.stderr +++ b/tests/ui/moves/moves-based-on-type-capture-clause-bad.stderr @@ -11,7 +11,6 @@ LL | }); LL | println!("{}", x); | ^ value borrowed here after move | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value before moving it into the closure | LL ~ let value = x.clone(); diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs index 87800d314ed5..0cbb501a5764 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs @@ -7,8 +7,6 @@ fn foo() { //~^ NOTE this reinitialization might get skipped //~| NOTE move occurs because `foo` has type `String` //~| NOTE inside of this loop - //~| HELP consider moving the expression out of the loop - //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE //~| NOTE baz.push(foo); @@ -35,8 +33,6 @@ fn main() { //~| NOTE for bar in &bars { //~^ NOTE inside of this loop - //~| HELP consider moving the expression out of the loop - //~| NOTE in this expansion of desugaring of `for` loop //~| NOTE if foo == *bar { baz.push(foo); @@ -44,7 +40,7 @@ fn main() { //~| HELP consider cloning the value continue; //~^ NOTE verify that your loop breaking logic is correct - //~| NOTE this `continue` advances the loop at line 36 + //~| NOTE this `continue` advances the loop at line 34 } } qux.push(foo); diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr index 6ef1a4193b1a..60be70007fbe 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:21:14 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:19:14 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --- ---------------- inside of this loop @@ -14,29 +14,20 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:17:9 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:15:9 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --------------- ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 20:8 -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ for foo in foos { let mut value = baz.push(foo); -LL ~ for bar in &bars { if foo == *bar { -LL | -... -LL | -LL ~ value; - | + | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 18:8 help: consider cloning the value if the performance cost is acceptable | LL | baz.push(foo.clone()); | ++++++++ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:50:18 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18 | LL | for foo in foos { | --- @@ -54,7 +45,7 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:45:17 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17 | LL | for foo in foos { | --------------- @@ -63,16 +54,7 @@ LL | for bar in &bars { | ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at line 36 -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ let mut value = baz.push(foo); -LL ~ for bar in &bars { -LL | -... -LL | if foo == *bar { -LL ~ value; - | + | ^^^^^^^^ this `continue` advances the loop at line 34 help: consider cloning the value if the performance cost is acceptable | LL | baz.push(foo.clone()); diff --git a/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr b/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr index 6272455cc57e..af0f67b7c1c0 100644 --- a/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr +++ b/tests/ui/moves/suggest-clone-when-some-obligation-is-unmet.stderr @@ -6,7 +6,7 @@ LL | let mut copy: Vec = map.clone().into_values().collect(); | | | move occurs because value has type `HashMap`, which does not implement the `Copy` trait | -note: `HashMap::::into_values` takes ownership of the receiver `self`, which moves value +note: `HashMap::::into_values` takes ownership of the receiver `self`, which moves value --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL note: if `Hash128_1` implemented `Clone`, you could clone the value --> $DIR/suggest-clone-when-some-obligation-is-unmet.rs:8:1 diff --git a/tests/ui/never_type/issue-13352.stderr b/tests/ui/never_type/issue-13352.stderr index 344625af683a..5fcbb4aab993 100644 --- a/tests/ui/never_type/issue-13352.stderr +++ b/tests/ui/never_type/issue-13352.stderr @@ -8,13 +8,19 @@ LL | 2_usize + (loop {}); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: `usize` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Add<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Add` + = note: `&usize` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/never_type/never-deref.rs b/tests/ui/never_type/never-deref.rs new file mode 100644 index 000000000000..6e4b89db04a5 --- /dev/null +++ b/tests/ui/never_type/never-deref.rs @@ -0,0 +1,5 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17373 +fn main() { + *return //~ ERROR type `!` cannot be dereferenced + ; +} diff --git a/tests/ui/never_type/never-deref.stderr b/tests/ui/never_type/never-deref.stderr new file mode 100644 index 000000000000..76f31f377987 --- /dev/null +++ b/tests/ui/never_type/never-deref.stderr @@ -0,0 +1,9 @@ +error[E0614]: type `!` cannot be dereferenced + --> $DIR/never-deref.rs:3:5 + | +LL | *return + | ^^^^^^^ can't be dereferenced + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0614`. diff --git a/tests/ui/never_type/try-block-never-type-fallback.e2021.stderr b/tests/ui/never_type/try-block-never-type-fallback.e2021.stderr new file mode 100644 index 000000000000..7e23c86bcbcc --- /dev/null +++ b/tests/ui/never_type/try-block-never-type-fallback.e2021.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `!: From<()>` is not satisfied + --> $DIR/try-block-never-type-fallback.rs:20:9 + | +LL | bar(try { x? }); + | --- ^^^^^^^^^^ the trait `From<()>` is not implemented for `!` + | | + | required by a bound introduced by this call + | + = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #148922 for more information) + = help: you might have intended to use the type `()` here instead + = note: required for `()` to implement `Into` +note: required by a bound in `bar` + --> $DIR/try-block-never-type-fallback.rs:15:23 + | +LL | fn bar(_: Result, u32>) { + | ^^^^^^^ required by this bound in `bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/never_type/try-block-never-type-fallback.rs b/tests/ui/never_type/try-block-never-type-fallback.rs new file mode 100644 index 000000000000..94107a0ff103 --- /dev/null +++ b/tests/ui/never_type/try-block-never-type-fallback.rs @@ -0,0 +1,25 @@ +//@ revisions: e2021 e2024 +//@[e2021] edition: 2021 +//@[e2024] edition: 2024 +//@[e2024] check-pass + +// Issue #125364: Bad interaction between never_type, try_blocks, and From/Into +// +// In edition 2021, the never type in try blocks falls back to (), +// causing a type error (since (): Into does not hold). +// In edition 2024, it falls back to !, allowing the code to compile correctly. + +#![feature(never_type)] +#![feature(try_blocks)] + +fn bar(_: Result, u32>) { + unimplemented!() +} + +fn foo(x: Result) { + bar(try { x? }); + //[e2021]~^ ERROR the trait bound `!: From<()>` is not satisfied +} + +fn main() { +} diff --git a/tests/ui/new-range/disabled.rs b/tests/ui/new-range/disabled.rs index 6ba29f5ca9a2..ab6fbd3276b3 100644 --- a/tests/ui/new-range/disabled.rs +++ b/tests/ui/new-range/disabled.rs @@ -4,11 +4,12 @@ fn main() { // Unchanged - let a: core::range::RangeFull = ..; - let b: core::range::RangeTo = ..2; + let a: core::ops::RangeFull = ..; + let b: core::ops::RangeTo = ..2; - let _: core::ops::RangeFull = a; - let _: core::ops::RangeTo = b; + // FIXME(#125687): re-exports temporarily removed + // let _: core::range::RangeFull = a; + // let _: core::range::RangeTo = b; // Changed let a: core::range::legacy::RangeFrom = 1..; diff --git a/tests/ui/new-range/enabled.rs b/tests/ui/new-range/enabled.rs index 140e3b648709..b49681eaacde 100644 --- a/tests/ui/new-range/enabled.rs +++ b/tests/ui/new-range/enabled.rs @@ -5,11 +5,12 @@ fn main() { // Unchanged - let a: core::range::RangeFull = ..; - let b: core::range::RangeTo = ..2; + let a: core::ops::RangeFull = ..; + let b: core::ops::RangeTo = ..2; - let _: core::ops::RangeFull = a; - let _: core::ops::RangeTo = b; + // FIXME(#125687): re-exports temporarily removed + // let _: core::range::RangeFull = a; + // let _: core::range::RangeTo = b; // Changed let a: core::range::RangeFrom = 1..; diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.rs b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.rs new file mode 100644 index 000000000000..addfc7b91391 --- /dev/null +++ b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.rs @@ -0,0 +1,51 @@ +// Test that we can propagate multiple region errors for closure constraints +// where the longer region has multiple non-local lower bounds without any postdominating one. +//@ compile-flags:-Zverbose-internals + +#![feature(rustc_attrs)] + +use std::cell::Cell; + +// Callee knows that: +// +// 'x: 'a +// 'x: 'b +// 'c: 'y +// +// we have to prove that `'x: 'y`. We find non-local lower bounds of 'x to be 'a and 'b and +// non-local upper bound of 'y to be 'c. So we propagate `'b: 'c` and `'a: 'c`. +fn establish_relationships<'a, 'b, 'c, F>( + _cell_a: Cell<&'a u32>, + _cell_b: Cell<&'b u32>, + _cell_c: Cell<&'c u32>, + _closure: F, +) where + F: for<'x, 'y> FnMut( + Cell<&'a &'x u32>, // shows that 'x: 'a + Cell<&'b &'x u32>, // shows that 'x: 'b + Cell<&'y &'c u32>, // shows that 'c: 'y + Cell<&'x u32>, + Cell<&'y u32>, + ), +{ +} + +fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {} + +#[rustc_regions] +fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + //~vv ERROR lifetime may not live long enough + //~v ERROR lifetime may not live long enough + establish_relationships( + cell_a, + cell_b, + cell_c, + |_outlives1, _outlives2, _outlives3, x, y| { + // Only works if 'x: 'y: + let p = x.get(); + demand_y(x, y, p) + }, + ); +} + +fn main() {} diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.stderr new file mode 100644 index 000000000000..af7ea253cc52 --- /dev/null +++ b/tests/ui/nll/closure-requirements/propagate-approximated-both-lower-bounds.stderr @@ -0,0 +1,79 @@ +note: external requirements + --> $DIR/propagate-approximated-both-lower-bounds.rs:43:9 + | +LL | |_outlives1, _outlives2, _outlives3, x, y| { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: supply::{closure#0} with closure args [ + i16, + for extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'?2 &'^0 u32>, std::cell::Cell<&'^1 &'?3 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)), + (), + ] + = note: late-bound region is '?7 + = note: late-bound region is '?8 + = note: late-bound region is '?4 + = note: late-bound region is '?5 + = note: late-bound region is '?6 + = note: number of external vids: 7 + = note: where '?2: '?3 + = note: where '?1: '?3 + +note: no external requirements + --> $DIR/propagate-approximated-both-lower-bounds.rs:36:1 + | +LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: defining type: supply + +error: lifetime may not live long enough + --> $DIR/propagate-approximated-both-lower-bounds.rs:39:5 + | +LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'a` defined here +... +LL | / establish_relationships( +LL | | cell_a, +LL | | cell_b, +LL | | cell_c, +... | +LL | | }, +LL | | ); + | |_____^ argument requires that `'a` must outlive `'c` + | + = help: consider adding the following bound: `'a: 'c` + = note: requirement occurs because of the type `Cell<&'?10 u32>`, which makes the generic argument `&'?10 u32` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance + +error: lifetime may not live long enough + --> $DIR/propagate-approximated-both-lower-bounds.rs:39:5 + | +LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { + | -- -- lifetime `'c` defined here + | | + | lifetime `'b` defined here +... +LL | / establish_relationships( +LL | | cell_a, +LL | | cell_b, +LL | | cell_c, +... | +LL | | }, +LL | | ); + | |_____^ argument requires that `'b` must outlive `'c` + | + = help: consider adding the following bound: `'b: 'c` + = note: requirement occurs because of the type `Cell<&'?10 u32>`, which makes the generic argument `&'?10 u32` invariant + = note: the struct `Cell` is invariant over the parameter `T` + = help: see for more information about variance + +help: the following changes may resolve your lifetime errors + | + = help: add bound `'a: 'c` + = help: add bound `'b: 'c` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs deleted file mode 100644 index 5d21fa100a43..000000000000 --- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Test where we fail to approximate due to demanding a postdom -// relationship between our upper bounds. - -//@ compile-flags:-Zverbose-internals - -#![feature(rustc_attrs)] - -use std::cell::Cell; - -// Callee knows that: -// -// 'x: 'a -// 'x: 'b -// 'c: 'y -// -// we have to prove that `'x: 'y`. We currently can only approximate -// via a postdominator -- hence we fail to choose between `'a` and -// `'b` here and report the error in the closure. -fn establish_relationships<'a, 'b, 'c, F>( - _cell_a: Cell<&'a u32>, - _cell_b: Cell<&'b u32>, - _cell_c: Cell<&'c u32>, - _closure: F, -) where - F: for<'x, 'y> FnMut( - Cell<&'a &'x u32>, // shows that 'x: 'a - Cell<&'b &'x u32>, // shows that 'x: 'b - Cell<&'y &'c u32>, // shows that 'c: 'y - Cell<&'x u32>, - Cell<&'y u32>, - ), -{ -} - -fn demand_y<'x, 'y>(_cell_x: Cell<&'x u32>, _cell_y: Cell<&'y u32>, _y: &'y u32) {} - -#[rustc_regions] -fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { - establish_relationships( - cell_a, - cell_b, - cell_c, - |_outlives1, _outlives2, _outlives3, x, y| { - // Only works if 'x: 'y: - let p = x.get(); - demand_y(x, y, p) //~ ERROR - }, - ); -} - -fn main() {} diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr deleted file mode 100644 index 134ce99014d8..000000000000 --- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ /dev/null @@ -1,42 +0,0 @@ -note: no external requirements - --> $DIR/propagate-approximated-fail-no-postdom.rs:43:9 - | -LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: supply::{closure#0} with closure args [ - i16, - for extern "rust-call" fn((std::cell::Cell<&'?1 &'^0 u32>, std::cell::Cell<&'?2 &'^0 u32>, std::cell::Cell<&'^1 &'?3 u32>, std::cell::Cell<&'^0 u32>, std::cell::Cell<&'^1 u32>)), - (), - ] - = note: late-bound region is '?7 - = note: late-bound region is '?8 - = note: late-bound region is '?4 - = note: late-bound region is '?5 - = note: late-bound region is '?6 - -error: lifetime may not live long enough - --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13 - | -LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ---------- ---------- has type `Cell<&'2 &'?3 u32>` - | | - | has type `Cell<&'?1 &'1 u32>` -... -LL | demand_y(x, y, p) - | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - | - = note: requirement occurs because of the type `Cell<&'?34 u32>`, which makes the generic argument `&'?34 u32` invariant - = note: the struct `Cell` is invariant over the parameter `T` - = help: see for more information about variance - -note: no external requirements - --> $DIR/propagate-approximated-fail-no-postdom.rs:38:1 - | -LL | fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: defining type: supply - -error: aborting due to 1 previous error - diff --git a/tests/ui/nll/issue-112604-closure-output-normalize.rs b/tests/ui/nll/issue-112604-closure-output-normalize.rs index 117e1d91e341..c99900759917 100644 --- a/tests/ui/nll/issue-112604-closure-output-normalize.rs +++ b/tests/ui/nll/issue-112604-closure-output-normalize.rs @@ -1,4 +1,7 @@ //@check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver use higher_kinded_types::*; mod higher_kinded_types { diff --git a/tests/ui/nll/issue-98693.stderr b/tests/ui/nll/issue-98693.stderr index b5e281538f9c..cf69fbd5aeed 100644 --- a/tests/ui/nll/issue-98693.stderr +++ b/tests/ui/nll/issue-98693.stderr @@ -2,7 +2,7 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/issue-98693.rs:16:9 | LL | assert_static::(); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | | | the parameter type `T` must be valid for the static lifetime... | ...so that the type `T` will meet its required lifetime bounds diff --git a/tests/ui/nll/nll-anon-to-static.rs b/tests/ui/nll/nll-anon-to-static.rs new file mode 100644 index 000000000000..3dc79950056c --- /dev/null +++ b/tests/ui/nll/nll-anon-to-static.rs @@ -0,0 +1,7 @@ +//! regression test for issue +fn foo(x: &u32) -> &'static u32 { + &*x + //~^ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/nll/nll-anon-to-static.stderr b/tests/ui/nll/nll-anon-to-static.stderr new file mode 100644 index 000000000000..e431dfd992e1 --- /dev/null +++ b/tests/ui/nll/nll-anon-to-static.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/nll-anon-to-static.rs:3:5 + | +LL | fn foo(x: &u32) -> &'static u32 { + | - let's call the lifetime of this reference `'1` +LL | &*x + | ^^^ returning this value requires that `'1` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr index dc38b8c127e5..0ab90faabcf0 100644 --- a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.nll.stderr @@ -35,8 +35,21 @@ LL | | } LL | | } | |_____- returning this value requires that `*map` is borrowed for `'r` +error[E0499]: cannot borrow `*map` as mutable more than once at a time + --> $DIR/nll-problem-case-3-issue-21906.rs:45:41 + | +LL | fn get_priority_mut_entry<'a, K, V>( + | -- lifetime `'a` defined here +... +LL | match map.entry(key1) { + | --- first mutable borrow occurs here +LL | Entry::Occupied(occupied) => Some(occupied.into_mut()), + | ------------------------- returning this value requires that `*map` is borrowed for `'a` +LL | Entry::Vacant(_vacant) => match map.entry(key2) { + | ^^^ second mutable borrow occurs here + error[E0499]: cannot borrow `*self` as mutable more than once at a time - --> $DIR/nll-problem-case-3-issue-21906.rs:44:21 + --> $DIR/nll-problem-case-3-issue-21906.rs:64:21 | LL | fn two(&mut self) -> &i32 { | - let's call the lifetime of this reference `'1` @@ -48,7 +61,7 @@ LL | return k; | - returning this value requires that `*self` is borrowed for `'1` error[E0502]: cannot borrow `x.data` as immutable because it is also borrowed as mutable - --> $DIR/nll-problem-case-3-issue-21906.rs:62:22 + --> $DIR/nll-problem-case-3-issue-21906.rs:82:22 | LL | fn foo(x: &mut Foo) -> Option<&mut i32> { | - let's call the lifetime of this reference `'1` @@ -59,11 +72,9 @@ LL | return Some(y); ... LL | println!("{:?}", x.data); | ^^^^^^ immutable borrow occurs here - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0499]: cannot borrow `*vec` as mutable more than once at a time - --> $DIR/nll-problem-case-3-issue-21906.rs:77:9 + --> $DIR/nll-problem-case-3-issue-21906.rs:97:9 | LL | fn f(vec: &mut Vec) -> &u8 { | - let's call the lifetime of this reference `'1` @@ -77,7 +88,7 @@ LL | vec.push(10); | ^^^ second mutable borrow occurs here error[E0502]: cannot borrow `*vec` as immutable because it is also borrowed as mutable - --> $DIR/nll-problem-case-3-issue-21906.rs:78:9 + --> $DIR/nll-problem-case-3-issue-21906.rs:98:9 | LL | fn f(vec: &mut Vec) -> &u8 { | - let's call the lifetime of this reference `'1` @@ -90,7 +101,7 @@ LL | n LL | vec.last().unwrap() | ^^^ immutable borrow occurs here -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0499, E0502. For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs index b025ea78f8b4..45b56e32522f 100644 --- a/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs +++ b/tests/ui/nll/polonius/nll-problem-case-3-issue-21906.rs @@ -29,6 +29,26 @@ fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>( } } +// A variant that's similar to the RFC example above, but using the entry API, and requested in +// https://internals.rust-lang.org/t/get-mut-map-back-from-entry-api/24003 +fn get_priority_mut_entry<'a, K, V>( + map: &'a mut HashMap, + key1: K, + key2: K, +) -> Option<&'a mut V> +where + K: Eq + Hash, +{ + use std::collections::hash_map::Entry; + match map.entry(key1) { + Entry::Occupied(occupied) => Some(occupied.into_mut()), + Entry::Vacant(_vacant) => match map.entry(key2) { + Entry::Occupied(occupied2) => Some(occupied2.into_mut()), + Entry::Vacant(_) => None, + }, + } +} + // MCVE 1 from issue #21906 struct A { a: i32, diff --git a/tests/ui/nll/type-test-universe.stderr b/tests/ui/nll/type-test-universe.stderr index 54b48c1597bd..c9dcb69f08f5 100644 --- a/tests/ui/nll/type-test-universe.stderr +++ b/tests/ui/nll/type-test-universe.stderr @@ -2,7 +2,7 @@ error: `S` does not live long enough --> $DIR/type-test-universe.rs:11:5 | LL | outlives_forall::(); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ error: lifetime may not live long enough --> $DIR/type-test-universe.rs:17:5 diff --git a/tests/ui/nll/user-annotations/patterns.rs b/tests/ui/nll/user-annotations/patterns.rs index 1f635d7f50cd..07f78430f67c 100644 --- a/tests/ui/nll/user-annotations/patterns.rs +++ b/tests/ui/nll/user-annotations/patterns.rs @@ -70,6 +70,11 @@ fn underscore_with_initializer() { //~^ ERROR temporary value dropped while borrowed [E0716] } +fn issue_47184() { + let _vec: Vec<&'static String> = vec![&String::new()]; + //~^ ERROR temporary value dropped while borrowed [E0716] +} + fn pair_underscores_with_initializer() { let x = 22; let (_, _): (&'static u32, u32) = (&x, 44); //~ ERROR diff --git a/tests/ui/nll/user-annotations/patterns.stderr b/tests/ui/nll/user-annotations/patterns.stderr index 8bb714f1d0cd..325af6a52a0e 100644 --- a/tests/ui/nll/user-annotations/patterns.stderr +++ b/tests/ui/nll/user-annotations/patterns.stderr @@ -111,8 +111,17 @@ LL | let (_a, b): (Vec<&'static String>, _) = (vec![&String::new()], 44); | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` +error[E0716]: temporary value dropped while borrowed + --> $DIR/patterns.rs:74:44 + | +LL | let _vec: Vec<&'static String> = vec![&String::new()]; + | -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | type annotation requires that borrow lasts for `'static` + error[E0597]: `x` does not live long enough - --> $DIR/patterns.rs:75:40 + --> $DIR/patterns.rs:80:40 | LL | let x = 22; | - binding `x` declared here @@ -124,7 +133,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/patterns.rs:80:40 + --> $DIR/patterns.rs:85:40 | LL | let x = 22; | - binding `x` declared here @@ -136,7 +145,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/patterns.rs:85:69 + --> $DIR/patterns.rs:90:69 | LL | let x = 22; | - binding `x` declared here @@ -148,7 +157,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/patterns.rs:90:69 + --> $DIR/patterns.rs:95:69 | LL | let x = 22; | - binding `x` declared here @@ -160,7 +169,7 @@ LL | } | - `x` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/patterns.rs:98:17 + --> $DIR/patterns.rs:103:17 | LL | let x = 22; | - binding `x` declared here @@ -173,7 +182,7 @@ LL | } | - `x` dropped here while still borrowed error: lifetime may not live long enough - --> $DIR/patterns.rs:111:5 + --> $DIR/patterns.rs:116:5 | LL | fn static_to_a_to_static_through_variable<'a>(x: &'a u32) -> &'static u32 { | -- lifetime `'a` defined here @@ -182,7 +191,7 @@ LL | y | ^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/patterns.rs:123:5 + --> $DIR/patterns.rs:128:5 | LL | fn static_to_a_to_static_through_tuple<'a>(x: &'a u32) -> &'static u32 { | -- lifetime `'a` defined here @@ -191,7 +200,7 @@ LL | y | ^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/patterns.rs:128:5 + --> $DIR/patterns.rs:133:5 | LL | fn static_to_a_to_static_through_struct<'a>(_x: &'a u32) -> &'static u32 { | -- lifetime `'a` defined here @@ -200,14 +209,14 @@ LL | y | ^ returning this value requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/patterns.rs:132:18 + --> $DIR/patterns.rs:137:18 | LL | fn a_to_static_then_static<'a>(x: &'a u32) -> &'static u32 { | -- lifetime `'a` defined here LL | let (y, _z): (&'static u32, u32) = (x, 44); | ^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` -error: aborting due to 19 previous errors +error: aborting due to 20 previous errors Some errors have detailed explanations: E0597, E0716. For more information about an error, try `rustc --explain E0597`. diff --git a/tests/ui/no_std/no-core-with-explicit-std-core.rs b/tests/ui/no_std/no-core-with-explicit-std-core.rs index 3940bcb3aa4f..6e8e41adca07 100644 --- a/tests/ui/no_std/no-core-with-explicit-std-core.rs +++ b/tests/ui/no_std/no-core-with-explicit-std-core.rs @@ -6,8 +6,7 @@ //@ run-pass -#![allow(stable_features)] -#![feature(no_core, core)] +#![feature(no_core)] #![no_core] extern crate core; diff --git a/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs new file mode 100644 index 000000000000..623a8a92ae62 --- /dev/null +++ b/tests/ui/numbers-arithmetic/i128-min-literal-parses.rs @@ -0,0 +1,5 @@ +//! regression test for +//@ run-pass +fn main() { + let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; +} diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr index 3f5297be3719..a62bf5b6a04d 100644 --- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr @@ -8,13 +8,19 @@ LL | x + 100.0 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Add` + = note: `u8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Add<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Add` + = note: `&u8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot add `&str` to `f64` @@ -27,13 +33,19 @@ LL | x + "foo" help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot add `{integer}` to `f64` @@ -46,13 +58,19 @@ LL | x + y help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `{float}` from `u8` @@ -65,13 +83,19 @@ LL | x - 100.0 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Sub` + = note: `u8` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Sub<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Sub` + = note: `&u8` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `&str` from `f64` @@ -84,13 +108,19 @@ LL | x - "foo" help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot subtract `{integer}` from `f64` @@ -103,13 +133,19 @@ LL | x - y help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `u8` by `{float}` @@ -122,13 +158,19 @@ LL | x * 100.0 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Mul` + = note: `u8` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u8` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u8` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u8` implements `Mul<&u8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u8` implements `Mul` + = note: `&u8` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `f64` by `&str` @@ -141,13 +183,19 @@ LL | x * "foo" help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot multiply `f64` by `{integer}` @@ -160,13 +208,19 @@ LL | x * y help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot divide `u8` by `{float}` @@ -193,13 +247,19 @@ LL | x / "foo" help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: cannot divide `f64` by `{integer}` @@ -212,13 +272,19 @@ LL | x / y help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 12 previous errors diff --git a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr index a31ed6154746..65881ca7a82f 100644 --- a/tests/ui/numbers-arithmetic/suggest-float-literal.stderr +++ b/tests/ui/numbers-arithmetic/suggest-float-literal.stderr @@ -8,13 +8,19 @@ LL | x + 100 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Add` + = note: `f32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Add<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Add` + = note: `&f32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -31,13 +37,19 @@ LL | x + 100 help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: `f64` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Add<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Add` + = note: `&f64` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -54,13 +66,19 @@ LL | x - 100 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Sub` + = note: `f32` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Sub<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Sub` + = note: `&f32` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -77,13 +95,19 @@ LL | x - 100 help: the following other types implement trait `Sub` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: `f64` implements `Sub` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Sub` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Sub` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Sub<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Sub` + = note: `&f64` implements `Sub` = note: this error originates in the macro `sub_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -100,13 +124,19 @@ LL | x * 100 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Mul` + = note: `f32` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Mul<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Mul` + = note: `&f32` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -123,13 +153,19 @@ LL | x * 100 help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: `f64` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Mul<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Mul` + = note: `&f64` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -146,13 +182,19 @@ LL | x / 100 help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Div` + = note: `f32` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f32` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f32` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f32` implements `Div<&f32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f32` implements `Div` + = note: `&f32` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | @@ -169,13 +211,19 @@ LL | x / 100 help: the following other types implement trait `Div` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: `f64` implements `Div` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&f64` implements `Div` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&f64` implements `Div` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `f64` implements `Div<&f64>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `f64` implements `Div` + = note: `&f64` implements `Div` = note: this error originates in the macro `div_impl_float` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a floating-point literal by writing it with `.0` | diff --git a/tests/ui/numeric/ref-int.rs b/tests/ui/numeric/ref-int.rs new file mode 100644 index 000000000000..da4f4fc07082 --- /dev/null +++ b/tests/ui/numeric/ref-int.rs @@ -0,0 +1,8 @@ +//@ run-pass +//! regression test for + +pub fn main() { + let x = 1; + let y = 1; + assert_eq!(&x, &y); +} diff --git a/tests/ui/object-lifetime/object-lifetime-default-ambiguous.rs b/tests/ui/object-lifetime/object-lifetime-default-ambiguous.rs index 5dae92fee5f9..0a0f44073740 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-ambiguous.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-ambiguous.rs @@ -21,11 +21,11 @@ struct Ref2<'a,'b:'a,T:'a+'b+?Sized> { } fn a<'a,'b>(t: Ref2<'a,'b, dyn Test>) { - //~^ ERROR lifetime bound for this object type cannot be deduced from context + //~^ ERROR cannot deduce the lifetime bound for this trait object type } fn b(t: Ref2) { - //~^ ERROR lifetime bound for this object type cannot be deduced from context + //~^ ERROR cannot deduce the lifetime bound for this trait object type } fn c(t: Ref2<&dyn Test>) { @@ -41,7 +41,7 @@ fn e(t: Ref2>) { } fn f(t: &Ref2) { - //~^ ERROR lifetime bound for this object type cannot be deduced from context + //~^ ERROR cannot deduce the lifetime bound for this trait object type } fn main() { diff --git a/tests/ui/object-lifetime/object-lifetime-default-ambiguous.stderr b/tests/ui/object-lifetime/object-lifetime-default-ambiguous.stderr index bd50a27fd5e5..6aa3da66fda0 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-ambiguous.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-ambiguous.stderr @@ -1,20 +1,35 @@ -error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound +error[E0228]: cannot deduce the lifetime bound for this trait object type from context --> $DIR/object-lifetime-default-ambiguous.rs:23:28 | LL | fn a<'a,'b>(t: Ref2<'a,'b, dyn Test>) { | ^^^^^^^^ + | +help: please supply an explicit bound + | +LL | fn a<'a,'b>(t: Ref2<'a,'b, dyn Test + /* 'a */>) { + | ++++++++++ -error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound +error[E0228]: cannot deduce the lifetime bound for this trait object type from context --> $DIR/object-lifetime-default-ambiguous.rs:27:14 | LL | fn b(t: Ref2) { | ^^^^^^^^ + | +help: please supply an explicit bound + | +LL | fn b(t: Ref2) { + | ++++++++++ -error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound +error[E0228]: cannot deduce the lifetime bound for this trait object type from context --> $DIR/object-lifetime-default-ambiguous.rs:43:15 | LL | fn f(t: &Ref2) { | ^^^^^^^^ + | +help: please supply an explicit bound + | +LL | fn f(t: &Ref2) { + | ++++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs index 7337383e2978..7a7bba02879e 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.rs @@ -18,7 +18,7 @@ fn is_static(_: T) where T: 'static { } // Here, we should default to `dyn Bar + 'static`, but the current // code forces us into a conservative, hacky path. fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } -//~^ ERROR please supply an explicit bound +//~^ ERROR cannot deduce the lifetime bound for this trait object type fn main() { let s = format!("foo"); diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr index 8d44b4de55a4..5744d0dd162c 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic1.stderr @@ -1,8 +1,13 @@ -error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound +error[E0228]: cannot deduce the lifetime bound for this trait object type from context --> $DIR/object-lifetime-default-dyn-binding-nonstatic1.rs:20:50 | LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } | ^^^^^^^ + | +help: please supply an explicit bound + | +LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar + /* 'a */> { &() } + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs index 2a7415174f8a..9ddf792eaada 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.rs @@ -18,7 +18,7 @@ fn is_static(_: T) where T: 'static { } // Here, we default to `dyn Bar + 'a`. Or, we *should*, but the // current code forces us into a conservative, hacky path. fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } -//~^ ERROR please supply an explicit bound +//~^ ERROR cannot deduce the lifetime bound for this trait object type fn main() { let s = format!("foo"); diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr index 0846dd60723a..ca8612f57934 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic2.stderr @@ -1,8 +1,13 @@ -error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound +error[E0228]: cannot deduce the lifetime bound for this trait object type from context --> $DIR/object-lifetime-default-dyn-binding-nonstatic2.rs:20:50 | LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() } | ^^^^^^^ + | +help: please supply an explicit bound + | +LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar + /* 'a */> { &() } + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs index 51be999a6329..48ac5623f898 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs @@ -14,7 +14,7 @@ fn is_static(_: T) where T: 'static { } // Here, we should default to `dyn Bar + 'static`, but the current // code forces us into a conservative, hacky path. fn bar(x: &str) -> &dyn Foo { &() } -//~^ ERROR please supply an explicit bound +//~^ ERROR cannot deduce the lifetime bound for this trait object type fn main() { let s = format!("foo"); diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr index 688f8af0822b..05620d3878f7 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr @@ -1,8 +1,13 @@ -error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound +error[E0228]: cannot deduce the lifetime bound for this trait object type from context --> $DIR/object-lifetime-default-dyn-binding-nonstatic3.rs:16:36 | LL | fn bar(x: &str) -> &dyn Foo { &() } | ^^^^^^^ + | +help: please supply an explicit bound + | +LL | fn bar(x: &str) -> &dyn Foo { &() } + | ++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/object-lifetime/undeclared-object-lifetime.rs b/tests/ui/object-lifetime/undeclared-object-lifetime.rs new file mode 100644 index 000000000000..7c0e1100fe7b --- /dev/null +++ b/tests/ui/object-lifetime/undeclared-object-lifetime.rs @@ -0,0 +1,7 @@ +//! E0228 (lifetime bound for trait object cannot be deduced from context) should not be emitted +//! when an undeclared lifetime bound has been specified. +//! +//! Regression test for https://github.com/rust-lang/rust/issues/152014 + +fn f(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {} //~ ERROR use of undeclared lifetime name `'undefined` +fn main() {} diff --git a/tests/ui/object-lifetime/undeclared-object-lifetime.stderr b/tests/ui/object-lifetime/undeclared-object-lifetime.stderr new file mode 100644 index 000000000000..b6646a05420b --- /dev/null +++ b/tests/ui/object-lifetime/undeclared-object-lifetime.stderr @@ -0,0 +1,14 @@ +error[E0261]: use of undeclared lifetime name `'undefined` + --> $DIR/undeclared-object-lifetime.rs:6:24 + | +LL | fn f(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {} + | ^^^^^^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'undefined` here + | +LL | fn f<'undefined>(_: std::cell::Ref<'undefined, dyn std::fmt::Debug>) {} + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/on-unimplemented/no-debug.stderr b/tests/ui/on-unimplemented/no-debug.stderr index 1e6fa7d52fa0..3c3b8d2e2054 100644 --- a/tests/ui/on-unimplemented/no-debug.stderr +++ b/tests/ui/on-unimplemented/no-debug.stderr @@ -8,7 +8,6 @@ LL | println!("{:?} {:?}", Foo, Bar); | = help: the trait `Debug` is not implemented for `Foo` = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Foo` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -24,7 +23,6 @@ LL | println!("{:?} {:?}", Foo, Bar); | required by this formatting parameter | = help: the trait `Debug` is not implemented for `Bar` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Foo` doesn't implement `std::fmt::Display` --> $DIR/no-debug.rs:11:23 @@ -40,7 +38,6 @@ help: the trait `std::fmt::Display` is not implemented for `Foo` LL | struct Foo; | ^^^^^^^^^^ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Bar` doesn't implement `std::fmt::Display` --> $DIR/no-debug.rs:11:28 @@ -52,7 +49,6 @@ LL | println!("{} {}", Foo, Bar); | = help: the trait `std::fmt::Display` is not implemented for `Bar` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index baf821c45c5e..67b72bd038d8 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -28,6 +28,9 @@ help: the following other types implement trait `SliceIndex` --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL | = note: `RangeTo` implements `SliceIndex` + ::: $SRC_DIR/core/src/bstr/traits.rs:LL:COL + | + = note: in this macro invocation --> $SRC_DIR/core/src/str/traits.rs:LL:COL | = note: `RangeTo` implements `SliceIndex` diff --git a/tests/ui/on-unimplemented/sum.stderr b/tests/ui/on-unimplemented/sum.stderr index c4650e9f5278..5e82948352f7 100644 --- a/tests/ui/on-unimplemented/sum.stderr +++ b/tests/ui/on-unimplemented/sum.stderr @@ -9,10 +9,14 @@ LL | vec![(), ()].iter().sum::(); = help: the trait `Sum<&()>` is not implemented for `i32` help: the following other types implement trait `Sum` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Sum<&i32>` | = note: `i32` implements `Sum` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Sum<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:4:18 | @@ -35,10 +39,14 @@ LL | vec![(), ()].iter().product::(); = help: the trait `Product<&()>` is not implemented for `i32` help: the following other types implement trait `Product` --> $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL - | - = note: `i32` implements `Product<&i32>` | = note: `i32` implements `Product` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: `i32` implements `Product<&i32>` + ::: $SRC_DIR/core/src/iter/traits/accum.rs:LL:COL + | + = note: in this macro invocation note: the method call chain might not have had the expected associated types --> $DIR/sum.rs:7:18 | diff --git a/tests/ui/overloaded/overloaded-autoderef.rs b/tests/ui/overloaded/overloaded-autoderef.rs index a7a07449ca89..c1a715dd2e9f 100644 --- a/tests/ui/overloaded/overloaded-autoderef.rs +++ b/tests/ui/overloaded/overloaded-autoderef.rs @@ -1,6 +1,5 @@ //@ run-pass #![allow(unused_variables)] -#![allow(stable_features)] use std::cell::RefCell; use std::rc::Rc; diff --git a/tests/ui/overloaded/overloaded-calls-nontuple.stderr b/tests/ui/overloaded/overloaded-calls-nontuple.stderr index 22598f3a3901..b898288c3e4b 100644 --- a/tests/ui/overloaded/overloaded-calls-nontuple.stderr +++ b/tests/ui/overloaded/overloaded-calls-nontuple.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `FnMut` trait must be a tuple --> $DIR/overloaded-calls-nontuple.rs:10:6 | LL | impl FnMut for S { - | ^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize` | note: required by a bound in `FnMut` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -11,7 +11,7 @@ error[E0059]: type parameter to bare `FnOnce` trait must be a tuple --> $DIR/overloaded-calls-nontuple.rs:18:6 | LL | impl FnOnce for S { - | ^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize` | note: required by a bound in `FnOnce` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -20,19 +20,19 @@ error[E0277]: functions with the "rust-call" ABI must take a single non-self tup --> $DIR/overloaded-calls-nontuple.rs:12:5 | LL | extern "rust-call" fn call_mut(&mut self, z: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize` error[E0277]: functions with the "rust-call" ABI must take a single non-self tuple argument --> $DIR/overloaded-calls-nontuple.rs:21:5 | LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize` error[E0277]: `isize` is not a tuple --> $DIR/overloaded-calls-nontuple.rs:23:23 | LL | self.call_mut(z) - | -------- ^ the trait `Tuple` is not implemented for `isize` + | -------- ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize` | | | required by a bound introduced by this call | @@ -53,7 +53,7 @@ error[E0277]: `isize` is not a tuple --> $DIR/overloaded-calls-nontuple.rs:29:10 | LL | drop(s(3)) - | ^^^^ the trait `Tuple` is not implemented for `isize` + | ^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `isize` error: aborting due to 7 previous errors diff --git a/tests/ui/overloaded/overloaded-index-autoderef.rs b/tests/ui/overloaded/overloaded-index-autoderef.rs index ab49826e9dfc..3709bb0b5cd5 100644 --- a/tests/ui/overloaded/overloaded-index-autoderef.rs +++ b/tests/ui/overloaded/overloaded-index-autoderef.rs @@ -1,6 +1,4 @@ //@ run-pass -#![allow(stable_features)] - // Test overloaded indexing combined with autoderef. use std::ops::{Index, IndexMut}; diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index f6a4b60461ce..4d4e20037aaa 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta" extern crate core; diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index 48c216ce27ec..3c4426782233 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -7,7 +7,7 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) - = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta = note: second definition in the local crate (`panic_handler_std`) error: aborting due to 1 previous error diff --git a/tests/ui/panics/alloc_error_hook-unwind.rs b/tests/ui/panics/alloc_error_hook-unwind.rs new file mode 100644 index 000000000000..8a107bc390d4 --- /dev/null +++ b/tests/ui/panics/alloc_error_hook-unwind.rs @@ -0,0 +1,26 @@ +//! Test that out-of-memory conditions trigger catchable panics with `set_alloc_error_hook`. + +//@ run-pass +//@ needs-unwind +//@ only-linux +//@ ignore-backends: gcc + +#![feature(alloc_error_hook)] + +use std::hint::black_box; +use std::mem::forget; +use std::panic::catch_unwind; + +fn main() { + std::alloc::set_alloc_error_hook(|_| panic!()); + + let panic = catch_unwind(|| { + // This is guaranteed to exceed even the size of the address space + for _ in 0..16 { + // Truncates to a suitable value for both 32-bit and 64-bit targets. + let alloc_size = 0x1000_0000_1000_0000u64 as usize; + forget(black_box(vec![0u8; alloc_size])); + } + }); + assert!(panic.is_err()); +} diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr index a7d99e325d9b..4e48e769d9d5 100644 --- a/tests/ui/panics/default-backtrace-ice.stderr +++ b/tests/ui/panics/default-backtrace-ice.stderr @@ -13,7 +13,7 @@ stack backtrace: (end_short_backtrace) (begin_short_backtrace) -error: the compiler unexpectedly panicked. this is a bug. +error: the compiler unexpectedly panicked. This is a bug diff --git a/tests/ui/panics/oom-panic-unwind.rs b/tests/ui/panics/oom-panic-unwind.rs deleted file mode 100644 index 4f7939ce60b2..000000000000 --- a/tests/ui/panics/oom-panic-unwind.rs +++ /dev/null @@ -1,24 +0,0 @@ -//! Test that out-of-memory conditions trigger catchable panics with `-Z oom=panic`. - -//@ compile-flags: -Z oom=panic -//@ run-pass -//@ no-prefer-dynamic -//@ needs-unwind -//@ only-linux -//@ ignore-backends: gcc - -use std::hint::black_box; -use std::mem::forget; -use std::panic::catch_unwind; - -fn main() { - let panic = catch_unwind(|| { - // This is guaranteed to exceed even the size of the address space - for _ in 0..16 { - // Truncates to a suitable value for both 32-bit and 64-bit targets. - let alloc_size = 0x1000_0000_1000_0000u64 as usize; - forget(black_box(vec![0u8; alloc_size])); - } - }); - assert!(panic.is_err()); -} diff --git a/tests/ui/panics/panic-handler-chain-update-hook.rs b/tests/ui/panics/panic-handler-chain-update-hook.rs index 2ae79ad236ef..b75c21c8b3b2 100644 --- a/tests/ui/panics/panic-handler-chain-update-hook.rs +++ b/tests/ui/panics/panic-handler-chain-update-hook.rs @@ -1,11 +1,8 @@ //@ run-pass //@ needs-unwind -#![allow(stable_features)] - //@ needs-threads //@ ignore-backends: gcc -#![feature(std_panic)] #![feature(panic_update_hook)] use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/tests/ui/panics/panic-handler-chain.rs b/tests/ui/panics/panic-handler-chain.rs index cc591c1d9992..49b76834ffe9 100644 --- a/tests/ui/panics/panic-handler-chain.rs +++ b/tests/ui/panics/panic-handler-chain.rs @@ -2,9 +2,6 @@ //@ needs-unwind //@ needs-threads //@ ignore-backends: gcc -#![allow(stable_features)] - -#![feature(std_panic)] use std::sync::atomic::{AtomicUsize, Ordering}; use std::panic; diff --git a/tests/ui/panics/panic-handler-flail-wildly.rs b/tests/ui/panics/panic-handler-flail-wildly.rs index d5f5195d3812..b44a388caad3 100644 --- a/tests/ui/panics/panic-handler-flail-wildly.rs +++ b/tests/ui/panics/panic-handler-flail-wildly.rs @@ -1,14 +1,11 @@ //@ run-pass //@ needs-unwind -#![allow(stable_features)] #![allow(unused_must_use)] //@ needs-threads //@ ignore-backends: gcc -#![feature(std_panic)] - use std::panic; use std::thread; diff --git a/tests/ui/panics/panic-handler-set-twice.rs b/tests/ui/panics/panic-handler-set-twice.rs index ca4ed65f5683..aa40187f08ca 100644 --- a/tests/ui/panics/panic-handler-set-twice.rs +++ b/tests/ui/panics/panic-handler-set-twice.rs @@ -1,9 +1,6 @@ //@ run-pass //@ needs-unwind #![allow(unused_variables)] -#![allow(stable_features)] - -#![feature(std_panic)] //@ needs-threads //@ ignore-backends: gcc diff --git a/tests/ui/panics/panic-in-cleanup.rs b/tests/ui/panics/panic-in-cleanup.rs index 2e307de43939..23430d1f496e 100644 --- a/tests/ui/panics/panic-in-cleanup.rs +++ b/tests/ui/panics/panic-in-cleanup.rs @@ -5,6 +5,7 @@ //@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" //@ normalize-stderr: "\n +at [^\n]+" -> "" //@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output //@ ignore-msvc SEH doesn't do panic-during-cleanup the same way as everyone else diff --git a/tests/ui/panics/panic-in-cleanup.run.stderr b/tests/ui/panics/panic-in-cleanup.run.stderr index bfe3dc8c9d73..b6b396d8617d 100644 --- a/tests/ui/panics/panic-in-cleanup.run.stderr +++ b/tests/ui/panics/panic-in-cleanup.run.stderr @@ -1,9 +1,9 @@ -thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:22:5: +thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:23:5: explicit panic note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:16:9: +thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:17:9: BOOM stack backtrace: diff --git a/tests/ui/panics/panic-in-ffi.rs b/tests/ui/panics/panic-in-ffi.rs index b926d0fa7761..ef40a3b6f7d6 100644 --- a/tests/ui/panics/panic-in-ffi.rs +++ b/tests/ui/panics/panic-in-ffi.rs @@ -6,6 +6,7 @@ //@ normalize-stderr: "\n +[0-9]+:[^\n]+" -> "" //@ normalize-stderr: "\n +at [^\n]+" -> "" //@ normalize-stderr: "(core/src/panicking\.rs):[0-9]+:[0-9]+" -> "$1:$$LINE:$$COL" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ needs-unwind //@ ignore-emscripten "RuntimeError" junk in output diff --git a/tests/ui/panics/panic-in-ffi.run.stderr b/tests/ui/panics/panic-in-ffi.run.stderr index ce907d64358f..49eb92ef7c91 100644 --- a/tests/ui/panics/panic-in-ffi.run.stderr +++ b/tests/ui/panics/panic-in-ffi.run.stderr @@ -1,5 +1,5 @@ -thread 'main' ($TID) panicked at $DIR/panic-in-ffi.rs:21:5: +thread 'main' ($TID) panicked at $DIR/panic-in-ffi.rs:22:5: Test note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Noisy Drop diff --git a/tests/ui/panics/vec-extend-after-panic-3029.rs b/tests/ui/panics/vec-extend-after-panic-3029.rs new file mode 100644 index 000000000000..3ae708d91e19 --- /dev/null +++ b/tests/ui/panics/vec-extend-after-panic-3029.rs @@ -0,0 +1,14 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3029 + +//@ run-fail +//@ error-pattern:so long +//@ needs-subprocess + +#![allow(unreachable_code)] + +fn main() { + let mut x = Vec::new(); + let y = vec![3]; + panic!("so long"); + x.extend(y.into_iter()); +} diff --git a/tests/ui/parser/attribute-on-empty.rs b/tests/ui/parser/attribute-on-empty.rs index 5932377f73ec..0177e6c1b59d 100644 --- a/tests/ui/parser/attribute-on-empty.rs +++ b/tests/ui/parser/attribute-on-empty.rs @@ -4,7 +4,7 @@ struct Baz(i32); fn main() { - let _: Baz<#[cfg(any())]> = todo!(); + let _: Baz<#[cfg(false)]> = todo!(); //~^ ERROR attributes cannot be applied here } diff --git a/tests/ui/parser/attribute-on-empty.stderr b/tests/ui/parser/attribute-on-empty.stderr index 7c4806c8704a..6bcbf1ceb8d1 100644 --- a/tests/ui/parser/attribute-on-empty.stderr +++ b/tests/ui/parser/attribute-on-empty.stderr @@ -1,7 +1,7 @@ error: attributes cannot be applied here --> $DIR/attribute-on-empty.rs:7:16 | -LL | let _: Baz<#[cfg(any())]> = todo!(); +LL | let _: Baz<#[cfg(false)]> = todo!(); | - ^^^^^^^^^^^^^ attributes are not allowed here | | | while parsing the type for `_` diff --git a/tests/ui/parser/attribute-on-type.rs b/tests/ui/parser/attribute-on-type.rs index 196d322bdf8f..b400bd1c173f 100644 --- a/tests/ui/parser/attribute-on-type.rs +++ b/tests/ui/parser/attribute-on-type.rs @@ -16,16 +16,16 @@ fn main() { let _: #[attr] &'static str = "123"; //~^ ERROR attributes cannot be applied to types - let _: Bar<#[cfg(any())] 'static> = Bar(&123); + let _: Bar<#[cfg(false)] 'static> = Bar(&123); //~^ ERROR attributes cannot be applied to generic arguments - let _: Baz<#[cfg(any())] 42> = Baz(42); + let _: Baz<#[cfg(false)] 42> = Baz(42); //~^ ERROR attributes cannot be applied to generic arguments let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); //~^ ERROR attributes cannot be applied to generic arguments - let _: Bar<#[cfg(any())] 'static> = Bar(&456); + let _: Bar<#[cfg(false)] 'static> = Bar(&456); //~^ ERROR attributes cannot be applied to generic arguments let _generic: Box<#[attr] i32> = Box::new(1); diff --git a/tests/ui/parser/attribute-on-type.stderr b/tests/ui/parser/attribute-on-type.stderr index 603c7e2be51a..316620325c04 100644 --- a/tests/ui/parser/attribute-on-type.stderr +++ b/tests/ui/parser/attribute-on-type.stderr @@ -13,13 +13,13 @@ LL | let _: #[attr] &'static str = "123"; error: attributes cannot be applied to generic arguments --> $DIR/attribute-on-type.rs:19:16 | -LL | let _: Bar<#[cfg(any())] 'static> = Bar(&123); +LL | let _: Bar<#[cfg(false)] 'static> = Bar(&123); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments --> $DIR/attribute-on-type.rs:22:16 | -LL | let _: Baz<#[cfg(any())] 42> = Baz(42); +LL | let _: Baz<#[cfg(false)] 42> = Baz(42); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments @@ -31,7 +31,7 @@ LL | let _: Foo<#[cfg(not(wrong))]String> = Foo(String::new()); error: attributes cannot be applied to generic arguments --> $DIR/attribute-on-type.rs:28:16 | -LL | let _: Bar<#[cfg(any())] 'static> = Bar(&456); +LL | let _: Bar<#[cfg(false)] 'static> = Bar(&456); | ^^^^^^^^^^^^^ attributes are not allowed here error: attributes cannot be applied to generic arguments diff --git a/tests/ui/parser/attribute/attr-bad-meta-4.rs b/tests/ui/parser/attribute/attr-bad-meta-4.rs index 606b41e89a5f..bfd2958ad565 100644 --- a/tests/ui/parser/attribute/attr-bad-meta-4.rs +++ b/tests/ui/parser/attribute/attr-bad-meta-4.rs @@ -9,7 +9,7 @@ macro_rules! mac { mac!(an(arbitrary token stream)); #[cfg(feature = -1)] -//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found fn handler() {} fn main() {} diff --git a/tests/ui/parser/attribute/attr-bad-meta-4.stderr b/tests/ui/parser/attribute/attr-bad-meta-4.stderr index 1d939942fb9a..8f4edca226d3 100644 --- a/tests/ui/parser/attribute/attr-bad-meta-4.stderr +++ b/tests/ui/parser/attribute/attr-bad-meta-4.stderr @@ -1,8 +1,8 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/attr-bad-meta-4.rs:11:17 | LL | #[cfg(feature = -1)] - | ^ + | ^^ expressions are not allowed here | help: negative numbers are not literals, try removing the `-` sign | diff --git a/tests/ui/parser/attribute/attr-pat-struct-rest.rs b/tests/ui/parser/attribute/attr-pat-struct-rest.rs index b2bfcf82df8d..8f0e4cd827e0 100644 --- a/tests/ui/parser/attribute/attr-pat-struct-rest.rs +++ b/tests/ui/parser/attribute/attr-pat-struct-rest.rs @@ -3,6 +3,6 @@ struct S {} fn main() { - let S { #[cfg(any())] .. } = S {}; + let S { #[cfg(false)] .. } = S {}; //~^ ERROR expected identifier, found `..` } diff --git a/tests/ui/parser/attribute/attr-pat-struct-rest.stderr b/tests/ui/parser/attribute/attr-pat-struct-rest.stderr index f72c54973fce..94ad7d571101 100644 --- a/tests/ui/parser/attribute/attr-pat-struct-rest.stderr +++ b/tests/ui/parser/attribute/attr-pat-struct-rest.stderr @@ -1,7 +1,7 @@ error: expected identifier, found `..` --> $DIR/attr-pat-struct-rest.rs:6:27 | -LL | let S { #[cfg(any())] .. } = S {}; +LL | let S { #[cfg(false)] .. } = S {}; | - ^^ expected identifier | | | while parsing the fields for this pattern diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.rs b/tests/ui/parser/attribute/attr-unquoted-ident.rs index 8a0c65b783a7..6207662a6e19 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.rs +++ b/tests/ui/parser/attribute/attr-unquoted-ident.rs @@ -4,14 +4,21 @@ fn main() { #[cfg(key=foo)] - //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` - //~| HELP surround the identifier with quotation marks to make it into a string literal + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found + //~| HELP: surround the identifier with quotation marks to make it into a string literal + //~| NOTE: expressions are not allowed here println!(); #[cfg(key="bar")] println!(); #[cfg(key=foo bar baz)] - //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` - //~| HELP surround the identifier with quotation marks to make it into a string literal + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found + //~| HELP: surround the identifier with quotation marks to make it into a string literal + //~| NOTE: expressions are not allowed here + println!(); + #[cfg(key=foo 1 bar 2.0 baz.)] + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found + //~| HELP: surround the identifier with quotation marks to make it into a string literal + //~| NOTE: expressions are not allowed here println!(); } @@ -19,7 +26,10 @@ fn main() { macro_rules! make { ($name:ident) => { #[doc(alias = $name)] pub struct S; } - //~^ ERROR expected unsuffixed literal, found identifier `nickname` + //~^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + //~| NOTE: expressions are not allowed here + //~| HELP: surround the identifier with quotation marks to make it into a string literal } -make!(nickname); //~ NOTE in this expansion +make!(nickname); //~ NOTE: in this expansion +//~^ NOTE in this expansion of make diff --git a/tests/ui/parser/attribute/attr-unquoted-ident.stderr b/tests/ui/parser/attribute/attr-unquoted-ident.stderr index 8a2785280adc..48ca499ba78f 100644 --- a/tests/ui/parser/attribute/attr-unquoted-ident.stderr +++ b/tests/ui/parser/attribute/attr-unquoted-ident.stderr @@ -1,35 +1,50 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/attr-unquoted-ident.rs:6:15 | LL | #[cfg(key=foo)] - | ^^^ + | ^^^ expressions are not allowed here | help: surround the identifier with quotation marks to make it into a string literal | LL | #[cfg(key="foo")] | + + -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `foo` - --> $DIR/attr-unquoted-ident.rs:12:15 +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/attr-unquoted-ident.rs:13:15 | LL | #[cfg(key=foo bar baz)] - | ^^^ + | ^^^ expressions are not allowed here | help: surround the identifier with quotation marks to make it into a string literal | LL | #[cfg(key="foo bar baz")] | + + -error: expected unsuffixed literal, found identifier `nickname` - --> $DIR/attr-unquoted-ident.rs:21:38 +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/attr-unquoted-ident.rs:18:15 + | +LL | #[cfg(key=foo 1 bar 2.0 baz.)] + | ^^^ expressions are not allowed here + | +help: surround the identifier with quotation marks to make it into a string literal + | +LL | #[cfg(key="foo 1 bar 2.0 baz.")] + | + + + +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/attr-unquoted-ident.rs:28:38 | LL | ($name:ident) => { #[doc(alias = $name)] pub struct S; } - | ^^^^^ + | ^^^^^ expressions are not allowed here ... LL | make!(nickname); | --------------- in this macro invocation | = note: this error originates in the macro `make` (in Nightly builds, run with -Z macro-backtrace for more info) +help: surround the identifier with quotation marks to make it into a string literal + | +LL | ($name:ident) => { #[doc(alias = "$name")] pub struct S; } + | + + -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/tests/ui/parser/bare-struct-body.stderr b/tests/ui/parser/bare-struct-body.stderr index 7d17ea59647e..1b817e2b9ee2 100644 --- a/tests/ui/parser/bare-struct-body.stderr +++ b/tests/ui/parser/bare-struct-body.stderr @@ -21,14 +21,12 @@ LL | let x = { | _____________^ LL | | val: (), LL | | }; - | |_____^ + | |_____^ struct name missing for struct literal | -help: you might have forgotten to add the struct literal inside the block - | -LL ~ let x = { SomeStruct { -LL | val: (), -LL ~ } }; +help: add the correct type | +LL | let x = /* Type */ { + | ++++++++++ error[E0308]: mismatched types --> $DIR/bare-struct-body.rs:11:14 diff --git a/tests/ui/parser/cast-angle-bracket-precedence.rs b/tests/ui/parser/cast-angle-bracket-precedence.rs new file mode 100644 index 000000000000..65b598d03bde --- /dev/null +++ b/tests/ui/parser/cast-angle-bracket-precedence.rs @@ -0,0 +1,29 @@ +//! regression test for https://github.com/rust-lang/rust/issues/22644 + +fn main() { + let a: usize = 0; + let long_name: usize = 0; + + println!("{}", a as usize > long_name); + println!("{}", a as usize < long_name); //~ ERROR `<` is interpreted as a start of generic + println!("{}{}", a as usize < long_name, long_name); + //~^ ERROR `<` is interpreted as a start of generic + println!("{}", a as usize < 4); //~ ERROR `<` is interpreted as a start of generic + + println!("{}", a + as + usize + < //~ ERROR `<` is interpreted as a start of generic + 4); + println!("{}", a + + + as + + + usize + < //~ ERROR `<` is interpreted as a start of generic + 5); + + println!("{}", a as usize << long_name); //~ ERROR `<<` is interpreted as a start of generic +} diff --git a/tests/ui/parser/cast-angle-bracket-precedence.stderr b/tests/ui/parser/cast-angle-bracket-precedence.stderr new file mode 100644 index 000000000000..975bfea9425a --- /dev/null +++ b/tests/ui/parser/cast-angle-bracket-precedence.stderr @@ -0,0 +1,86 @@ +error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison + --> $DIR/cast-angle-bracket-precedence.rs:8:31 + | +LL | println!("{}", a as usize < long_name); + | ^ --------- interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}", (a as usize) < long_name); + | + + + +error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison + --> $DIR/cast-angle-bracket-precedence.rs:9:33 + | +LL | println!("{}{}", a as usize < long_name, long_name); + | ^ -------------------- interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}{}", (a as usize) < long_name, long_name); + | + + + +error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison + --> $DIR/cast-angle-bracket-precedence.rs:11:31 + | +LL | println!("{}", a as usize < 4); + | ^ - interpreted as generic arguments + | | + | not interpreted as comparison + | +help: try comparing the cast value + | +LL | println!("{}", (a as usize) < 4); + | + + + +error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison + --> $DIR/cast-angle-bracket-precedence.rs:16:20 + | +LL | < + | ^ not interpreted as comparison +LL | 4); + | - interpreted as generic arguments + | +help: try comparing the cast value + | +LL ~ println!("{}", (a +LL | as +LL ~ usize) + | + +error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison + --> $DIR/cast-angle-bracket-precedence.rs:25:20 + | +LL | < + | ^ not interpreted as comparison +LL | 5); + | - interpreted as generic arguments + | +help: try comparing the cast value + | +LL ~ println!("{}", (a +LL | +... +LL | +LL ~ usize) + | + +error: `<<` is interpreted as a start of generic arguments for `usize`, not a shift + --> $DIR/cast-angle-bracket-precedence.rs:28:31 + | +LL | println!("{}", a as usize << long_name); + | ^^ --------- interpreted as generic arguments + | | + | not interpreted as shift + | +help: try shifting the cast value + | +LL | println!("{}", (a as usize) << long_name); + | + + + +error: aborting due to 6 previous errors + diff --git a/tests/ui/parser/cfg-keyword-lifetime.rs b/tests/ui/parser/cfg-keyword-lifetime.rs index a1588eddc074..c61b69175c88 100644 --- a/tests/ui/parser/cfg-keyword-lifetime.rs +++ b/tests/ui/parser/cfg-keyword-lifetime.rs @@ -1,6 +1,6 @@ // Disallow `'keyword` even in cfg'd code. -#[cfg(any())] +#[cfg(false)] fn hello() -> &'ref () {} //~^ ERROR lifetimes cannot use keyword names diff --git a/tests/ui/parser/const-block-items/attrs.rs b/tests/ui/parser/const-block-items/attrs.rs new file mode 100644 index 000000000000..eb7a0554ea9c --- /dev/null +++ b/tests/ui/parser/const-block-items/attrs.rs @@ -0,0 +1,14 @@ +//@ check-pass + +#![feature(const_block_items)] + +#[cfg(false)] +const { assert!(false) } + +#[expect(unused)] +const { + let a = 1; + assert!(true); +} + +fn main() {} diff --git a/tests/ui/parser/const-block-items/inner-attr.rs b/tests/ui/parser/const-block-items/inner-attr.rs new file mode 100644 index 000000000000..5da3191760d2 --- /dev/null +++ b/tests/ui/parser/const-block-items/inner-attr.rs @@ -0,0 +1,12 @@ +#![feature(const_block_items)] + +// ATTENTION: if we ever start accepting inner attributes here, make sure `rustfmt` can handle them. +// see: https://github.com/rust-lang/rustfmt/issues/6158 + +const { + #![expect(unused)] //~ ERROR: an inner attribute is not permitted in this context + let a = 1; + assert!(true); +} + +fn main() {} diff --git a/tests/ui/parser/const-block-items/inner-attr.stderr b/tests/ui/parser/const-block-items/inner-attr.stderr new file mode 100644 index 000000000000..e0a70566332c --- /dev/null +++ b/tests/ui/parser/const-block-items/inner-attr.stderr @@ -0,0 +1,13 @@ +error: an inner attribute is not permitted in this context + --> $DIR/inner-attr.rs:7:5 + | +LL | #![expect(unused)] + | ^^^^^^^^^^^^^^^^^^ +... +LL | fn main() {} + | ------------ the inner attribute doesn't annotate this function + | + = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/const-block-items/macro-item.rs b/tests/ui/parser/const-block-items/macro-item.rs new file mode 100644 index 000000000000..0c07bfc203d2 --- /dev/null +++ b/tests/ui/parser/const-block-items/macro-item.rs @@ -0,0 +1,12 @@ +//@ check-pass +#![feature(const_block_items)] + +macro_rules! foo { + ($item:item) => { + $item + }; +} + +foo!(const {}); + +fn main() {} diff --git a/tests/ui/parser/const-block-items/macro-stmt.rs b/tests/ui/parser/const-block-items/macro-stmt.rs new file mode 100644 index 000000000000..38632d2eec33 --- /dev/null +++ b/tests/ui/parser/const-block-items/macro-stmt.rs @@ -0,0 +1,14 @@ +//@ check-fail + +#![feature(const_block_items)] + +macro_rules! foo { + ($item:item) => { + $item + //~^ ERROR: expected expression, found `` + }; +} + +fn main() { + foo!(const {}); +} diff --git a/tests/ui/parser/const-block-items/macro-stmt.stderr b/tests/ui/parser/const-block-items/macro-stmt.stderr new file mode 100644 index 000000000000..dce90e5daa4c --- /dev/null +++ b/tests/ui/parser/const-block-items/macro-stmt.stderr @@ -0,0 +1,13 @@ +error: expected expression, found `` + --> $DIR/macro-stmt.rs:7:9 + | +LL | $item + | ^^^^^ expected expression +... +LL | foo!(const {}); + | -------------- in this macro invocation + | + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/const-block-items/mod-in-fn.rs b/tests/ui/parser/const-block-items/mod-in-fn.rs new file mode 100644 index 000000000000..ec98f95a8448 --- /dev/null +++ b/tests/ui/parser/const-block-items/mod-in-fn.rs @@ -0,0 +1,9 @@ +//@ check-pass + +#![feature(const_block_items)] + +fn main() { + mod foo { + const { assert!(true) } + } +} diff --git a/tests/ui/parser/const-block-items/pub.rs b/tests/ui/parser/const-block-items/pub.rs new file mode 100644 index 000000000000..b76d30d9bda1 --- /dev/null +++ b/tests/ui/parser/const-block-items/pub.rs @@ -0,0 +1,10 @@ +#![feature(const_block_items)] + +//@ check-pass + +// FIXME(const_block_items): `pub`` is useless here +pub const { + assert!(true); +} + +fn main() { } diff --git a/tests/ui/parser/const-block-items/unsafe.rs b/tests/ui/parser/const-block-items/unsafe.rs new file mode 100644 index 000000000000..f53dfab7a0a2 --- /dev/null +++ b/tests/ui/parser/const-block-items/unsafe.rs @@ -0,0 +1,10 @@ +#![feature(const_block_items)] + +const unsafe fn foo() -> bool { + true +} + +const unsafe { assert!(foo()) } +//~^ ERROR: expected one of `extern` or `fn`, found `{` + +fn main() { } diff --git a/tests/ui/parser/const-block-items/unsafe.stderr b/tests/ui/parser/const-block-items/unsafe.stderr new file mode 100644 index 000000000000..0d38af838b3e --- /dev/null +++ b/tests/ui/parser/const-block-items/unsafe.stderr @@ -0,0 +1,8 @@ +error: expected one of `extern` or `fn`, found `{` + --> $DIR/unsafe.rs:7:14 + | +LL | const unsafe { assert!(foo()) } + | ^ expected one of `extern` or `fn` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs index 3876fb41d23f..764c1c2a3210 100644 --- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs +++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.rs @@ -11,5 +11,5 @@ fn banana(a: >::BAR) {} fn chaenomeles() { path::path::Struct::() //~^ ERROR unexpected `const` parameter declaration - //~| ERROR failed to resolve: use of unresolved module or unlinked crate `path` + //~| ERROR cannot find module or crate `path` } diff --git a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr index db7c76dc1aa9..7aba69a0cf5a 100644 --- a/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr +++ b/tests/ui/parser/const-param-decl-on-type-instead-of-impl.stderr @@ -22,7 +22,7 @@ error: unexpected `const` parameter declaration LL | path::path::Struct::() | ^^^^^^^^^^^^^^ expected a `const` expression, not a parameter declaration -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `path` +error[E0433]: cannot find module or crate `path` in this scope --> $DIR/const-param-decl-on-type-instead-of-impl.rs:12:5 | LL | path::path::Struct::() diff --git a/tests/ui/parser/diff-markers/enum-2.stderr b/tests/ui/parser/diff-markers/enum-2.stderr index b76cf5d5a01e..8f20e70922f9 100644 --- a/tests/ui/parser/diff-markers/enum-2.stderr +++ b/tests/ui/parser/diff-markers/enum-2.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/enum-2.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `|||||||` is the code that we're merging into + | ^^^^^^^ between this marker and `|||||||` is the code that you are merging into LL | x: u8, LL | ||||||| | ------- between this marker and `=======` is the base code (what the two refs diverged from) @@ -15,12 +15,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/enum.stderr b/tests/ui/parser/diff-markers/enum.stderr index 0ce473bc7023..67f7561fd77b 100644 --- a/tests/ui/parser/diff-markers/enum.stderr +++ b/tests/ui/parser/diff-markers/enum.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/enum.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | Foo(u8), LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/fn-arg.stderr b/tests/ui/parser/diff-markers/fn-arg.stderr index 24521ffa6262..e63592ecf426 100644 --- a/tests/ui/parser/diff-markers/fn-arg.stderr +++ b/tests/ui/parser/diff-markers/fn-arg.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/fn-arg.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | x: u8, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item-with-attr.stderr b/tests/ui/parser/diff-markers/item-with-attr.stderr index 432673cd5518..29dbfab16fda 100644 --- a/tests/ui/parser/diff-markers/item-with-attr.stderr +++ b/tests/ui/parser/diff-markers/item-with-attr.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/item-with-attr.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | fn foo() {} LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item.stderr b/tests/ui/parser/diff-markers/item.stderr index 180c74e5d696..8de41123c9e9 100644 --- a/tests/ui/parser/diff-markers/item.stderr +++ b/tests/ui/parser/diff-markers/item.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/item.rs:1:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | fn foo() {} LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/long-conflict-markers.rs b/tests/ui/parser/diff-markers/long-conflict-markers.rs new file mode 100644 index 000000000000..f92615fb75b4 --- /dev/null +++ b/tests/ui/parser/diff-markers/long-conflict-markers.rs @@ -0,0 +1,11 @@ +enum E { + Foo { +<<<<<<<<< HEAD //~ ERROR encountered diff marker + x: u8, +||||||| + z: (), +========= + y: i8, +>>>>>>>>> branch + } +} diff --git a/tests/ui/parser/diff-markers/long-conflict-markers.stderr b/tests/ui/parser/diff-markers/long-conflict-markers.stderr new file mode 100644 index 000000000000..c83aaf16b741 --- /dev/null +++ b/tests/ui/parser/diff-markers/long-conflict-markers.stderr @@ -0,0 +1,20 @@ +error: encountered diff marker + --> $DIR/long-conflict-markers.rs:3:1 + | +LL | <<<<<<<<< HEAD + | ^^^^^^^^^ between this marker and `=======` is the code that you are merging into +... +LL | ========= + | --------- between this marker and `>>>>>>>` is the incoming code +LL | y: i8, +LL | >>>>>>>>> branch + | ^^^^^^^^^ this marker concludes the conflict region + | + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/diff-markers/statement.stderr b/tests/ui/parser/diff-markers/statement.stderr index 6dccce4a48ee..5b5da0ede615 100644 --- a/tests/ui/parser/diff-markers/statement.stderr +++ b/tests/ui/parser/diff-markers/statement.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/statement.rs:10:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | S::foo(); LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct-expr.stderr b/tests/ui/parser/diff-markers/struct-expr.stderr index 3733cdd34964..d094cbcc9e8c 100644 --- a/tests/ui/parser/diff-markers/struct-expr.stderr +++ b/tests/ui/parser/diff-markers/struct-expr.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/struct-expr.rs:6:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | x: 42, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct.stderr b/tests/ui/parser/diff-markers/struct.stderr index 44f8346613e6..33999ff92b93 100644 --- a/tests/ui/parser/diff-markers/struct.stderr +++ b/tests/ui/parser/diff-markers/struct.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | x: u8, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/trait-item.stderr b/tests/ui/parser/diff-markers/trait-item.stderr index 4361542c7743..6b89b800790c 100644 --- a/tests/ui/parser/diff-markers/trait-item.stderr +++ b/tests/ui/parser/diff-markers/trait-item.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/trait-item.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | fn foo() {} LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/tuple-struct.stderr b/tests/ui/parser/diff-markers/tuple-struct.stderr index 7fda24ba4853..a0c8b7f3700a 100644 --- a/tests/ui/parser/diff-markers/tuple-struct.stderr +++ b/tests/ui/parser/diff-markers/tuple-struct.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/tuple-struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | u8, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/use-statement.stderr b/tests/ui/parser/diff-markers/use-statement.stderr index 3eac7bebb5af..640f88f98057 100644 --- a/tests/ui/parser/diff-markers/use-statement.stderr +++ b/tests/ui/parser/diff-markers/use-statement.stderr @@ -2,7 +2,7 @@ error: encountered diff marker --> $DIR/use-statement.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ between this marker and `=======` is the code that we're merging into + | ^^^^^^^ between this marker and `=======` is the code that you are merging into LL | bar, LL | ======= | ------- between this marker and `>>>>>>>` is the incoming code @@ -12,12 +12,9 @@ LL | >>>>>>> branch | = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers - = help: if you're having merge conflicts after pulling new code: - the top section is the code you already had and the bottom section is the remote code - if you're in the middle of a rebase: - the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation: - visit + = help: if you are in a merge, the top section is the code you already had checked out and the bottom section is the new code + if you are in a rebase, the top section is the code being rebased onto and the bottom section is the code you had checked out which is being rebased + = note: for an explanation on these markers from the `git` documentation, visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/duplicate-visibility.rs b/tests/ui/parser/duplicate-visibility.rs index f0ee60873da0..d35624981c74 100644 --- a/tests/ui/parser/duplicate-visibility.rs +++ b/tests/ui/parser/duplicate-visibility.rs @@ -2,8 +2,8 @@ fn main() {} extern "C" { //~ NOTE while parsing this item list starting here pub pub fn foo(); - //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub` - //~| NOTE expected one of 9 possible tokens + //~^ ERROR expected one of `(`, `async`, `const`, `default`, `extern`, `final`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub` + //~| NOTE expected one of 10 possible tokens //~| HELP there is already a visibility modifier, remove one //~| NOTE explicit visibility first seen here } //~ NOTE the item list ends here diff --git a/tests/ui/parser/duplicate-visibility.stderr b/tests/ui/parser/duplicate-visibility.stderr index 0d1421ee7f4e..e00ebe6a8cf6 100644 --- a/tests/ui/parser/duplicate-visibility.stderr +++ b/tests/ui/parser/duplicate-visibility.stderr @@ -1,4 +1,4 @@ -error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub` +error: expected one of `(`, `async`, `const`, `default`, `extern`, `final`, `fn`, `safe`, `unsafe`, or `use`, found keyword `pub` --> $DIR/duplicate-visibility.rs:4:9 | LL | extern "C" { @@ -6,7 +6,7 @@ LL | extern "C" { LL | pub pub fn foo(); | ^^^ | | - | expected one of 9 possible tokens + | expected one of 10 possible tokens | help: there is already a visibility modifier, remove one ... LL | } diff --git a/tests/ui/parser/dyn-trait-compatibility.rs b/tests/ui/parser/dyn-trait-compatibility.rs index c6e84284fbec..dd01b6e19d05 100644 --- a/tests/ui/parser/dyn-trait-compatibility.rs +++ b/tests/ui/parser/dyn-trait-compatibility.rs @@ -3,7 +3,7 @@ type A0 = dyn; //~^ ERROR cannot find type `dyn` in this scope type A1 = dyn::dyn; -//~^ ERROR use of unresolved module or unlinked crate `dyn` +//~^ ERROR cannot find module or crate `dyn` in this scope type A2 = dyn; //~^ ERROR cannot find type `dyn` in this scope //~| ERROR cannot find type `dyn` in this scope diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr index d15bf3c97f65..233b22123d31 100644 --- a/tests/ui/parser/dyn-trait-compatibility.stderr +++ b/tests/ui/parser/dyn-trait-compatibility.stderr @@ -40,7 +40,7 @@ error[E0425]: cannot find type `dyn` in this scope LL | type A3 = dyn<::dyn>; | ^^^ not found in this scope -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `dyn` +error[E0433]: cannot find module or crate `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:5:11 | LL | type A1 = dyn::dyn; diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr index ef4e647b9f50..016ed0401caf 100644 --- a/tests/ui/parser/emoji-identifiers.stderr +++ b/tests/ui/parser/emoji-identifiers.stderr @@ -91,7 +91,13 @@ LL | fn i_like_to_😅_a_lot() -> 👀 { | ----------------------------- similarly named function `i_like_to_😅_a_lot` defined here ... LL | let _ = i_like_to_😄_a_lot() ➖ 4; - | ^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `i_like_to_😅_a_lot` + | ^^^^^^^^^^^^^^^^^^ + | +help: a function with a similar name exists + | +LL - let _ = i_like_to_😄_a_lot() ➖ 4; +LL + let _ = i_like_to_😅_a_lot() ➖ 4; + | error: aborting due to 10 previous errors diff --git a/tests/ui/parser/issue-116781.rs b/tests/ui/parser/issue-116781.rs index 0e951d2eaa44..176350fe2eec 100644 --- a/tests/ui/parser/issue-116781.rs +++ b/tests/ui/parser/issue-116781.rs @@ -1,6 +1,6 @@ #[derive(Debug)] struct Foo { - #[cfg(all())] + #[cfg(true)] field: fn(($),), //~ ERROR expected pattern, found `$` //~^ ERROR expected pattern, found `$` } diff --git a/tests/ui/parser/issue-12187-1.stderr b/tests/ui/parser/issue-12187-1.stderr index 704854fe5858..ee5d1c0b2f16 100644 --- a/tests/ui/parser/issue-12187-1.stderr +++ b/tests/ui/parser/issue-12187-1.stderr @@ -6,7 +6,7 @@ LL | let &v = new(); | help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let &v: &T = new(); +LL | let &v: &_ = new(); | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/parser/issue-12187-2.stderr b/tests/ui/parser/issue-12187-2.stderr index eeef63a1d0bd..67d18cf137be 100644 --- a/tests/ui/parser/issue-12187-2.stderr +++ b/tests/ui/parser/issue-12187-2.stderr @@ -6,7 +6,7 @@ LL | let &v = new(); | help: consider giving this pattern a type, where the type for type parameter `T` is specified | -LL | let &v: &T = new(); +LL | let &v: &_ = new(); | ++++ error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-89574.stderr b/tests/ui/parser/issues/issue-89574.stderr deleted file mode 100644 index f40f5aded8ef..000000000000 --- a/tests/ui/parser/issues/issue-89574.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-89574.rs:2:25 - | -LL | const EMPTY_ARRAY = []; - | ^^ cannot infer type - -error: missing type for `const` item - --> $DIR/issue-89574.rs:2:22 - | -LL | const EMPTY_ARRAY = []; - | ^ - | -help: provide a type for the item - | -LL | const EMPTY_ARRAY: = []; - | ++++++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/parser/kw-in-trait-bounds.stderr b/tests/ui/parser/kw-in-trait-bounds.stderr index 5a4adf3e37b4..5f86b1430616 100644 --- a/tests/ui/parser/kw-in-trait-bounds.stderr +++ b/tests/ui/parser/kw-in-trait-bounds.stderr @@ -94,37 +94,61 @@ error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:10 | LL | fn _g(_: impl struct, _: &dyn struct) - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - fn _g(_: impl struct, _: &dyn struct) +LL + fn _g(_: impl struct, _: &dyn struct) + | error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:30:8 | LL | B: struct, - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - B: struct, +LL + B: Struct, + | error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:29 | LL | fn _g(_: impl struct, _: &dyn struct) - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - fn _g(_: impl struct, _: &dyn struct) +LL + fn _g(_: impl Struct, _: &dyn struct) + | error[E0405]: cannot find trait `r#struct` in this scope --> $DIR/kw-in-trait-bounds.rs:16:45 | LL | fn _g(_: impl struct, _: &dyn struct) - | ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct` + | ^^^^^^ ... LL | trait Struct {} | ------------ similarly named trait `Struct` defined here + | +help: a trait with a similar name exists (notice the capitalization) + | +LL - fn _g(_: impl struct, _: &dyn struct) +LL + fn _g(_: impl struct, _: &dyn Struct) + | error: aborting due to 12 previous errors diff --git a/tests/ui/parser/macro-rules-paren-name-issue-150899.rs b/tests/ui/parser/macro-rules-paren-name-issue-150899.rs new file mode 100644 index 000000000000..174a6e7e7de8 --- /dev/null +++ b/tests/ui/parser/macro-rules-paren-name-issue-150899.rs @@ -0,0 +1,7 @@ +macro_rules!(i_think_the_name_should_go_here) { + //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon + //~| ERROR expected item, found `{` + () => {} +} + +fn main() {} diff --git a/tests/ui/parser/macro-rules-paren-name-issue-150899.stderr b/tests/ui/parser/macro-rules-paren-name-issue-150899.stderr new file mode 100644 index 000000000000..f5b6ff40f27e --- /dev/null +++ b/tests/ui/parser/macro-rules-paren-name-issue-150899.stderr @@ -0,0 +1,22 @@ +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macro-rules-paren-name-issue-150899.rs:1:13 + | +LL | macro_rules!(i_think_the_name_should_go_here) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to define a macro, remove the parentheses around the macro name + | +LL - macro_rules!(i_think_the_name_should_go_here) { +LL + macro_rules! i_think_the_name_should_go_here { + | + +error: expected item, found `{` + --> $DIR/macro-rules-paren-name-issue-150899.rs:1:47 + | +LL | macro_rules!(i_think_the_name_should_go_here) { + | ^ expected item + | + = note: for a full list of items that can appear in modules, see + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/macro/expr-in-attribute.rs b/tests/ui/parser/macro/expr-in-attribute.rs new file mode 100644 index 000000000000..8c8934493361 --- /dev/null +++ b/tests/ui/parser/macro/expr-in-attribute.rs @@ -0,0 +1,9 @@ +// Test for #146325. +// Ensure that when we encounter an expr invocation in an attribute, we don't suggest nonsense. + +#[deprecated(note = a!=b)] +struct X; +//~^^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression +//~| NOTE: expressions are not allowed here + +fn main() {} diff --git a/tests/ui/parser/macro/expr-in-attribute.stderr b/tests/ui/parser/macro/expr-in-attribute.stderr new file mode 100644 index 000000000000..08d6f12d1e64 --- /dev/null +++ b/tests/ui/parser/macro/expr-in-attribute.stderr @@ -0,0 +1,8 @@ +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression + --> $DIR/expr-in-attribute.rs:4:21 + | +LL | #[deprecated(note = a!=b)] + | ^^^^ expressions are not allowed here + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs index 58bb62bc4bf8..8619856cad67 100644 --- a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs +++ b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.rs @@ -6,6 +6,7 @@ macro_rules! m { } m!(const Self()); -//~^ ERROR expected one of `!` or `::`, found `(` +//~^ ERROR expected identifier, found keyword `Self` +//~^^ ERROR missing `fn` or `struct` for function or struct definition fn main() {} diff --git a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr index f9b73109dbb4..d412c59c4372 100644 --- a/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr +++ b/tests/ui/parser/macro/kw-in-const-item-pos-recovery-149692.stderr @@ -1,11 +1,22 @@ -error: expected one of `!` or `::`, found `(` - --> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:14 +error: expected identifier, found keyword `Self` + --> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:10 + | +LL | m!(const Self()); + | ^^^^ expected identifier, found keyword + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/kw-in-const-item-pos-recovery-149692.rs:8:10 | LL | (const $id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(const Self()); - | ^ expected one of `!` or `::` + | ^^^^ + | +help: if you meant to call a macro, try + | +LL | m!(const Self!()); + | + -error: aborting due to 1 previous error +error: aborting due to 2 previous errors diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs index 223864e33296..77372ced09c4 100644 --- a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.rs @@ -8,12 +8,15 @@ macro_rules! m { } m!(Self()); -//~^ ERROR expected one of `!` or `::`, found `(` +//~^ ERROR expected identifier, found keyword `Self` +//~^^ ERROR missing `fn` or `struct` for function or struct definition m!(Self{}); -//~^ ERROR expected one of `!` or `::`, found `{` +//~^ ERROR expected identifier, found keyword `Self` +//~^^ ERROR missing `enum` or `struct` for enum or struct definition m!(crate()); -//~^ ERROR expected one of `!` or `::`, found `(` +//~^ ERROR expected identifier, found keyword `crate` +//~^^ ERROR missing `fn` or `struct` for function or struct definition fn main() {} diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr index a65214b0d1f9..39f3e2d3a9ea 100644 --- a/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-149692.stderr @@ -1,29 +1,57 @@ -error: expected one of `!` or `::`, found `(` - --> $DIR/kw-in-item-pos-recovery-149692.rs:10:8 +error: expected identifier, found keyword `Self` + --> $DIR/kw-in-item-pos-recovery-149692.rs:10:4 + | +LL | m!(Self()); + | ^^^^ expected identifier, found keyword + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/kw-in-item-pos-recovery-149692.rs:10:4 | LL | ($id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(Self()); - | ^ expected one of `!` or `::` + | ^^^^ + | +help: if you meant to call a macro, try + | +LL | m!(Self!()); + | + -error: expected one of `!` or `::`, found `{` - --> $DIR/kw-in-item-pos-recovery-149692.rs:13:8 +error: expected identifier, found keyword `Self` + --> $DIR/kw-in-item-pos-recovery-149692.rs:14:4 + | +LL | m!(Self{}); + | ^^^^ expected identifier, found keyword + +error: missing `enum` or `struct` for enum or struct definition + --> $DIR/kw-in-item-pos-recovery-149692.rs:14:4 | LL | ($id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(Self{}); - | ^ expected one of `!` or `::` + | ^^^^ -error: expected one of `!` or `::`, found `(` - --> $DIR/kw-in-item-pos-recovery-149692.rs:16:9 +error: expected identifier, found keyword `crate` + --> $DIR/kw-in-item-pos-recovery-149692.rs:18:4 + | +LL | m!(crate()); + | ^^^^^ expected identifier, found keyword + +error: missing `fn` or `struct` for function or struct definition + --> $DIR/kw-in-item-pos-recovery-149692.rs:18:4 | LL | ($id:item()) => {} | -------- while parsing argument for this `item` macro fragment ... LL | m!(crate()); - | ^ expected one of `!` or `::` + | ^^^^^ + | +help: if you meant to call a macro, try + | +LL | m!(crate!()); + | + -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.rs b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.rs new file mode 100644 index 000000000000..bd1785ba5b3c --- /dev/null +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.rs @@ -0,0 +1,13 @@ +//@ edition: 2021 + +macro_rules! x { + ($ty : item) => {}; +} +x! { + trait MyTrait { fn bar(c self) } + //~^ ERROR expected identifier, found keyword `self` + //~^^ ERROR expected one of `:`, `@`, or `|`, found keyword `self` + //~^^^ ERROR expected one of `->`, `;`, `where`, or `{`, found `}` +} + +fn main() {} diff --git a/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr new file mode 100644 index 000000000000..81151edaf0c0 --- /dev/null +++ b/tests/ui/parser/macro/kw-in-item-pos-recovery-151238.stderr @@ -0,0 +1,25 @@ +error: expected identifier, found keyword `self` + --> $DIR/kw-in-item-pos-recovery-151238.rs:7:28 + | +LL | trait MyTrait { fn bar(c self) } + | ^^^^ expected identifier, found keyword + +error: expected one of `:`, `@`, or `|`, found keyword `self` + --> $DIR/kw-in-item-pos-recovery-151238.rs:7:28 + | +LL | trait MyTrait { fn bar(c self) } + | --^^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `: ` + +error: expected one of `->`, `;`, `where`, or `{`, found `}` + --> $DIR/kw-in-item-pos-recovery-151238.rs:7:34 + | +LL | trait MyTrait { fn bar(c self) } + | --- ^ expected one of `->`, `;`, `where`, or `{` + | | + | while parsing this `fn` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs b/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs index 8be99f22d2ee..b29f6915ae3d 100644 --- a/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs +++ b/tests/ui/parser/macro/macro-dotdotdot-may-not-begin-a-type.rs @@ -1,4 +1,4 @@ -// A bare `...` represents `CVarArgs` (`VaListImpl<'_>`) in function argument type +// A bare `...` represents `CVarArgs` (`VaList<'_>`) in function argument type // position without being a proper type syntactically. // This test ensures that we do not regress certain MBE calls would we ever promote // `...` to a proper type syntactically. diff --git a/tests/ui/parser/macro/macro-in-attribute.rs b/tests/ui/parser/macro/macro-in-attribute.rs new file mode 100644 index 000000000000..7a4b3b22baa9 --- /dev/null +++ b/tests/ui/parser/macro/macro-in-attribute.rs @@ -0,0 +1,9 @@ +// Test for #146325. +// Ensure that when we encounter a macro invocation in an attribute, we don't suggest nonsense. + +#[deprecated(note = concat!("a", "b"))] +struct X; +//~^^ ERROR: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found +//~| NOTE: macro calls are not allowed here + +fn main() {} diff --git a/tests/ui/parser/macro/macro-in-attribute.stderr b/tests/ui/parser/macro/macro-in-attribute.stderr new file mode 100644 index 000000000000..d057c93ede07 --- /dev/null +++ b/tests/ui/parser/macro/macro-in-attribute.stderr @@ -0,0 +1,8 @@ +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found macro call + --> $DIR/macro-in-attribute.rs:4:21 + | +LL | #[deprecated(note = concat!("a", "b"))] + | ^^^^^^^^^^^^^^^^^ macro calls are not allowed here + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-closing-generics-bracket.fixed b/tests/ui/parser/missing-closing-generics-bracket.fixed new file mode 100644 index 000000000000..3166887fa8c3 --- /dev/null +++ b/tests/ui/parser/missing-closing-generics-bracket.fixed @@ -0,0 +1,10 @@ +// Issue #141436 +//@ run-rustfix +#![allow(dead_code)] + +trait Trait<'a> {} + +fn foo>() {} +//~^ ERROR expected one of + +fn main() {} diff --git a/tests/ui/parser/missing-closing-generics-bracket.rs b/tests/ui/parser/missing-closing-generics-bracket.rs new file mode 100644 index 000000000000..9424e3467246 --- /dev/null +++ b/tests/ui/parser/missing-closing-generics-bracket.rs @@ -0,0 +1,10 @@ +// Issue #141436 +//@ run-rustfix +#![allow(dead_code)] + +trait Trait<'a> {} + +fn foo() {} +//~^ ERROR expected one of + +fn main() {} diff --git a/tests/ui/parser/missing-closing-generics-bracket.stderr b/tests/ui/parser/missing-closing-generics-bracket.stderr new file mode 100644 index 000000000000..c4287301c595 --- /dev/null +++ b/tests/ui/parser/missing-closing-generics-bracket.stderr @@ -0,0 +1,13 @@ +error: expected one of `+`, `,`, `::`, `=`, or `>`, found `(` + --> $DIR/missing-closing-generics-bracket.rs:7:25 + | +LL | fn foo() {} + | ^ expected one of `+`, `,`, `::`, `=`, or `>` + | +help: you might have meant to end the type parameters here + | +LL | fn foo>() {} + | + + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/missing-operator-after-float.rs b/tests/ui/parser/missing-operator-after-float.rs new file mode 100644 index 000000000000..8868689ff81f --- /dev/null +++ b/tests/ui/parser/missing-operator-after-float.rs @@ -0,0 +1,5 @@ +//! regression test for issue +fn main() { + let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 }; + //~^ ERROR expected function, found `{float}` +} diff --git a/tests/ui/parser/missing-operator-after-float.stderr b/tests/ui/parser/missing-operator-after-float.stderr new file mode 100644 index 000000000000..08878cf098a7 --- /dev/null +++ b/tests/ui/parser/missing-operator-after-float.stderr @@ -0,0 +1,11 @@ +error[E0618]: expected function, found `{float}` + --> $DIR/missing-operator-after-float.rs:3:30 + | +LL | let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 }; + | ^^^---------- + | | + | call expression requires function + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/parser/misspelled-keywords/pub-fn.stderr b/tests/ui/parser/misspelled-keywords/pub-fn.stderr index 1123c652c0ee..9b895f32c91e 100644 --- a/tests/ui/parser/misspelled-keywords/pub-fn.stderr +++ b/tests/ui/parser/misspelled-keywords/pub-fn.stderr @@ -1,8 +1,8 @@ -error: expected one of `#`, `async`, `auto`, `const`, `default`, `enum`, `extern`, `fn`, `gen`, `impl`, `macro_rules`, `macro`, `mod`, `pub`, `safe`, `static`, `struct`, `trait`, `type`, `unsafe`, or `use`, found `puB` +error: expected one of `#`, `async`, `auto`, `const`, `default`, `enum`, `extern`, `final`, `fn`, `gen`, `impl`, `macro_rules`, `macro`, `mod`, `pub`, `safe`, `static`, `struct`, `trait`, `type`, `unsafe`, or `use`, found `puB` --> $DIR/pub-fn.rs:1:1 | LL | puB fn code() {} - | ^^^ expected one of 21 possible tokens + | ^^^ expected one of 22 possible tokens | help: write keyword `pub` in lowercase | diff --git a/tests/ui/parser/mod_file_not_exist.rs b/tests/ui/parser/mod_file_not_exist.rs index 49ce44982ab9..ba89a8c2c1fb 100644 --- a/tests/ui/parser/mod_file_not_exist.rs +++ b/tests/ui/parser/mod_file_not_exist.rs @@ -1,8 +1,9 @@ -mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file` -//~^ HELP to create the module `not_a_real_file`, create file +mod not_a_real_file; +//~^ ERROR: file not found for module `not_a_real_file` +//~| HELP: to create the module `not_a_real_file`, create file fn main() { assert_eq!(mod_file_aux::bar(), 10); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `mod_file_aux` - //~| HELP you might be missing a crate named `mod_file_aux` + //~^ ERROR: cannot find module or crate `mod_file_aux` + //~| HELP: you might be missing a crate named `mod_file_aux` } diff --git a/tests/ui/parser/mod_file_not_exist.stderr b/tests/ui/parser/mod_file_not_exist.stderr index d9e4e8f31f5f..83fff7161cae 100644 --- a/tests/ui/parser/mod_file_not_exist.stderr +++ b/tests/ui/parser/mod_file_not_exist.stderr @@ -7,8 +7,8 @@ LL | mod not_a_real_file; = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs" = note: if there is a `mod not_a_real_file` elsewhere in the crate already, import it with `use crate::...` instead -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `mod_file_aux` - --> $DIR/mod_file_not_exist.rs:5:16 +error[E0433]: cannot find module or crate `mod_file_aux` in this scope + --> $DIR/mod_file_not_exist.rs:6:16 | LL | assert_eq!(mod_file_aux::bar(), 10); | ^^^^^^^^^^^^ use of unresolved module or unlinked crate `mod_file_aux` diff --git a/tests/ui/parser/mod_file_not_exist_windows.rs b/tests/ui/parser/mod_file_not_exist_windows.rs index bb74684d9944..b0b65ae8c759 100644 --- a/tests/ui/parser/mod_file_not_exist_windows.rs +++ b/tests/ui/parser/mod_file_not_exist_windows.rs @@ -5,6 +5,6 @@ mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file` fn main() { assert_eq!(mod_file_aux::bar(), 10); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `mod_file_aux` + //~^ ERROR cannot find module or crate `mod_file_aux` in this scope //~| HELP you might be missing a crate named `mod_file_aux` } diff --git a/tests/ui/parser/mod_file_not_exist_windows.stderr b/tests/ui/parser/mod_file_not_exist_windows.stderr index 03c762d0ef2d..95c6c1c92e64 100644 --- a/tests/ui/parser/mod_file_not_exist_windows.stderr +++ b/tests/ui/parser/mod_file_not_exist_windows.stderr @@ -7,7 +7,7 @@ LL | mod not_a_real_file; = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs" or "$DIR/not_a_real_file/mod.rs" = note: if there is a `mod not_a_real_file` elsewhere in the crate already, import it with `use crate::...` instead -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `mod_file_aux` +error[E0433]: cannot find module or crate `mod_file_aux` in this scope --> $DIR/mod_file_not_exist_windows.rs:7:16 | LL | assert_eq!(mod_file_aux::bar(), 10); diff --git a/tests/ui/parser/raw/raw-idents.rs b/tests/ui/parser/raw/raw-idents.rs index 93015ee6c494..4e1e6b124c31 100644 --- a/tests/ui/parser/raw/raw-idents.rs +++ b/tests/ui/parser/raw/raw-idents.rs @@ -62,7 +62,7 @@ macro_rules! tests { impl<$kw> B<$kw> {} } mod extern_crate { - #[cfg(any())] + #[cfg(false)] extern crate $kw; } mod body { diff --git a/tests/ui/parser/recover/raw-no-const-mut.stderr b/tests/ui/parser/recover/raw-no-const-mut.stderr index 65032c807953..3007134f7f5c 100644 --- a/tests/ui/parser/recover/raw-no-const-mut.stderr +++ b/tests/ui/parser/recover/raw-no-const-mut.stderr @@ -101,7 +101,13 @@ LL | fn a() { | ------ similarly named function `a` defined here ... LL | f(&raw 2); - | ^ help: a function with a similar name exists: `a` + | ^ + | +help: a function with a similar name exists + | +LL - f(&raw 2); +LL + a(&raw 2); + | error: aborting due to 9 previous errors diff --git a/tests/ui/parser/recover/recover-assoc-const-constraint.stderr b/tests/ui/parser/recover/recover-assoc-const-constraint.stderr index 02b1c3fe68a9..766acd0398d2 100644 --- a/tests/ui/parser/recover/recover-assoc-const-constraint.stderr +++ b/tests/ui/parser/recover/recover-assoc-const-constraint.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | bar::(); | ^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -14,8 +14,8 @@ error[E0658]: associated const equality is incomplete LL | bar::(); | ^^^^^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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: aborting due to 2 previous errors diff --git a/tests/ui/parser/struct-lit-placeholder-or-empty-path.rs b/tests/ui/parser/struct-lit-placeholder-or-empty-path.rs new file mode 100644 index 000000000000..8f91eb68b2eb --- /dev/null +++ b/tests/ui/parser/struct-lit-placeholder-or-empty-path.rs @@ -0,0 +1,14 @@ +fn main() { + let _ = {foo: (), bar: {} }; //~ ERROR struct literal body without path + //~| NOTE struct name missing for struct literal + //~| HELP add the correct type + let _ = _ {foo: (), bar: {} }; //~ ERROR placeholder `_` is not allowed for the path in struct literals + //~| NOTE not allowed in struct literals + //~| HELP replace it with the correct type + let _ = {foo: ()}; //~ ERROR struct literal body without path + //~| NOTE struct name missing for struct literal + //~| HELP add the correct type + let _ = _ {foo: ()}; //~ ERROR placeholder `_` is not allowed for the path in struct literals + //~| NOTE not allowed in struct literals + //~| HELP replace it with the correct type +} diff --git a/tests/ui/parser/struct-lit-placeholder-or-empty-path.stderr b/tests/ui/parser/struct-lit-placeholder-or-empty-path.stderr new file mode 100644 index 000000000000..62a417aefc1e --- /dev/null +++ b/tests/ui/parser/struct-lit-placeholder-or-empty-path.stderr @@ -0,0 +1,48 @@ +error: struct literal body without path + --> $DIR/struct-lit-placeholder-or-empty-path.rs:2:13 + | +LL | let _ = {foo: (), bar: {} }; + | ^^^^^^^^^^^^^^^^^^^ struct name missing for struct literal + | +help: add the correct type + | +LL | let _ = /* Type */ {foo: (), bar: {} }; + | ++++++++++ + +error: placeholder `_` is not allowed for the path in struct literals + --> $DIR/struct-lit-placeholder-or-empty-path.rs:5:13 + | +LL | let _ = _ {foo: (), bar: {} }; + | ^ not allowed in struct literals + | +help: replace it with the correct type + | +LL - let _ = _ {foo: (), bar: {} }; +LL + let _ = /* Type */ {foo: (), bar: {} }; + | + +error: struct literal body without path + --> $DIR/struct-lit-placeholder-or-empty-path.rs:8:13 + | +LL | let _ = {foo: ()}; + | ^^^^^^^^^ struct name missing for struct literal + | +help: add the correct type + | +LL | let _ = /* Type */ {foo: ()}; + | ++++++++++ + +error: placeholder `_` is not allowed for the path in struct literals + --> $DIR/struct-lit-placeholder-or-empty-path.rs:11:13 + | +LL | let _ = _ {foo: ()}; + | ^ not allowed in struct literals + | +help: replace it with the correct type + | +LL - let _ = _ {foo: ()}; +LL + let _ = /* Type */ {foo: ()}; + | + +error: aborting due to 4 previous errors + diff --git a/tests/ui/parser/struct-literals-in-invalid-places.stderr b/tests/ui/parser/struct-literals-in-invalid-places.stderr index 39dc2d2efb75..380ecf94d824 100644 --- a/tests/ui/parser/struct-literals-in-invalid-places.stderr +++ b/tests/ui/parser/struct-literals-in-invalid-places.stderr @@ -200,7 +200,7 @@ LL | if x == E::V { field } {} | ---------------^^^^^-- | | | | | expected `()`, found `bool` - | expected this to be `()` + | `if` expressions without `else` arms expect their inner expression to be `()` | help: you might have meant to return this value | diff --git a/tests/ui/parser/ty-path-followed-by-single-colon.rs b/tests/ui/parser/ty-path-followed-by-single-colon.rs index a9082ea317a7..588fec3f2fc8 100644 --- a/tests/ui/parser/ty-path-followed-by-single-colon.rs +++ b/tests/ui/parser/ty-path-followed-by-single-colon.rs @@ -12,7 +12,7 @@ mod garden { fn g(_: impl Take) {} // OK! - #[cfg(any())] fn h() where a::path:to::nowhere {} // OK! + #[cfg(false)] fn h() where a::path:to::nowhere {} // OK! fn i(_: impl Take:to::somewhere>) {} // OK! diff --git a/tests/ui/parser/unbalanced-doublequote-2.rs b/tests/ui/parser/unbalanced-doublequote-2.rs new file mode 100644 index 000000000000..1906f96f6c9b --- /dev/null +++ b/tests/ui/parser/unbalanced-doublequote-2.rs @@ -0,0 +1,4 @@ +//! regression test for issue +fn main() { + "😊""; //~ ERROR unterminated double quote +} diff --git a/tests/ui/parser/unbalanced-doublequote-2.stderr b/tests/ui/parser/unbalanced-doublequote-2.stderr new file mode 100644 index 000000000000..3a6efaf7d4ec --- /dev/null +++ b/tests/ui/parser/unbalanced-doublequote-2.stderr @@ -0,0 +1,11 @@ +error[E0765]: unterminated double quote string + --> $DIR/unbalanced-doublequote-2.rs:3:8 + | +LL | "😊""; + | _________^ +LL | | } + | |__^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0765`. diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 025c0e3ecaca..4e038875d78f 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -31,18 +31,18 @@ extern "C" fn f3_3(_: ..., x: isize) {} //~^ ERROR `...` must be the last argument of a C-variadic function const unsafe extern "C" fn f4_1(x: isize, _: ...) {} -//~^ ERROR functions cannot be both `const` and C-variadic -//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +//~^ ERROR destructor of `VaList<'_>` cannot be evaluated at compile-time +//~| ERROR c-variadic const function definitions are unstable const extern "C" fn f4_2(x: isize, _: ...) {} -//~^ ERROR functions cannot be both `const` and C-variadic -//~| ERROR functions with a C variable argument list must be unsafe -//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +//~^ ERROR functions with a C variable argument list must be unsafe +//~| ERROR destructor of `VaList<'_>` cannot be evaluated at compile-time +//~| ERROR c-variadic const function definitions are unstable const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} -//~^ ERROR functions cannot be both `const` and C-variadic -//~| ERROR functions with a C variable argument list must be unsafe +//~^ ERROR functions with a C variable argument list must be unsafe //~| ERROR `...` must be the last argument of a C-variadic function +//~| ERROR c-variadic const function definitions are unstable extern "C" { fn e_f2(..., x: isize); @@ -64,8 +64,8 @@ impl X { //~| ERROR `...` must be the last argument of a C-variadic function const fn i_f5(x: isize, _: ...) {} //~^ ERROR `...` is not supported for non-extern functions - //~| ERROR functions cannot be both `const` and C-variadic - //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time + //~| ERROR destructor of `VaList<'_>` cannot be evaluated at compile-time + //~| ERROR c-variadic const function definitions are unstable } trait T { diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 0e02d4434233..ea9f9baa58ba 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -80,17 +80,25 @@ error: `...` must be the last argument of a C-variadic function LL | extern "C" fn f3_3(_: ..., x: isize) {} | ^^^^^^ -error: functions cannot be both `const` and C-variadic +error[E0658]: c-variadic const function definitions are unstable --> $DIR/variadic-ffi-semantic-restrictions.rs:33:1 | LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {} - | ^^^^^ `const` because of this ^^^^^^ C-variadic because of this + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151787 for more information + = help: add `#![feature(const_c_variadic)]` 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: functions cannot be both `const` and C-variadic +error[E0658]: c-variadic const function definitions are unstable --> $DIR/variadic-ffi-semantic-restrictions.rs:37:1 | LL | const extern "C" fn f4_2(x: isize, _: ...) {} - | ^^^^^ `const` because of this ^^^^^^ C-variadic because of this + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151787 for more information + = help: add `#![feature(const_c_variadic)]` 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: functions with a C variable argument list must be unsafe --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36 @@ -109,11 +117,15 @@ error: `...` must be the last argument of a C-variadic function LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} | ^^^^^^ -error: functions cannot be both `const` and C-variadic +error[E0658]: c-variadic const function definitions are unstable --> $DIR/variadic-ffi-semantic-restrictions.rs:42:1 | LL | const extern "C" fn f4_3(_: ..., x: isize, _: ...) {} - | ^^^^^ `const` because of this ^^^^^^ C-variadic because of this + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151787 for more information + = help: add `#![feature(const_c_variadic)]` 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: functions with a C variable argument list must be unsafe --> $DIR/variadic-ffi-semantic-restrictions.rs:42:44 @@ -176,13 +188,15 @@ LL | fn i_f4(_: ..., x: isize, _: ...) {} | = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: functions cannot be both `const` and C-variadic +error[E0658]: c-variadic const function definitions are unstable --> $DIR/variadic-ffi-semantic-restrictions.rs:65:5 | LL | const fn i_f5(x: isize, _: ...) {} - | ^^^^^ ^^^^^^ C-variadic because of this - | | - | `const` because of this + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #151787 for more information + = help: add `#![feature(const_c_variadic)]` 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: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 @@ -236,30 +250,43 @@ error: `...` must be the last argument of a C-variadic function LL | fn t_f6(_: ..., x: isize); | ^^^^^^ -error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +error[E0493]: destructor of `VaList<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:33:43 | LL | const unsafe extern "C" fn f4_1(x: isize, _: ...) {} | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions + | + = note: see issue #133214 for more information + = help: add `#![feature(const_destruct)]` 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[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +error[E0493]: destructor of `VaList<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:37:36 | LL | const extern "C" fn f4_2(x: isize, _: ...) {} | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions + | + = note: see issue #133214 for more information + = help: add `#![feature(const_destruct)]` 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[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time +error[E0493]: destructor of `VaList<'_>` cannot be evaluated at compile-time --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | LL | const fn i_f5(x: isize, _: ...) {} | ^ - value is dropped here | | | the destructor for this type cannot be evaluated in constant functions + | + = note: see issue #133214 for more information + = help: add `#![feature(const_destruct)]` 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: aborting due to 33 previous errors -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`. diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs index 1e376c9ff3c1..5cbeccf1b0e4 100644 --- a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs @@ -1,17 +1,26 @@ #![feature(patchable_function_entry)] fn main() {} -#[patchable_function_entry(prefix_nops = 256, entry_nops = 0)]//~error: integer value out of range +#[patchable_function_entry(prefix_nops = 256, entry_nops = 0)] +//~^ ERROR malformed pub fn too_high_pnops() {} -#[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)]//~error: invalid literal value +#[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)] +//~^ ERROR malformed pub fn non_int_nop() {} -#[patchable_function_entry]//~error: malformed `patchable_function_entry` attribute input +#[patchable_function_entry] +//~^ ERROR malformed `patchable_function_entry` attribute input pub fn malformed_attribute() {} -#[patchable_function_entry(prefix_nops = 10, something = 0)]//~error: unexpected parameter name +#[patchable_function_entry(prefix_nops = 10, something = 0)] +//~^ ERROR malformed pub fn unexpected_parameter_name() {} -#[patchable_function_entry()]//~error: must specify at least one parameter +#[patchable_function_entry()] +//~^ ERROR malformed pub fn no_parameters_given() {} + +#[patchable_function_entry(prefix_nops = 255, prefix_nops = 255)] +//~^ ERROR malformed +pub fn duplicate_parameter() {} diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr index 9357a86c4153..43fc0c0518af 100644 --- a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr @@ -1,32 +1,58 @@ -error: malformed `patchable_function_entry` attribute input - --> $DIR/patchable-function-entry-attribute.rs:10:1 - | -LL | #[patchable_function_entry] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` - -error: integer value out of range - --> $DIR/patchable-function-entry-attribute.rs:4:42 +error[E0539]: malformed `patchable_function_entry` attribute input + --> $DIR/patchable-function-entry-attribute.rs:4:1 | LL | #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)] - | ^^^ value must be between `0` and `255` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^ + | | | + | | expected an integer literal in the range of 0..=255 + | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` -error: invalid literal value - --> $DIR/patchable-function-entry-attribute.rs:7:42 +error[E0539]: malformed `patchable_function_entry` attribute input + --> $DIR/patchable-function-entry-attribute.rs:8:1 | LL | #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)] - | ^^^^^^^^^^^^^ value must be an integer between `0` and `255` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^^^^^^^^^^^^^^^^ + | | | + | | expected an integer literal here + | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` -error: unexpected parameter name - --> $DIR/patchable-function-entry-attribute.rs:13:46 +error[E0539]: malformed `patchable_function_entry` attribute input + --> $DIR/patchable-function-entry-attribute.rs:12:1 | -LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] - | ^^^^^^^^^^^^^ expected `prefix_nops` or `entry_nops` +LL | #[patchable_function_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` -error: must specify at least one parameter +error[E0539]: malformed `patchable_function_entry` attribute input --> $DIR/patchable-function-entry-attribute.rs:16:1 | +LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^^^^^^ + | | | + | | valid arguments are `prefix_nops` or `entry_nops` + | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` + +error[E0539]: malformed `patchable_function_entry` attribute input + --> $DIR/patchable-function-entry-attribute.rs:20:1 + | LL | #[patchable_function_entry()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^--^ + | | | + | | expected this to be a list + | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` -error: aborting due to 5 previous errors +error[E0538]: malformed `patchable_function_entry` attribute input + --> $DIR/patchable-function-entry-attribute.rs:24:1 + | +LL | #[patchable_function_entry(prefix_nops = 255, prefix_nops = 255)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^ + | | | + | | found `prefix_nops` used as a key more than once + | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0538, E0539. +For more information about an error, try `rustc --explain E0538`. diff --git a/tests/ui/pattern/bindings-after-at/bind-by-copy.rs b/tests/ui/pattern/bindings-after-at/bind-by-copy.rs index d766411e4f98..3b6f2a9b08f7 100644 --- a/tests/ui/pattern/bindings-after-at/bind-by-copy.rs +++ b/tests/ui/pattern/bindings-after-at/bind-by-copy.rs @@ -53,7 +53,6 @@ pub fn main() { } match (E::E { a: 10, e: C { c: 20 } }) { mut x @ E::E{ a, e: C { mut c } } => { - //~^ WARN value assigned to `a` is never read x = E::NotE; //~^ WARN value assigned to `x` is never read c += 30; diff --git a/tests/ui/pattern/bindings-after-at/bind-by-copy.stderr b/tests/ui/pattern/bindings-after-at/bind-by-copy.stderr index d775b69ef0a5..d0128950ddda 100644 --- a/tests/ui/pattern/bindings-after-at/bind-by-copy.stderr +++ b/tests/ui/pattern/bindings-after-at/bind-by-copy.stderr @@ -20,20 +20,12 @@ LL | y.d.c = 30; = help: maybe it is overwritten before being read? warning: value assigned to `x` is never read - --> $DIR/bind-by-copy.rs:57:13 + --> $DIR/bind-by-copy.rs:56:13 | LL | x = E::NotE; | ^^^^^^^^^^^ | = help: maybe it is overwritten before being read? -warning: value assigned to `a` is never read - --> $DIR/bind-by-copy.rs:55:23 - | -LL | mut x @ E::E{ a, e: C { mut c } } => { - | ^ - | - = help: maybe it is overwritten before being read? - -warning: 4 warnings emitted +warning: 3 warnings emitted diff --git a/tests/ui/pattern/const-pattern-str-match-lifetime.rs b/tests/ui/pattern/const-pattern-str-match-lifetime.rs new file mode 100644 index 000000000000..8814d55c63b6 --- /dev/null +++ b/tests/ui/pattern/const-pattern-str-match-lifetime.rs @@ -0,0 +1,15 @@ +//! regression test for +//@ run-pass + +const X: &'static str = "12345"; + +fn test(s: String) -> bool { + match &*s { + X => true, + _ => false, + } +} + +fn main() { + assert!(test("12345".to_string())); +} diff --git a/tests/ui/pattern/constructor-type-mismatch.rs b/tests/ui/pattern/constructor-type-mismatch.rs new file mode 100644 index 000000000000..77b8e5312dca --- /dev/null +++ b/tests/ui/pattern/constructor-type-mismatch.rs @@ -0,0 +1,20 @@ +//! regression test for +enum Foo { + Bar(i32), + Baz +} + +struct S; + +fn main() { + match Foo::Baz { + Foo::Bar => {} + //~^ ERROR expected unit struct, unit variant or constant, found tuple variant `Foo::Bar` + _ => {} + } + + match S { + S(()) => {} + //~^ ERROR expected tuple struct or tuple variant, found unit struct `S` + } +} diff --git a/tests/ui/pattern/constructor-type-mismatch.stderr b/tests/ui/pattern/constructor-type-mismatch.stderr new file mode 100644 index 000000000000..6610e12cdc75 --- /dev/null +++ b/tests/ui/pattern/constructor-type-mismatch.stderr @@ -0,0 +1,33 @@ +error[E0532]: expected unit struct, unit variant or constant, found tuple variant `Foo::Bar` + --> $DIR/constructor-type-mismatch.rs:11:9 + | +LL | Bar(i32), + | -------- `Foo::Bar` defined here +LL | Baz + | --- similarly named unit variant `Baz` defined here +... +LL | Foo::Bar => {} + | ^^^^^^^^ + | +help: use the tuple variant pattern syntax instead + | +LL | Foo::Bar(_) => {} + | +++ +help: a unit variant with a similar name exists + | +LL - Foo::Bar => {} +LL + Foo::Baz => {} + | + +error[E0532]: expected tuple struct or tuple variant, found unit struct `S` + --> $DIR/constructor-type-mismatch.rs:17:9 + | +LL | struct S; + | --------- `S` defined here +... +LL | S(()) => {} + | ^^^^^ help: use this syntax instead: `S` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0532`. diff --git a/tests/ui/pattern/deref-patterns/basic.rs b/tests/ui/pattern/deref-patterns/basic.rs new file mode 100644 index 000000000000..dee4521e1f95 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/basic.rs @@ -0,0 +1,18 @@ +//@ run-pass +//@ check-run-results +#![feature(deref_patterns)] +#![expect(incomplete_features)] + +fn main() { + test(Some(String::from("42"))); + test(Some(String::new())); + test(None); +} + +fn test(o: Option) { + match o { + Some("42") => println!("the answer"), + Some(_) => println!("something else?"), + None => println!("nil"), + } +} diff --git a/tests/ui/deref-patterns/basic.run.stdout b/tests/ui/pattern/deref-patterns/basic.run.stdout similarity index 100% rename from tests/ui/deref-patterns/basic.run.stdout rename to tests/ui/pattern/deref-patterns/basic.run.stdout diff --git a/tests/ui/pattern/deref-patterns/default-infer.rs b/tests/ui/pattern/deref-patterns/default-infer.rs new file mode 100644 index 000000000000..fb0b2add132a --- /dev/null +++ b/tests/ui/pattern/deref-patterns/default-infer.rs @@ -0,0 +1,10 @@ +//@ check-pass +#![feature(deref_patterns)] +#![expect(incomplete_features)] + +fn main() { + match <_ as Default>::default() { + "" => (), + _ => unreachable!(), + } +} diff --git a/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.rs b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.rs new file mode 100644 index 000000000000..fbc742aa8477 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.rs @@ -0,0 +1,10 @@ +#![feature(deref_patterns)] +#![expect(incomplete_features)] + +fn main() { + let vec![const { vec![] }]: Vec = vec![]; + //~^ ERROR expected a pattern, found a function call + //~| ERROR expected a pattern, found a function call + //~| ERROR expected tuple struct or tuple variant + //~| ERROR arbitrary expressions aren't allowed in patterns +} diff --git a/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.stderr b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.stderr new file mode 100644 index 000000000000..48728acbc291 --- /dev/null +++ b/tests/ui/pattern/deref-patterns/ice-adjust-mode-unimplemented-for-constblock.stderr @@ -0,0 +1,36 @@ +error[E0532]: expected a pattern, found a function call + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant + | + = note: function calls are not allowed in patterns: + +error[E0532]: expected a pattern, found a function call + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant + | + = note: function calls are not allowed in patterns: + +error: arbitrary expressions aren't allowed in patterns + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:14 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^ + | + = help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead + +error[E0164]: expected tuple struct or tuple variant, found associated function `::alloc::boxed::Box::new_uninit` + --> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9 + | +LL | let vec![const { vec![] }]: Vec = vec![]; + | ^^^^^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns + | + = help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0164, E0532. +For more information about an error, try `rustc --explain E0164`. diff --git a/tests/ui/pattern/deref-patterns/recursion-limit.stderr b/tests/ui/pattern/deref-patterns/recursion-limit.stderr index f6aa92b23adb..7c140e4493e7 100644 --- a/tests/ui/pattern/deref-patterns/recursion-limit.stderr +++ b/tests/ui/pattern/deref-patterns/recursion-limit.stderr @@ -12,7 +12,7 @@ error[E0277]: the trait bound `Cyclic: DerefPure` is not satisfied LL | () => {} | ^^ unsatisfied trait bound | -help: the trait `DerefPure` is not implemented for `Cyclic` +help: the nightly-only, unstable trait `DerefPure` is not implemented for `Cyclic` --> $DIR/recursion-limit.rs:8:1 | LL | struct Cyclic; diff --git a/tests/ui/deref-patterns/refs.rs b/tests/ui/pattern/deref-patterns/refs.rs similarity index 79% rename from tests/ui/deref-patterns/refs.rs rename to tests/ui/pattern/deref-patterns/refs.rs index c93e579bfd80..51826225856b 100644 --- a/tests/ui/deref-patterns/refs.rs +++ b/tests/ui/pattern/deref-patterns/refs.rs @@ -1,5 +1,6 @@ //@ check-pass -#![feature(string_deref_patterns)] +#![feature(deref_patterns)] +#![expect(incomplete_features)] fn foo(s: &String) -> i32 { match *s { diff --git a/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr b/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr index 0b1e8ef49780..3ee6efefe697 100644 --- a/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr +++ b/tests/ui/pattern/deref-patterns/unsatisfied-bounds.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `MyPointer: DerefPure` is not satisfied LL | () => {} | ^^ unsatisfied trait bound | -help: the trait `DerefPure` is not implemented for `MyPointer` +help: the nightly-only, unstable trait `DerefPure` is not implemented for `MyPointer` --> $DIR/unsatisfied-bounds.rs:4:1 | LL | struct MyPointer; diff --git a/tests/ui/pattern/enum-variant-not-found.rs b/tests/ui/pattern/enum-variant-not-found.rs new file mode 100644 index 000000000000..e78e28abeb6e --- /dev/null +++ b/tests/ui/pattern/enum-variant-not-found.rs @@ -0,0 +1,13 @@ +//! regression test for + +enum S { + A, +} + +fn bug(l: S) { + match l { + S::B {} => {}, //~ ERROR no variant named `B` found for enum `S` + } +} + +fn main () {} diff --git a/tests/ui/pattern/enum-variant-not-found.stderr b/tests/ui/pattern/enum-variant-not-found.stderr new file mode 100644 index 000000000000..6db4cf79d6b3 --- /dev/null +++ b/tests/ui/pattern/enum-variant-not-found.stderr @@ -0,0 +1,18 @@ +error[E0599]: no variant named `B` found for enum `S` + --> $DIR/enum-variant-not-found.rs:9:12 + | +LL | enum S { + | ------ variant `B` not found here +... +LL | S::B {} => {}, + | ^ + | +help: there is a variant with a similar name + | +LL - S::B {} => {}, +LL + S::A {} => {}, + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/pattern/match-at-pattern-shadows-name.rs b/tests/ui/pattern/match-at-pattern-shadows-name.rs new file mode 100644 index 000000000000..3cd2040c9faf --- /dev/null +++ b/tests/ui/pattern/match-at-pattern-shadows-name.rs @@ -0,0 +1,14 @@ +//! regression test for https://github.com/rust-lang/rust/issues/27033 +fn main() { + match Some(1) { + None @ _ => {} //~ ERROR match bindings cannot shadow unit variants + }; + const C: u8 = 1; + match 1 { + C @ 2 => { + //~^ ERROR match bindings cannot shadow constant + println!("{}", C); + } + _ => {} + }; +} diff --git a/tests/ui/pattern/match-at-pattern-shadows-name.stderr b/tests/ui/pattern/match-at-pattern-shadows-name.stderr new file mode 100644 index 000000000000..6e2fbf546e82 --- /dev/null +++ b/tests/ui/pattern/match-at-pattern-shadows-name.stderr @@ -0,0 +1,22 @@ +error[E0530]: match bindings cannot shadow unit variants + --> $DIR/match-at-pattern-shadows-name.rs:4:9 + | +LL | None @ _ => {} + | ^^^^ cannot be named the same as a unit variant + | + --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL + | + = note: the unit variant `None` is defined here + +error[E0530]: match bindings cannot shadow constants + --> $DIR/match-at-pattern-shadows-name.rs:8:9 + | +LL | const C: u8 = 1; + | ---------------- the constant `C` is defined here +LL | match 1 { +LL | C @ 2 => { + | ^ cannot be named the same as a constant + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0530`. diff --git a/tests/ui/pattern/match-constant-and-byte-literal.rs b/tests/ui/pattern/match-constant-and-byte-literal.rs new file mode 100644 index 000000000000..7a793478016d --- /dev/null +++ b/tests/ui/pattern/match-constant-and-byte-literal.rs @@ -0,0 +1,12 @@ +//! regression test for +//@ run-pass +fn main() { + const X: u8 = 0; + let out: u8 = match 0u8 { + X => 99, + b'\t' => 1, + 1u8 => 2, + _ => 3, + }; + assert_eq!(out, 99); +} diff --git a/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr b/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr index 326595a7cb70..f449f00a6982 100644 --- a/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr +++ b/tests/ui/pattern/match-enum-struct-variant-field-missing.stderr @@ -2,10 +2,13 @@ error[E0026]: variant `A::A` does not have a field named `fob` --> $DIR/match-enum-struct-variant-field-missing.rs:12:16 | LL | A::A { fob } => { - | ^^^ - | | - | variant `A::A` does not have this field - | help: a field with a similar name exists: `foo` + | ^^^ variant `A::A` does not have this field + | +help: a field with a similar name exists + | +LL - A::A { fob } => { +LL + A::A { foo } => { + | error: aborting due to 1 previous error diff --git a/tests/ui/pattern/multiple-bindings-on-var.rs b/tests/ui/pattern/multiple-bindings-on-var.rs new file mode 100644 index 000000000000..f84276257b67 --- /dev/null +++ b/tests/ui/pattern/multiple-bindings-on-var.rs @@ -0,0 +1,27 @@ +//! regression test for +enum F { G(isize, isize) } + +enum H { I(J, K) } + +enum J { L(isize, isize) } +enum K { M(isize, isize) } + +fn main() +{ + + let _z = match F::G(1, 2) { + F::G(x, x) => { println!("{}", x + x); } + //~^ ERROR identifier `x` is bound more than once in the same pattern + }; + + let _z = match H::I(J::L(1, 2), K::M(3, 4)) { + H::I(J::L(x, _), K::M(_, x)) + //~^ ERROR identifier `x` is bound more than once in the same pattern + => { println!("{}", x + x); } + }; + + let _z = match (1, 2) { + (x, x) => { x } //~ ERROR identifier `x` is bound more than once in the same pattern + }; + +} diff --git a/tests/ui/pattern/multiple-bindings-on-var.stderr b/tests/ui/pattern/multiple-bindings-on-var.stderr new file mode 100644 index 000000000000..c2ec11c43465 --- /dev/null +++ b/tests/ui/pattern/multiple-bindings-on-var.stderr @@ -0,0 +1,21 @@ +error[E0416]: identifier `x` is bound more than once in the same pattern + --> $DIR/multiple-bindings-on-var.rs:13:15 + | +LL | F::G(x, x) => { println!("{}", x + x); } + | ^ used in a pattern more than once + +error[E0416]: identifier `x` is bound more than once in the same pattern + --> $DIR/multiple-bindings-on-var.rs:18:32 + | +LL | H::I(J::L(x, _), K::M(_, x)) + | ^ used in a pattern more than once + +error[E0416]: identifier `x` is bound more than once in the same pattern + --> $DIR/multiple-bindings-on-var.rs:24:13 + | +LL | (x, x) => { x } + | ^ used in a pattern more than once + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0416`. diff --git a/tests/ui/pattern/or-pattern-binding-mismatch.rs b/tests/ui/pattern/or-pattern-binding-mismatch.rs new file mode 100644 index 000000000000..a207c3f81899 --- /dev/null +++ b/tests/ui/pattern/or-pattern-binding-mismatch.rs @@ -0,0 +1,9 @@ +//! regression test for +enum Foo { Alpha, Beta(isize) } + +fn main() { + match Foo::Alpha { + Foo::Alpha | Foo::Beta(i) => {} + //~^ ERROR variable `i` is not bound in all patterns + } +} diff --git a/tests/ui/pattern/or-pattern-binding-mismatch.stderr b/tests/ui/pattern/or-pattern-binding-mismatch.stderr new file mode 100644 index 000000000000..46984fac03ce --- /dev/null +++ b/tests/ui/pattern/or-pattern-binding-mismatch.stderr @@ -0,0 +1,11 @@ +error[E0408]: variable `i` is not bound in all patterns + --> $DIR/or-pattern-binding-mismatch.rs:6:7 + | +LL | Foo::Alpha | Foo::Beta(i) => {} + | ^^^^^^^^^^ - variable not in all patterns + | | + | pattern doesn't bind `i` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0408`. diff --git a/tests/ui/pattern/or-pattern-mismatched-variable-and-variant.rs b/tests/ui/pattern/or-pattern-mismatched-variable-and-variant.rs new file mode 100644 index 000000000000..0447fd2ad589 --- /dev/null +++ b/tests/ui/pattern/or-pattern-mismatched-variable-and-variant.rs @@ -0,0 +1,19 @@ +//! regression test for +#[allow(non_camel_case_types)] + +mod bar { + pub enum foo { + alpha, + beta, + charlie + } +} + +fn main() { + use bar::foo::{alpha, charlie}; + match alpha { + alpha | beta => {} //~ ERROR variable `beta` is not bound in all patterns + //~^ ERROR `beta` is named the same as one of the variants + charlie => {} + } +} diff --git a/tests/ui/pattern/or-pattern-mismatched-variable-and-variant.stderr b/tests/ui/pattern/or-pattern-mismatched-variable-and-variant.stderr new file mode 100644 index 000000000000..66c7d7d348c9 --- /dev/null +++ b/tests/ui/pattern/or-pattern-mismatched-variable-and-variant.stderr @@ -0,0 +1,20 @@ +error[E0408]: variable `beta` is not bound in all patterns + --> $DIR/or-pattern-mismatched-variable-and-variant.rs:15:7 + | +LL | alpha | beta => {} + | ^^^^^ ---- variable not in all patterns + | | + | pattern doesn't bind `beta` + +error[E0170]: pattern binding `beta` is named the same as one of the variants of the type `bar::foo` + --> $DIR/or-pattern-mismatched-variable-and-variant.rs:15:15 + | +LL | alpha | beta => {} + | ^^^^ help: to match on the variant, qualify the path: `bar::foo::beta` + | + = note: `#[deny(bindings_with_variant_name)]` on by default + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0170, E0408. +For more information about an error, try `rustc --explain E0170`. diff --git a/tests/ui/pattern/pattern-error-continue.rs b/tests/ui/pattern/pattern-error-continue.rs index 664d4e80ef56..56c3fa1dda7d 100644 --- a/tests/ui/pattern/pattern-error-continue.rs +++ b/tests/ui/pattern/pattern-error-continue.rs @@ -32,6 +32,6 @@ fn main() { //~| NOTE expected `char`, found `bool` match () { - E::V => {} //~ ERROR failed to resolve: use of undeclared type `E` + E::V => {} //~ ERROR cannot find type `E` } } diff --git a/tests/ui/pattern/pattern-error-continue.stderr b/tests/ui/pattern/pattern-error-continue.stderr index a9ac96e3eaff..5068f2800617 100644 --- a/tests/ui/pattern/pattern-error-continue.stderr +++ b/tests/ui/pattern/pattern-error-continue.stderr @@ -52,14 +52,17 @@ note: function defined here LL | fn f(_c: char) {} | ^ -------- -error[E0433]: failed to resolve: use of undeclared type `E` +error[E0433]: cannot find type `E` in this scope --> $DIR/pattern-error-continue.rs:35:9 | LL | E::V => {} - | ^ - | | - | use of undeclared type `E` - | help: an enum with a similar name exists: `A` + | ^ use of undeclared type `E` + | +help: an enum with a similar name exists + | +LL - E::V => {} +LL + A::V => {} + | error: aborting due to 5 previous errors diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr index 37b2d96bb019..378ff04d3a1a 100644 --- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr +++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr @@ -16,10 +16,16 @@ error[E0425]: cannot find value `rest` in this scope LL | [1, rest..] => println!("{rest}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `rest`, use the at operator | LL | [1, rest @ ..] => println!("{rest}"), | + +help: if you meant to destructure a range use a struct pattern + | +LL - [1, rest..] => println!("{rest}"), +LL + [1, std::ops::RangeFrom { start: rest }] => println!("{rest}"), + | error[E0425]: cannot find value `rest` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35 @@ -33,11 +39,17 @@ error[E0425]: cannot find value `tail` in this scope LL | [_, ..tail] => println!("{tail}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `tail`, use the at operator | LL - [_, ..tail] => println!("{tail}"), LL + [_, tail @ ..] => println!("{tail}"), | +help: if you meant to destructure a range use a struct pattern + | +LL - [_, ..tail] => println!("{tail}"), +LL + [_, std::ops::RangeTo { end: tail }] => println!("{tail}"), + | error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:35 @@ -51,11 +63,17 @@ error[E0425]: cannot find value `tail` in this scope LL | [_, ...tail] => println!("{tail}"), | ^^^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `tail`, use the at operator | LL - [_, ...tail] => println!("{tail}"), LL + [_, tail @ ..] => println!("{tail}"), | +help: if you meant to destructure a range use a struct pattern + | +LL - [_, ...tail] => println!("{tail}"), +LL + [_, std::ops::RangeToInclusive { end: tail }] => println!("{tail}"), + | error[E0425]: cannot find value `tail` in this scope --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:17:36 diff --git a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr index a5d9fd2b1a6e..44e42f142707 100644 --- a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr +++ b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr @@ -38,43 +38,85 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:10:34 | LL | fn bad_fn_item_1(x: bool, ((y if x) | y): bool) {} - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - fn bad_fn_item_1(x: bool, ((y if x) | y): bool) {} +LL + fn bad_fn_item_1(x: bool, ((y if y) | y): bool) {} + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:12:25 | LL | fn bad_fn_item_2(((x if y) | x): bool, y: bool) {} - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - fn bad_fn_item_2(((x if y) | x): bool, y: bool) {} +LL + fn bad_fn_item_2(((x if x) | x): bool, y: bool) {} + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:20:18 | LL | (x, y if x) => x && y, - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - (x, y if x) => x && y, +LL + (x, y if y) => x && y, + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:22:15 | LL | (x if y, y) => x && y, - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - (x if y, y) => x && y, +LL + (x if x, y) => x && y, + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:29:20 | LL | (x @ (y if x),) => x && y, - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - (x @ (y if x),) => x && y, +LL + (x @ (y if y),) => x && y, + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:37:20 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - ((Ok(x) if y) | (Err(y) if x),) => x && y, +LL + ((Ok(x) if x) | (Err(y) if x),) => x && y, + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:37:36 | LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - ((Ok(x) if y) | (Err(y) if x),) => x && y, +LL + ((Ok(x) if y) | (Err(y) if y),) => x && y, + | error[E0425]: cannot find value `nonexistent` in this scope --> $DIR/name-resolution.rs:44:15 @@ -86,49 +128,97 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:46:22 | LL | if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + if let ((x, y if y) | (x if y, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:46:33 | LL | if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - if let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + if let ((x, y if x) | (x if x, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:49:25 | LL | while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + while let ((x, y if y) | (x if y, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:49:36 | LL | while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - while let ((x, y if x) | (x if y, y)) = (true, true) { x && y; } +LL + while let ((x, y if x) | (x if x, y)) = (true, true) { x && y; } + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:52:19 | LL | for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } +LL + for ((x, y if y) | (x if y, y)) in [(true, true)] { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:52:30 | LL | for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - for ((x, y if x) | (x if y, y)) in [(true, true)] { x && y; } +LL + for ((x, y if x) | (x if x, y)) in [(true, true)] { x && y; } + | error[E0425]: cannot find value `y` in this scope --> $DIR/name-resolution.rs:57:13 | LL | (|(x if y), (y if x)| x && y)(true, true); - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - (|(x if y), (y if x)| x && y)(true, true); +LL + (|(x if x), (y if x)| x && y)(true, true); + | error[E0425]: cannot find value `x` in this scope --> $DIR/name-resolution.rs:57:23 | LL | (|(x if y), (y if x)| x && y)(true, true); - | ^ help: a local variable with a similar name exists: `y` + | ^ + | +help: a local variable with a similar name exists + | +LL - (|(x if y), (y if x)| x && y)(true, true); +LL + (|(x if y), (y if y)| x && y)(true, true); + | error[E0308]: mismatched types --> $DIR/name-resolution.rs:75:18 diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr index b985b771754e..b8c6f1d867a1 100644 --- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr +++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr @@ -20,7 +20,13 @@ error[E0425]: cannot find value `a` in this scope LL | if let Foo::Bar { .. } = x { | --------------- this pattern doesn't include `a`, which is available in `Bar` LL | println!("{a}"); - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - println!("{a}"); +LL + println!("{x}"); + | error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/struct_pattern_on_tuple_enum.rs b/tests/ui/pattern/struct_pattern_on_tuple_enum.rs new file mode 100644 index 000000000000..a82778841939 --- /dev/null +++ b/tests/ui/pattern/struct_pattern_on_tuple_enum.rs @@ -0,0 +1,10 @@ +//! regression test for +enum Foo { + Bar(isize) +} + +fn main() { + match Foo::Bar(1) { + Foo { i } => () //~ ERROR expected struct, variant or union type, found enum `Foo` + } +} diff --git a/tests/ui/pattern/struct_pattern_on_tuple_enum.stderr b/tests/ui/pattern/struct_pattern_on_tuple_enum.stderr new file mode 100644 index 000000000000..a322b363aa9c --- /dev/null +++ b/tests/ui/pattern/struct_pattern_on_tuple_enum.stderr @@ -0,0 +1,9 @@ +error[E0574]: expected struct, variant or union type, found enum `Foo` + --> $DIR/struct_pattern_on_tuple_enum.rs:8:9 + | +LL | Foo { i } => () + | ^^^ not a struct, variant or union type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/pattern/type_mismatch.rs b/tests/ui/pattern/type_mismatch.rs index 408ff7588471..39d57301e98f 100644 --- a/tests/ui/pattern/type_mismatch.rs +++ b/tests/ui/pattern/type_mismatch.rs @@ -1,4 +1,4 @@ -//! This test used to ICE: rust-lang/rust#109812 +//! These tests used to ICE: rust-lang/rust#109812, rust-lang/rust#150507 //! Instead of actually analyzing the erroneous patterns, //! we instead stop after typeck where errors are already //! reported. @@ -8,12 +8,21 @@ enum Either { One(X), Two(X), + Three { a: X }, } struct X(Y); struct Y; +struct Z(*const i32); +unsafe impl Send for Z {} + +enum Meow { + A { a: Z }, + B(Z), +} + fn consume_fnmut(_: impl FnMut()) {} fn move_into_fnmut() { @@ -25,6 +34,58 @@ fn move_into_fnmut() { let X(mut _t) = x; }); + + consume_fnmut(|| { + let Either::Three { a: ref mut _t } = x; + //~^ ERROR: mismatched types + + let X(mut _t) = x; + }); +} + +fn tuple_against_array() { + let variant: [();1] = [()]; + + || match variant { + (2,) => (), + //~^ ERROR: mismatched types + _ => {} + }; + + || { + let ((2,) | _) = variant; + //~^ ERROR: mismatched types + }; +} + +// Reproducer that triggers the compatibility lint more reliably, instead of relying on the fact +// that at the time of writing, an unresolved integer type variable does not implement any +// auto-traits. +// +// The @_ makes this example also reproduce ICE #150507 before PR #138961 +fn arcane() { + let variant: [();1] = [()]; + + || { + match variant { + (Z(y@_),) => {} + //~^ ERROR: mismatched types + } + }; + + || { + match variant { + Meow::A { a: Z(y@_) } => {} + //~^ ERROR: mismatched types + } + }; + + || { + match variant { + Meow::B(Z(y@_)) => {} + //~^ ERROR: mismatched types + } + }; } fn main() {} diff --git a/tests/ui/pattern/type_mismatch.stderr b/tests/ui/pattern/type_mismatch.stderr index b0441b1fadcf..3f24b2e70694 100644 --- a/tests/ui/pattern/type_mismatch.stderr +++ b/tests/ui/pattern/type_mismatch.stderr @@ -1,11 +1,68 @@ error[E0308]: mismatched types - --> $DIR/type_mismatch.rs:23:13 + --> $DIR/type_mismatch.rs:32:13 | LL | let Either::Two(ref mut _t) = x; | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `X` | | | expected `X`, found `Either` -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:39:13 + | +LL | let Either::Three { a: ref mut _t } = x; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `X` + | | + | expected `X`, found `Either` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:50:9 + | +LL | || match variant { + | ------- this expression has type `[(); 1]` +LL | (2,) => (), + | ^^^^ expected `[(); 1]`, found `(_,)` + | + = note: expected array `[(); 1]` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:56:14 + | +LL | let ((2,) | _) = variant; + | ^^^^ ------- this expression has type `[(); 1]` + | | + | expected `[(); 1]`, found `(_,)` + | + = note: expected array `[(); 1]` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:71:13 + | +LL | match variant { + | ------- this expression has type `[(); 1]` +LL | (Z(y@_),) => {} + | ^^^^^^^^^ expected `[(); 1]`, found `(_,)` + | + = note: expected array `[(); 1]` + found tuple `(_,)` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:78:13 + | +LL | match variant { + | ------- this expression has type `[(); 1]` +LL | Meow::A { a: Z(y@_) } => {} + | ^^^^^^^^^^^^^^^^^^^^^ expected `[(); 1]`, found `Meow` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:85:13 + | +LL | match variant { + | ------- this expression has type `[(); 1]` +LL | Meow::B(Z(y@_)) => {} + | ^^^^^^^^^^^^^^^ expected `[(); 1]`, found `Meow` + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pin-ergonomics/impl-unpin.adt.stderr b/tests/ui/pin-ergonomics/impl-unpin.adt.stderr new file mode 100644 index 000000000000..56fac42d4e32 --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.adt.stderr @@ -0,0 +1,14 @@ +error: explicit impls for the `Unpin` trait are not permitted for structurally pinned types + --> $DIR/impl-unpin.rs:14:5 + | +LL | impl Unpin for Foo {} + | ^^^^^^^^^^^^^^^^^^ impl of `Unpin` not allowed + | +help: `Foo` is structurally pinned because it is marked as `#[pin_v2]` + --> $DIR/impl-unpin.rs:7:1 + | +LL | struct Foo; + | ^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/pin-ergonomics/impl-unpin.assoc.stderr b/tests/ui/pin-ergonomics/impl-unpin.assoc.stderr new file mode 100644 index 000000000000..7f0ee1ddd898 --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.assoc.stderr @@ -0,0 +1,15 @@ +error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `::Assoc` + --> $DIR/impl-unpin.rs:68:5 + | +LL | impl Unpin for ::Assoc {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `::Assoc` + --> $DIR/impl-unpin.rs:70:5 + | +LL | impl Unpin for ::Assoc {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0321`. diff --git a/tests/ui/pin-ergonomics/impl-unpin.rs b/tests/ui/pin-ergonomics/impl-unpin.rs new file mode 100644 index 000000000000..ded8b4774dd9 --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.rs @@ -0,0 +1,74 @@ +//@ revisions: adt tait ty_alias assoc +#![feature(pin_ergonomics)] +#![cfg_attr(tait, feature(type_alias_impl_trait))] +#![allow(incomplete_features)] + +#[pin_v2] +struct Foo; +struct Bar; + +#[cfg(adt)] +mod adt { + use super::*; + + impl Unpin for Foo {} + //[adt]~^ ERROR explicit impls for the `Unpin` trait are not permitted for structurally pinned types + impl Unpin for Bar {} // ok +} + +#[cfg(ty_alias)] +mod ty_alias { + use super::*; + + type Identity = T; + + impl Unpin for Identity {} + //[ty_alias]~^ ERROR explicit impls for the `Unpin` trait are not permitted for structurally pinned types + impl Unpin for Identity {} // ok +} + +#[cfg(tait)] +mod tait { + use super::*; + + trait Identity {} + + impl Identity for T {} + + type FooAlias = impl Identity; + type BarAlias = impl Identity; + + #[define_opaque(FooAlias)] + fn foo_alias() -> FooAlias { + Foo + } + #[define_opaque(BarAlias)] + fn bar_alias() -> BarAlias { + Bar + } + + impl Unpin for FooAlias {} + //[tait]~^ ERROR only traits defined in the current crate can be implemented for arbitrary types + impl Unpin for BarAlias {} + //[tait]~^ ERROR only traits defined in the current crate can be implemented for arbitrary types +} + +#[cfg(assoc)] +mod assoc { + use super::*; + + trait Identity { + type Assoc; + } + + impl Identity for T { + type Assoc = T; + } + + impl Unpin for ::Assoc {} + //[assoc]~^ ERROR cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `::Assoc` + impl Unpin for ::Assoc {} + //[assoc]~^ ERROR cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `::Assoc` +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/impl-unpin.tait.stderr b/tests/ui/pin-ergonomics/impl-unpin.tait.stderr new file mode 100644 index 000000000000..5d9392745df3 --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.tait.stderr @@ -0,0 +1,27 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-unpin.rs:50:5 + | +LL | impl Unpin for FooAlias {} + | ^^^^^^^^^^^^^^^-------- + | | + | type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/impl-unpin.rs:52:5 + | +LL | impl Unpin for BarAlias {} + | ^^^^^^^^^^^^^^^-------- + | | + | type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/tests/ui/pin-ergonomics/impl-unpin.ty_alias.stderr b/tests/ui/pin-ergonomics/impl-unpin.ty_alias.stderr new file mode 100644 index 000000000000..82c1a7d29ddf --- /dev/null +++ b/tests/ui/pin-ergonomics/impl-unpin.ty_alias.stderr @@ -0,0 +1,14 @@ +error: explicit impls for the `Unpin` trait are not permitted for structurally pinned types + --> $DIR/impl-unpin.rs:25:5 + | +LL | impl Unpin for Identity {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Unpin` not allowed + | +help: `Foo` is structurally pinned because it is marked as `#[pin_v2]` + --> $DIR/impl-unpin.rs:7:1 + | +LL | struct Foo; + | ^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.rs b/tests/ui/pin-ergonomics/pin_v2-attr.rs index cfafe4b0b899..ba25d3587edd 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.rs +++ b/tests/ui/pin-ergonomics/pin_v2-attr.rs @@ -25,8 +25,8 @@ union Union { // disallowed enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { - //~^ ERROR `#[pin_v2]` attribute cannot be used on function params - //~| ERROR `#[pin_v2]` attribute cannot be used on function params + //~^ ERROR `#[pin_v2]` attribute cannot be used on type parameters + //~| ERROR `#[pin_v2]` attribute cannot be used on type parameters #[pin_v2] //~ ERROR `#[pin_v2]` attribute cannot be used on enum variants UnitVariant, TupleVariant(#[pin_v2] T), //~ ERROR `#[pin_v2]` attribute cannot be used on struct fields diff --git a/tests/ui/pin-ergonomics/pin_v2-attr.stderr b/tests/ui/pin-ergonomics/pin_v2-attr.stderr index 81e086f5a7ef..8f8a9f3b3a19 100644 --- a/tests/ui/pin-ergonomics/pin_v2-attr.stderr +++ b/tests/ui/pin-ergonomics/pin_v2-attr.stderr @@ -4,7 +4,7 @@ error: `#[pin_v2]` attribute cannot be used on macro calls LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters --> $DIR/pin_v2-attr.rs:84:12 @@ -18,23 +18,23 @@ error: `#[pin_v2]` attribute cannot be used on crates LL | #![pin_v2] | ^^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types -error: `#[pin_v2]` attribute cannot be used on function params +error: `#[pin_v2]` attribute cannot be used on type parameters --> $DIR/pin_v2-attr.rs:27:10 | LL | enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types -error: `#[pin_v2]` attribute cannot be used on function params +error: `#[pin_v2]` attribute cannot be used on type parameters --> $DIR/pin_v2-attr.rs:27:23 | LL | enum Foo<#[pin_v2] T, #[pin_v2] U = ()> { | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on enum variants --> $DIR/pin_v2-attr.rs:30:5 @@ -42,7 +42,7 @@ error: `#[pin_v2]` attribute cannot be used on enum variants LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on struct fields --> $DIR/pin_v2-attr.rs:32:18 @@ -50,7 +50,7 @@ error: `#[pin_v2]` attribute cannot be used on struct fields LL | TupleVariant(#[pin_v2] T), | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on struct fields --> $DIR/pin_v2-attr.rs:34:9 @@ -58,7 +58,7 @@ error: `#[pin_v2]` attribute cannot be used on struct fields LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on traits --> $DIR/pin_v2-attr.rs:39:1 @@ -66,7 +66,7 @@ error: `#[pin_v2]` attribute cannot be used on traits LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on associated consts --> $DIR/pin_v2-attr.rs:41:5 @@ -74,7 +74,7 @@ error: `#[pin_v2]` attribute cannot be used on associated consts LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on associated types --> $DIR/pin_v2-attr.rs:43:5 @@ -82,7 +82,7 @@ error: `#[pin_v2]` attribute cannot be used on associated types LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on required trait methods --> $DIR/pin_v2-attr.rs:46:5 @@ -90,7 +90,7 @@ error: `#[pin_v2]` attribute cannot be used on required trait methods LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on provided trait methods --> $DIR/pin_v2-attr.rs:48:5 @@ -98,7 +98,7 @@ error: `#[pin_v2]` attribute cannot be used on provided trait methods LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on trait aliases --> $DIR/pin_v2-attr.rs:52:1 @@ -106,7 +106,7 @@ error: `#[pin_v2]` attribute cannot be used on trait aliases LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on inherent impl blocks --> $DIR/pin_v2-attr.rs:55:1 @@ -114,7 +114,7 @@ error: `#[pin_v2]` attribute cannot be used on inherent impl blocks LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on delegations --> $DIR/pin_v2-attr.rs:58:5 @@ -122,7 +122,7 @@ error: `#[pin_v2]` attribute cannot be used on delegations LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on inherent methods --> $DIR/pin_v2-attr.rs:61:5 @@ -130,7 +130,7 @@ error: `#[pin_v2]` attribute cannot be used on inherent methods LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on trait impl blocks --> $DIR/pin_v2-attr.rs:65:1 @@ -138,7 +138,7 @@ error: `#[pin_v2]` attribute cannot be used on trait impl blocks LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on trait methods in impl blocks --> $DIR/pin_v2-attr.rs:67:5 @@ -146,7 +146,7 @@ error: `#[pin_v2]` attribute cannot be used on trait methods in impl blocks LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on extern crates --> $DIR/pin_v2-attr.rs:71:1 @@ -154,7 +154,7 @@ error: `#[pin_v2]` attribute cannot be used on extern crates LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on use statements --> $DIR/pin_v2-attr.rs:74:1 @@ -162,7 +162,7 @@ error: `#[pin_v2]` attribute cannot be used on use statements LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on statics --> $DIR/pin_v2-attr.rs:77:1 @@ -170,7 +170,7 @@ error: `#[pin_v2]` attribute cannot be used on statics LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on constants --> $DIR/pin_v2-attr.rs:80:1 @@ -178,7 +178,7 @@ error: `#[pin_v2]` attribute cannot be used on constants LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on functions --> $DIR/pin_v2-attr.rs:83:1 @@ -186,7 +186,7 @@ error: `#[pin_v2]` attribute cannot be used on functions LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on function params --> $DIR/pin_v2-attr.rs:84:12 @@ -194,7 +194,7 @@ error: `#[pin_v2]` attribute cannot be used on function params LL | fn f(#[pin_v2] param: Foo) | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on closures --> $DIR/pin_v2-attr.rs:92:5 @@ -202,7 +202,7 @@ error: `#[pin_v2]` attribute cannot be used on closures LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on expressions --> $DIR/pin_v2-attr.rs:94:5 @@ -210,7 +210,7 @@ error: `#[pin_v2]` attribute cannot be used on expressions LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on struct fields --> $DIR/pin_v2-attr.rs:98:9 @@ -218,7 +218,7 @@ error: `#[pin_v2]` attribute cannot be used on struct fields LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on statements --> $DIR/pin_v2-attr.rs:96:5 @@ -226,7 +226,7 @@ error: `#[pin_v2]` attribute cannot be used on statements LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on match arms --> $DIR/pin_v2-attr.rs:102:9 @@ -234,7 +234,7 @@ error: `#[pin_v2]` attribute cannot be used on match arms LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on pattern fields --> $DIR/pin_v2-attr.rs:106:13 @@ -242,7 +242,7 @@ error: `#[pin_v2]` attribute cannot be used on pattern fields LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on where predicates --> $DIR/pin_v2-attr.rs:88:5 @@ -250,7 +250,7 @@ error: `#[pin_v2]` attribute cannot be used on where predicates LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on modules --> $DIR/pin_v2-attr.rs:112:1 @@ -258,7 +258,7 @@ error: `#[pin_v2]` attribute cannot be used on modules LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on foreign modules --> $DIR/pin_v2-attr.rs:115:1 @@ -266,7 +266,7 @@ error: `#[pin_v2]` attribute cannot be used on foreign modules LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on foreign types --> $DIR/pin_v2-attr.rs:117:5 @@ -274,7 +274,7 @@ error: `#[pin_v2]` attribute cannot be used on foreign types LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on foreign statics --> $DIR/pin_v2-attr.rs:120:5 @@ -282,7 +282,7 @@ error: `#[pin_v2]` attribute cannot be used on foreign statics LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on foreign functions --> $DIR/pin_v2-attr.rs:123:5 @@ -290,7 +290,7 @@ error: `#[pin_v2]` attribute cannot be used on foreign functions LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on type aliases --> $DIR/pin_v2-attr.rs:127:1 @@ -298,7 +298,7 @@ error: `#[pin_v2]` attribute cannot be used on type aliases LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: `#[pin_v2]` attribute cannot be used on macro defs --> $DIR/pin_v2-attr.rs:130:1 @@ -306,7 +306,7 @@ error: `#[pin_v2]` attribute cannot be used on macro defs LL | #[pin_v2] | ^^^^^^^^^ | - = help: `#[pin_v2]` can be applied to data types and unions + = help: `#[pin_v2]` can only be applied to data types error: aborting due to 39 previous errors diff --git a/tests/ui/pin-ergonomics/user-type-projection.rs b/tests/ui/pin-ergonomics/user-type-projection.rs new file mode 100644 index 000000000000..f482586b6ebc --- /dev/null +++ b/tests/ui/pin-ergonomics/user-type-projection.rs @@ -0,0 +1,19 @@ +#![crate_type = "rlib"] +#![feature(pin_ergonomics)] +#![expect(incomplete_features)] +//@ edition: 2024 +//@ check-pass + +// Test that we don't ICE when projecting user-type-annotations through a `&pin` pattern. +// +// Historically, this could occur when the code handling those projections did not know +// about `&pin` patterns, and incorrectly treated them as plain `&`/`&mut` patterns instead. + +struct Data { + x: u32 +} + +pub fn project_user_type_through_pin() -> u32 { + let &pin const Data { x }: &pin const Data = &pin const Data { x: 30 }; + x +} diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr index 4ecc6370d3ca..347ec0a7743e 100644 --- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr +++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr @@ -10,7 +10,6 @@ LL | stuff(phantom_pinned) | -------------- borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0716]: temporary value dropped while borrowed --> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30 @@ -24,7 +23,6 @@ LL | }; | - temporary value is freed at the end of this statement | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/print-request/print-calling-conventions.stdout b/tests/ui/print-request/print-calling-conventions.stdout index b8b939e1c04e..8366697d0fb0 100644 --- a/tests/ui/print-request/print-calling-conventions.stdout +++ b/tests/ui/print-request/print-calling-conventions.stdout @@ -21,6 +21,7 @@ riscv-interrupt-s rust-call rust-cold rust-invalid +rust-preserve-none stdcall stdcall-unwind system diff --git a/tests/ui/print-request/supported-crate-types.rs b/tests/ui/print-request/supported-crate-types.rs index 50185a231eeb..d816e33b413f 100644 --- a/tests/ui/print-request/supported-crate-types.rs +++ b/tests/ui/print-request/supported-crate-types.rs @@ -17,9 +17,11 @@ //@[wasm] compile-flags: --target=wasm32-unknown-unknown --print=supported-crate-types -Zunstable-options //@[wasm] needs-llvm-components: webassembly +//@[wasm] ignore-backends: gcc //@[musl] compile-flags: --target=x86_64-unknown-linux-musl --print=supported-crate-types -Zunstable-options //@[musl] needs-llvm-components: x86 +//@[musl] ignore-backends: gcc //@[linux] compile-flags: --target=x86_64-unknown-linux-gnu --print=supported-crate-types -Zunstable-options //@[linux] needs-llvm-components: x86 diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout index d3d6b6471c6e..d2adff80e3c9 100644 --- a/tests/ui/print_type_sizes/async.stdout +++ b/tests/ui/print_type_sizes/async.stdout @@ -12,6 +12,8 @@ print-type-size variant `Panicked`: 8192 bytes print-type-size upvar `.arg`: 8192 bytes print-type-size type: `std::mem::ManuallyDrop<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes print-type-size field `.value`: 8192 bytes +print-type-size type: `std::mem::MaybeDangling<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes +print-type-size field `.0`: 8192 bytes print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 8192 bytes print-type-size field `.uninit`: 0 bytes @@ -47,6 +49,8 @@ print-type-size type: `std::ptr::NonNull`: 8 bytes, print-type-size field `.pointer`: 8 bytes print-type-size type: `std::mem::ManuallyDrop<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size field `.value`: 1 bytes +print-type-size type: `std::mem::MaybeDangling<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes +print-type-size field `.0`: 1 bytes print-type-size type: `std::mem::MaybeUninit<{async fn body of wait()}>`: 1 bytes, alignment: 1 bytes print-type-size variant `MaybeUninit`: 1 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout index 4ce1ce46f6e8..b51beb514ba8 100644 --- a/tests/ui/print_type_sizes/coroutine_discr_placement.stdout +++ b/tests/ui/print_type_sizes/coroutine_discr_placement.stdout @@ -11,6 +11,8 @@ print-type-size variant `Returned`: 0 bytes print-type-size variant `Panicked`: 0 bytes print-type-size type: `std::mem::ManuallyDrop`: 4 bytes, alignment: 4 bytes print-type-size field `.value`: 4 bytes +print-type-size type: `std::mem::MaybeDangling`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `std::mem::MaybeUninit`: 4 bytes, alignment: 4 bytes print-type-size variant `MaybeUninit`: 4 bytes print-type-size field `.uninit`: 0 bytes diff --git a/tests/ui/privacy/auxiliary/imported-enum-is-private.rs b/tests/ui/privacy/auxiliary/imported-enum-is-private.rs new file mode 100644 index 000000000000..ea847d9aff13 --- /dev/null +++ b/tests/ui/privacy/auxiliary/imported-enum-is-private.rs @@ -0,0 +1,11 @@ +//! auxiliary crate for + +enum Foo { + Bar(isize) +} + +pub mod test { + enum Foo { + Bar(isize) + } +} diff --git a/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern-2.rs b/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern-2.rs new file mode 100644 index 000000000000..38e3cdded5f2 --- /dev/null +++ b/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern-2.rs @@ -0,0 +1,46 @@ +// Doesn't involve `impl Trait` unlike missing-mir-priv-bounds-extern.rs + +pub trait ToPriv { + type AssocPriv; +} + +pub trait PubTr { + #[expect(private_bounds)] + type Assoc: ToPriv; +} + +// Dummy and DummyToPriv are only used in call_handler +struct Dummy; +struct DummyToPriv; +impl PubTr for Dummy { + type Assoc = DummyToPriv; +} +impl ToPriv for DummyToPriv { + type AssocPriv = Priv; +} + +pub trait PubTrHandler { + fn handle(); +} +pub fn call_handler() { + T::handle::(); +} + +struct Priv; + +pub trait GetUnreachable { + type Assoc; +} + +mod m { + pub struct Unreachable; + + impl Unreachable { + #[expect(dead_code)] + pub fn generic() {} + } + + impl crate::GetUnreachable for crate::Priv { + type Assoc = Unreachable; + } +} diff --git a/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern-3.rs b/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern-3.rs new file mode 100644 index 000000000000..807abe2c4ad8 --- /dev/null +++ b/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern-3.rs @@ -0,0 +1,35 @@ +struct Priv; + +pub trait Super { + type AssocSuper: GetUnreachable; +} +#[expect(private_bounds)] +pub trait Sub: Super {} + +// This Dummy type is only used in call_handler +struct Dummy; +impl Super for Dummy { + type AssocSuper = Priv; +} +impl Sub for Dummy {} + +pub trait SubHandler { + fn handle(); +} +pub fn call_handler() { + ::handle::(); +} + +pub trait GetUnreachable { + type Assoc; +} +mod m { + pub struct Unreachable; + impl Unreachable { + #[expect(dead_code)] + pub fn generic() {} + } + impl crate::GetUnreachable for crate::Priv { + type Assoc = Unreachable; + } +} diff --git a/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern.rs b/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern.rs new file mode 100644 index 000000000000..4cb7bfcc6a3f --- /dev/null +++ b/tests/ui/privacy/auxiliary/missing-mir-priv-bounds-extern.rs @@ -0,0 +1,40 @@ +pub trait ToPriv { + type AssocPriv; +} + +pub trait PubTr { + #[expect(private_bounds)] + type Assoc: ToPriv; +} + +struct Dummy; +struct DummyToPriv; +impl PubTr for Dummy { + type Assoc = DummyToPriv; +} +impl ToPriv for DummyToPriv { + type AssocPriv = Priv; +} + +pub fn get_dummy() -> impl PubTr { + Dummy +} + +struct Priv; + +pub trait GetUnreachable { + type Assoc; +} + +mod m { + pub struct Unreachable; + + impl Unreachable { + #[expect(dead_code)] + pub fn generic() {} + } + + impl crate::GetUnreachable for crate::Priv { + type Assoc = Unreachable; + } +} diff --git a/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs b/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs new file mode 100644 index 000000000000..18e63db0cdd1 --- /dev/null +++ b/tests/ui/privacy/auxiliary/non_exhaustive_with_private.rs @@ -0,0 +1,13 @@ +// Auxiliary crate for testing non-exhaustive struct with private fields + +#[non_exhaustive] +pub struct Foo { + pub my_field: u32, + private_field: i32, +} + +#[non_exhaustive] +pub struct Bar { + pub my_field: u32, + pub missing_field: i32, +} diff --git a/tests/ui/issues/auxiliary/issue-16725.rs b/tests/ui/privacy/auxiliary/private-extern-fn.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-16725.rs rename to tests/ui/privacy/auxiliary/private-extern-fn.rs diff --git a/tests/ui/privacy/imported-enum-is-private.rs b/tests/ui/privacy/imported-enum-is-private.rs new file mode 100644 index 000000000000..b628676a25c6 --- /dev/null +++ b/tests/ui/privacy/imported-enum-is-private.rs @@ -0,0 +1,12 @@ +//! regression test for +//@ aux-build:imported-enum-is-private.rs + +extern crate imported_enum_is_private as other; + +fn main() { + let _b = other::Foo::Bar(1); + //~^ ERROR: enum `Foo` is private + + let _b = other::test::Foo::Bar(1); + //~^ ERROR: enum `Foo` is private +} diff --git a/tests/ui/privacy/imported-enum-is-private.stderr b/tests/ui/privacy/imported-enum-is-private.stderr new file mode 100644 index 000000000000..cae1ebb0e29e --- /dev/null +++ b/tests/ui/privacy/imported-enum-is-private.stderr @@ -0,0 +1,31 @@ +error[E0603]: enum `Foo` is private + --> $DIR/imported-enum-is-private.rs:7:21 + | +LL | let _b = other::Foo::Bar(1); + | ^^^ --- tuple variant `Bar` is not publicly re-exported + | | + | private enum + | +note: the enum `Foo` is defined here + --> $DIR/auxiliary/imported-enum-is-private.rs:3:1 + | +LL | enum Foo { + | ^^^^^^^^ + +error[E0603]: enum `Foo` is private + --> $DIR/imported-enum-is-private.rs:10:27 + | +LL | let _b = other::test::Foo::Bar(1); + | ^^^ --- tuple variant `Bar` is not publicly re-exported + | | + | private enum + | +note: the enum `Foo` is defined here + --> $DIR/auxiliary/imported-enum-is-private.rs:8:5 + | +LL | enum Foo { + | ^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/privacy/issue-79593.rs b/tests/ui/privacy/issue-79593.rs index 39c222f7c341..663dd67fcdb1 100644 --- a/tests/ui/privacy/issue-79593.rs +++ b/tests/ui/privacy/issue-79593.rs @@ -10,7 +10,7 @@ mod foo { Pub {}; //~^ ERROR missing field `private` in initializer of `Pub` Enum::Variant { x: () }; - //~^ ERROR missing field `y` in initializer of `Enum` + //~^ ERROR missing field `y` in initializer of `foo::Enum` } } @@ -21,9 +21,9 @@ fn correct() { fn wrong() { foo::Enum::Variant { x: () }; - //~^ ERROR missing field `y` in initializer of `Enum` + //~^ ERROR missing field `y` in initializer of `foo::Enum` foo::Enum::Variant { }; - //~^ ERROR missing fields `x` and `y` in initializer of `Enum` + //~^ ERROR missing fields `x` and `y` in initializer of `foo::Enum` } fn main() {} diff --git a/tests/ui/privacy/issue-79593.stderr b/tests/ui/privacy/issue-79593.stderr index 5bb69836f609..74fea1a3ab76 100644 --- a/tests/ui/privacy/issue-79593.stderr +++ b/tests/ui/privacy/issue-79593.stderr @@ -4,7 +4,7 @@ error[E0063]: missing field `private` in initializer of `Pub` LL | Pub {}; | ^^^ missing `private` -error[E0063]: missing field `y` in initializer of `Enum` +error[E0063]: missing field `y` in initializer of `foo::Enum` --> $DIR/issue-79593.rs:12:9 | LL | Enum::Variant { x: () }; @@ -18,13 +18,13 @@ LL | foo::Pub {}; | = note: private field `private` that was not provided -error[E0063]: missing field `y` in initializer of `Enum` +error[E0063]: missing field `y` in initializer of `foo::Enum` --> $DIR/issue-79593.rs:23:5 | LL | foo::Enum::Variant { x: () }; | ^^^^^^^^^^^^^^^^^^ missing `y` -error[E0063]: missing fields `x` and `y` in initializer of `Enum` +error[E0063]: missing fields `x` and `y` in initializer of `foo::Enum` --> $DIR/issue-79593.rs:25:5 | LL | foo::Enum::Variant { }; diff --git a/tests/ui/privacy/missing-mir-priv-bounds-2.rs b/tests/ui/privacy/missing-mir-priv-bounds-2.rs new file mode 100644 index 000000000000..7676fdb4af4b --- /dev/null +++ b/tests/ui/privacy/missing-mir-priv-bounds-2.rs @@ -0,0 +1,29 @@ +// Test case from issue #151284. +// A private associated type bound allows to leak another private type and result in missing MIR. + +//@ build-fail +//@ aux-crate:dep=missing-mir-priv-bounds-extern-2.rs + +extern crate dep; +use dep::{GetUnreachable, PubTr, PubTrHandler, ToPriv, call_handler}; + +fn main() { + call_handler::(); +} + +struct Handler; +impl PubTrHandler for Handler { + fn handle() { + ::AccessAssoc::generic::(); + } +} + +trait Access: PubTr { + type AccessAssoc; +} + +impl Access for T { + type AccessAssoc = <::AssocPriv as GetUnreachable>::Assoc; +} + +//~? ERROR missing optimized MIR diff --git a/tests/ui/privacy/missing-mir-priv-bounds-2.stderr b/tests/ui/privacy/missing-mir-priv-bounds-2.stderr new file mode 100644 index 000000000000..29a10eb1223b --- /dev/null +++ b/tests/ui/privacy/missing-mir-priv-bounds-2.stderr @@ -0,0 +1,10 @@ +error: missing optimized MIR for `dep::m::Unreachable::generic::` in the crate `missing_mir_priv_bounds_extern_2` + | +note: missing optimized MIR for this item (was the crate `missing_mir_priv_bounds_extern_2` compiled with `--emit=metadata`?) + --> $DIR/auxiliary/missing-mir-priv-bounds-extern-2.rs:40:9 + | +LL | pub fn generic() {} + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/privacy/missing-mir-priv-bounds-3.rs b/tests/ui/privacy/missing-mir-priv-bounds-3.rs new file mode 100644 index 000000000000..1d277265451e --- /dev/null +++ b/tests/ui/privacy/missing-mir-priv-bounds-3.rs @@ -0,0 +1,30 @@ +// Test case from issue #151479. +// A private associated type bound allows to leak another private type and result in missing MIR. + +//@ build-fail +//@ aux-crate:dep=missing-mir-priv-bounds-extern-3.rs + +extern crate dep; +use dep::{GetUnreachable, Sub, SubHandler, Super, call_handler}; + +fn main() { + call_handler::(); +} + +struct Handler; +impl SubHandler for Handler { + fn handle() { + ::AccessAssoc::generic::(); + } +} + +// Without this indirection, Handler::handle notices that +// it's mentioning dep::Priv. +trait Access: Super { + type AccessAssoc; +} +impl Access for T { + type AccessAssoc = <::AssocSuper as GetUnreachable>::Assoc; +} + +//~? ERROR missing optimized MIR diff --git a/tests/ui/privacy/missing-mir-priv-bounds-3.stderr b/tests/ui/privacy/missing-mir-priv-bounds-3.stderr new file mode 100644 index 000000000000..ef464de08cb9 --- /dev/null +++ b/tests/ui/privacy/missing-mir-priv-bounds-3.stderr @@ -0,0 +1,10 @@ +error: missing optimized MIR for `dep::m::Unreachable::generic::` in the crate `missing_mir_priv_bounds_extern_3` + | +note: missing optimized MIR for this item (was the crate `missing_mir_priv_bounds_extern_3` compiled with `--emit=metadata`?) + --> $DIR/auxiliary/missing-mir-priv-bounds-extern-3.rs:30:9 + | +LL | pub fn generic() {} + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/privacy/missing-mir-priv-bounds.rs b/tests/ui/privacy/missing-mir-priv-bounds.rs new file mode 100644 index 000000000000..07783a2ef858 --- /dev/null +++ b/tests/ui/privacy/missing-mir-priv-bounds.rs @@ -0,0 +1,26 @@ +// Test case from issue #151284. +// A private associated type bound allows to leak another private type and result in missing MIR. + +//@ build-fail +//@ aux-crate:dep=missing-mir-priv-bounds-extern.rs + +extern crate dep; +use dep::{GetUnreachable, PubTr, ToPriv, get_dummy}; + +fn main() { + wut(get_dummy()); +} + +fn wut(_: T) { + ::AccessAssoc::generic::(); +} + +trait Access: PubTr { + type AccessAssoc; +} + +impl Access for T { + type AccessAssoc = <::AssocPriv as GetUnreachable>::Assoc; +} + +//~? ERROR missing optimized MIR diff --git a/tests/ui/privacy/missing-mir-priv-bounds.stderr b/tests/ui/privacy/missing-mir-priv-bounds.stderr new file mode 100644 index 000000000000..68eca33332cb --- /dev/null +++ b/tests/ui/privacy/missing-mir-priv-bounds.stderr @@ -0,0 +1,10 @@ +error: missing optimized MIR for `dep::m::Unreachable::generic::` in the crate `missing_mir_priv_bounds_extern` + | +note: missing optimized MIR for this item (was the crate `missing_mir_priv_bounds_extern` compiled with `--emit=metadata`?) + --> $DIR/auxiliary/missing-mir-priv-bounds-extern.rs:34:9 + | +LL | pub fn generic() {} + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/privacy/no-ice-on-inference-failure.stderr b/tests/ui/privacy/no-ice-on-inference-failure.stderr index 67476e6e2189..91b99c2890b8 100644 --- a/tests/ui/privacy/no-ice-on-inference-failure.stderr +++ b/tests/ui/privacy/no-ice-on-inference-failure.stderr @@ -8,7 +8,7 @@ LL | | } | |_________^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/no-ice-on-inference-failure.rs:2:22 | diff --git a/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs new file mode 100644 index 000000000000..0553ff6c781e --- /dev/null +++ b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.rs @@ -0,0 +1,17 @@ +//@ aux-build:non_exhaustive_with_private.rs + +extern crate non_exhaustive_with_private; + +use non_exhaustive_with_private::{Bar, Foo}; + +fn main() { + let foo = Foo { + //~^ ERROR cannot create non-exhaustive struct using struct expression + my_field: 10, + }; + + let bar = Bar { + //~^ ERROR cannot create non-exhaustive struct using struct expression + my_field: 10, + }; +} diff --git a/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr new file mode 100644 index 000000000000..85bf7e4847d7 --- /dev/null +++ b/tests/ui/privacy/non-exhaustive-with-private-fields-147513.stderr @@ -0,0 +1,23 @@ +error[E0639]: cannot create non-exhaustive struct using struct expression + --> $DIR/non-exhaustive-with-private-fields-147513.rs:8:15 + | +LL | let foo = Foo { + | _______________^ +LL | | +LL | | my_field: 10, +LL | | }; + | |_____^ + +error[E0639]: cannot create non-exhaustive struct using struct expression + --> $DIR/non-exhaustive-with-private-fields-147513.rs:13:15 + | +LL | let bar = Bar { + | _______________^ +LL | | +LL | | my_field: 10, +LL | | }; + | |_____^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0639`. diff --git a/tests/ui/privacy/privacy-sanity.rs b/tests/ui/privacy/privacy-sanity.rs index 6622089dda6d..fcd03394d631 100644 --- a/tests/ui/privacy/privacy-sanity.rs +++ b/tests/ui/privacy/privacy-sanity.rs @@ -25,6 +25,14 @@ pub extern "C" { //~ ERROR visibility qualifiers are not permitted here pub static St: u8; } +enum Bird { + pub Duck, + //~^ ERROR visibility qualifiers are not permitted here + pub(crate) Dove, + //~^ ERROR visibility qualifiers are not permitted here + Goose, +} + const MAIN: u8 = { pub trait Tr { fn f(); @@ -79,4 +87,11 @@ fn main() { pub fn f(); pub static St: u8; } + enum Bird { + pub Duck, + //~^ ERROR visibility qualifiers are not permitted here + pub(crate) Dove, + //~^ ERROR visibility qualifiers are not permitted here + Goose, + } } diff --git a/tests/ui/privacy/privacy-sanity.stderr b/tests/ui/privacy/privacy-sanity.stderr index 0acb05cbabaa..fd643357335a 100644 --- a/tests/ui/privacy/privacy-sanity.stderr +++ b/tests/ui/privacy/privacy-sanity.stderr @@ -47,7 +47,23 @@ LL | pub extern "C" { = note: place qualifiers on individual foreign items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:39:5 + --> $DIR/privacy-sanity.rs:29:5 + | +LL | pub Duck, + | ^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:31:5 + | +LL | pub(crate) Dove, + | ^^^^^^^^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:47:5 | LL | pub impl Tr for S { | ^^^ help: remove the qualifier @@ -55,7 +71,7 @@ LL | pub impl Tr for S { = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:40:9 + --> $DIR/privacy-sanity.rs:48:9 | LL | pub fn f() {} | ^^^ help: remove the qualifier @@ -63,7 +79,7 @@ LL | pub fn f() {} = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:41:9 + --> $DIR/privacy-sanity.rs:49:9 | LL | pub const C: u8 = 0; | ^^^ help: remove the qualifier @@ -71,7 +87,7 @@ LL | pub const C: u8 = 0; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:42:9 + --> $DIR/privacy-sanity.rs:50:9 | LL | pub type T = u8; | ^^^ help: remove the qualifier @@ -79,7 +95,7 @@ LL | pub type T = u8; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:44:5 + --> $DIR/privacy-sanity.rs:52:5 | LL | pub impl S { | ^^^ help: remove the qualifier @@ -87,7 +103,7 @@ LL | pub impl S { = note: place qualifiers on individual impl items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:49:5 + --> $DIR/privacy-sanity.rs:57:5 | LL | pub extern "C" { | ^^^ help: remove the qualifier @@ -95,7 +111,7 @@ LL | pub extern "C" { = note: place qualifiers on individual foreign items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:68:5 + --> $DIR/privacy-sanity.rs:76:5 | LL | pub impl Tr for S { | ^^^ help: remove the qualifier @@ -103,7 +119,7 @@ LL | pub impl Tr for S { = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:69:9 + --> $DIR/privacy-sanity.rs:77:9 | LL | pub fn f() {} | ^^^ help: remove the qualifier @@ -111,7 +127,7 @@ LL | pub fn f() {} = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:70:9 + --> $DIR/privacy-sanity.rs:78:9 | LL | pub const C: u8 = 0; | ^^^ help: remove the qualifier @@ -119,7 +135,7 @@ LL | pub const C: u8 = 0; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:71:9 + --> $DIR/privacy-sanity.rs:79:9 | LL | pub type T = u8; | ^^^ help: remove the qualifier @@ -127,7 +143,7 @@ LL | pub type T = u8; = note: trait items always share the visibility of their trait error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:73:5 + --> $DIR/privacy-sanity.rs:81:5 | LL | pub impl S { | ^^^ help: remove the qualifier @@ -135,13 +151,29 @@ LL | pub impl S { = note: place qualifiers on individual impl items instead error[E0449]: visibility qualifiers are not permitted here - --> $DIR/privacy-sanity.rs:78:5 + --> $DIR/privacy-sanity.rs:86:5 | LL | pub extern "C" { | ^^^ help: remove the qualifier | = note: place qualifiers on individual foreign items instead -error: aborting due to 18 previous errors +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:91:9 + | +LL | pub Duck, + | ^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error[E0449]: visibility qualifiers are not permitted here + --> $DIR/privacy-sanity.rs:93:9 + | +LL | pub(crate) Dove, + | ^^^^^^^^^^ help: remove the qualifier + | + = note: enum variants and their fields always share the visibility of the enum they are in + +error: aborting due to 22 previous errors For more information about this error, try `rustc --explain E0449`. diff --git a/tests/ui/privacy/private-extern-fn-visibility.rs b/tests/ui/privacy/private-extern-fn-visibility.rs new file mode 100644 index 000000000000..39f2c3c003d5 --- /dev/null +++ b/tests/ui/privacy/private-extern-fn-visibility.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ aux-build:private-extern-fn.rs + +extern crate private_extern_fn as foo; + +fn main() { + unsafe { + foo::bar(); + //~^ ERROR: function `bar` is private + } +} diff --git a/tests/ui/privacy/private-extern-fn-visibility.stderr b/tests/ui/privacy/private-extern-fn-visibility.stderr new file mode 100644 index 000000000000..8b1fa512b5de --- /dev/null +++ b/tests/ui/privacy/private-extern-fn-visibility.stderr @@ -0,0 +1,15 @@ +error[E0603]: function `bar` is private + --> $DIR/private-extern-fn-visibility.rs:8:14 + | +LL | foo::bar(); + | ^^^ private function + | +note: the function `bar` is defined here + --> $DIR/auxiliary/private-extern-fn.rs:2:5 + | +LL | fn bar(); + | ^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/privacy/private-in-public-warn.rs b/tests/ui/privacy/private-in-public-warn.rs index f79e4641312e..6a0ac2b9ade7 100644 --- a/tests/ui/privacy/private-in-public-warn.rs +++ b/tests/ui/privacy/private-in-public-warn.rs @@ -49,7 +49,11 @@ mod traits { fn f(arg: T) {} //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f` fn g() -> impl PrivTr; + //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` + //~| ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` fn h() -> impl PrivTr {} + //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` + //~| ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` } impl Pub {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub` impl PubTr for Pub {} // OK, trait impl predicates @@ -89,7 +93,15 @@ mod generics { pub trait Tr5 { fn required() -> impl PrivTr>; + //~^ ERROR trait `generics::PrivTr>` is more private than the item `Tr5::required::{anon_assoc#0}` + //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}` + //~| ERROR trait `generics::PrivTr>` is more private than the item `Tr5::required::{anon_assoc#0}` + //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}` fn provided() -> impl PrivTr> {} + //~^ ERROR trait `generics::PrivTr>` is more private than the item `Tr5::provided::{anon_assoc#0}` + //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}` + //~| ERROR trait `generics::PrivTr>` is more private than the item `Tr5::provided::{anon_assoc#0}` + //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}` } } diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr index edcffaf6b70a..1fa415e27c16 100644 --- a/tests/ui/privacy/private-in-public-warn.stderr +++ b/tests/ui/privacy/private-in-public-warn.stderr @@ -194,8 +194,56 @@ note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` LL | trait PrivTr {} | ^^^^^^^^^^^^ +error: trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:51:19 + | +LL | fn g() -> impl PrivTr; + | ^^^^^^^^^^^ opaque type `traits::Tr3::g::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + +error: trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:51:19 + | +LL | fn g() -> impl PrivTr; + | ^^^^^^^^^^^ opaque type `traits::Tr3::g::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + +error: trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:54:19 + | +LL | fn h() -> impl PrivTr {} + | ^^^^^^^^^^^ opaque type `traits::Tr3::h::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + +error: trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:54:19 + | +LL | fn h() -> impl PrivTr {} + | ^^^^^^^^^^^ opaque type `traits::Tr3::h::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `traits::PrivTr` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:37:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^ + error: trait `traits::PrivTr` is more private than the item `traits::Pub` - --> $DIR/private-in-public-warn.rs:54:5 + --> $DIR/private-in-public-warn.rs:58:5 | LL | impl Pub {} | ^^^^^^^^^^^^^^^^^^^^^^ implementation `traits::Pub` is reachable at visibility `pub(crate)` @@ -207,103 +255,199 @@ LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Alias` - --> $DIR/private-in-public-warn.rs:63:5 + --> $DIR/private-in-public-warn.rs:67:5 | LL | pub type Alias where T: PrivTr = T; | ^^^^^^^^^^^^^^^^^ type alias `traits_where::Alias` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:59:5 + --> $DIR/private-in-public-warn.rs:63:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr2` - --> $DIR/private-in-public-warn.rs:66:5 + --> $DIR/private-in-public-warn.rs:70:5 | LL | pub trait Tr2 where T: PrivTr {} | ^^^^^^^^^^^^^^^^ trait `traits_where::Tr2` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:59:5 + --> $DIR/private-in-public-warn.rs:63:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Tr3::f` - --> $DIR/private-in-public-warn.rs:69:9 + --> $DIR/private-in-public-warn.rs:73:9 | LL | fn f(arg: T) where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function `traits_where::Tr3::f` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:59:5 + --> $DIR/private-in-public-warn.rs:63:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `traits_where::PrivTr` is more private than the item `traits_where::Pub` - --> $DIR/private-in-public-warn.rs:72:5 + --> $DIR/private-in-public-warn.rs:76:5 | LL | impl Pub where T: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation `traits_where::Pub` is reachable at visibility `pub(crate)` | note: but trait `traits_where::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:59:5 + --> $DIR/private-in-public-warn.rs:63:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^ error: trait `generics::PrivTr` is more private than the item `generics::Tr1` - --> $DIR/private-in-public-warn.rs:84:5 + --> $DIR/private-in-public-warn.rs:88:5 | LL | pub trait Tr1: PrivTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr1` is reachable at visibility `pub(crate)` | note: but trait `generics::PrivTr` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:80:5 + --> $DIR/private-in-public-warn.rs:84:5 | LL | trait PrivTr {} | ^^^^^^^^^^^^^^^ error: type `generics::Priv` is more private than the item `generics::Tr2` - --> $DIR/private-in-public-warn.rs:86:5 + --> $DIR/private-in-public-warn.rs:90:5 | LL | pub trait Tr2: PubTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr2` is reachable at visibility `pub(crate)` | note: but type `generics::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:78:5 + --> $DIR/private-in-public-warn.rs:82:5 | LL | struct Priv(T); | ^^^^^^^^^^^^^^^^^^^ error: type `generics::Priv` is more private than the item `generics::Tr3` - --> $DIR/private-in-public-warn.rs:87:5 + --> $DIR/private-in-public-warn.rs:91:5 | LL | pub trait Tr3: PubTr<[Priv; 1]> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `generics::Tr3` is reachable at visibility `pub(crate)` | note: but type `generics::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:78:5 + --> $DIR/private-in-public-warn.rs:82:5 | LL | struct Priv(T); | ^^^^^^^^^^^^^^^^^^^ error: type `generics::Priv` is more private than the item `Tr4` - --> $DIR/private-in-public-warn.rs:88:5 + --> $DIR/private-in-public-warn.rs:92:5 | LL | pub trait Tr4: PubTr> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `Tr4` is reachable at visibility `pub(crate)` | note: but type `generics::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:78:5 + --> $DIR/private-in-public-warn.rs:82:5 + | +LL | struct Priv(T); + | ^^^^^^^^^^^^^^^^^^^ + +error: trait `generics::PrivTr>` is more private than the item `Tr5::required::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:95:26 + | +LL | fn required() -> impl PrivTr>; + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `generics::PrivTr>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:84:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^^^^ + +error: type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:95:26 + | +LL | fn required() -> impl PrivTr>; + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv<()>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:82:5 + | +LL | struct Priv(T); + | ^^^^^^^^^^^^^^^^^^^ + +error: trait `generics::PrivTr>` is more private than the item `Tr5::required::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:95:26 + | +LL | fn required() -> impl PrivTr>; + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `generics::PrivTr>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:84:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^^^^ + +error: type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:95:26 + | +LL | fn required() -> impl PrivTr>; + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv<()>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:82:5 + | +LL | struct Priv(T); + | ^^^^^^^^^^^^^^^^^^^ + +error: trait `generics::PrivTr>` is more private than the item `Tr5::provided::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:100:26 + | +LL | fn provided() -> impl PrivTr> {} + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `generics::PrivTr>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:84:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^^^^ + +error: type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:100:26 + | +LL | fn provided() -> impl PrivTr> {} + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv<()>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:82:5 + | +LL | struct Priv(T); + | ^^^^^^^^^^^^^^^^^^^ + +error: trait `generics::PrivTr>` is more private than the item `Tr5::provided::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:100:26 + | +LL | fn provided() -> impl PrivTr> {} + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but trait `generics::PrivTr>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:84:5 + | +LL | trait PrivTr {} + | ^^^^^^^^^^^^^^^ + +error: type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}` + --> $DIR/private-in-public-warn.rs:100:26 + | +LL | fn provided() -> impl PrivTr> {} + | ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)` + | +note: but type `generics::Priv<()>` is only usable at visibility `pub(self)` + --> $DIR/private-in-public-warn.rs:82:5 | LL | struct Priv(T); | ^^^^^^^^^^^^^^^^^^^ error[E0446]: private type `impls::Priv` in public interface - --> $DIR/private-in-public-warn.rs:119:9 + --> $DIR/private-in-public-warn.rs:131:9 | LL | struct Priv; | ----------- `impls::Priv` declared as private @@ -312,19 +456,19 @@ LL | type Alias = Priv; | ^^^^^^^^^^ can't leak private type error: type `aliases_pub::Priv` is more private than the item `aliases_pub::::f` - --> $DIR/private-in-public-warn.rs:190:9 + --> $DIR/private-in-public-warn.rs:202:9 | LL | pub fn f(arg: Priv) {} | ^^^^^^^^^^^^^^^^^^^ associated function `aliases_pub::::f` is reachable at visibility `pub(crate)` | note: but type `aliases_pub::Priv` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:163:5 + --> $DIR/private-in-public-warn.rs:175:5 | LL | struct Priv; | ^^^^^^^^^^^ error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:193:9 + --> $DIR/private-in-public-warn.rs:205:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -333,7 +477,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:196:9 + --> $DIR/private-in-public-warn.rs:208:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -342,7 +486,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:199:9 + --> $DIR/private-in-public-warn.rs:211:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -351,7 +495,7 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error[E0446]: private type `aliases_pub::Priv` in public interface - --> $DIR/private-in-public-warn.rs:202:9 + --> $DIR/private-in-public-warn.rs:214:9 | LL | struct Priv; | ----------- `aliases_pub::Priv` declared as private @@ -360,37 +504,37 @@ LL | type Check = Priv; | ^^^^^^^^^^ can't leak private type error: trait `PrivTr1` is more private than the item `aliases_priv::Tr1` - --> $DIR/private-in-public-warn.rs:232:5 + --> $DIR/private-in-public-warn.rs:244:5 | LL | pub trait Tr1: PrivUseAliasTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr1` is reachable at visibility `pub(crate)` | note: but trait `PrivTr1` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:218:5 + --> $DIR/private-in-public-warn.rs:230:5 | LL | trait PrivTr1 { | ^^^^^^^^^^^^^^^^^^^^^ error: trait `PrivTr1` is more private than the item `aliases_priv::Tr2` - --> $DIR/private-in-public-warn.rs:234:5 + --> $DIR/private-in-public-warn.rs:246:5 | LL | pub trait Tr2: PrivUseAliasTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)` | note: but trait `PrivTr1` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:218:5 + --> $DIR/private-in-public-warn.rs:230:5 | LL | trait PrivTr1 { | ^^^^^^^^^^^^^^^^^^^^^ error: type `Priv2` is more private than the item `aliases_priv::Tr2` - --> $DIR/private-in-public-warn.rs:234:5 + --> $DIR/private-in-public-warn.rs:246:5 | LL | pub trait Tr2: PrivUseAliasTr {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `aliases_priv::Tr2` is reachable at visibility `pub(crate)` | note: but type `Priv2` is only usable at visibility `pub(self)` - --> $DIR/private-in-public-warn.rs:216:5 + --> $DIR/private-in-public-warn.rs:228:5 | LL | struct Priv2; | ^^^^^^^^^^^^ @@ -410,7 +554,7 @@ LL | pub type Alias = T; = note: `#[warn(type_alias_bounds)]` on by default warning: where clauses on type aliases are not enforced - --> $DIR/private-in-public-warn.rs:63:29 + --> $DIR/private-in-public-warn.rs:67:29 | LL | pub type Alias where T: PrivTr = T; | ------^^^^^^^^^ @@ -422,6 +566,6 @@ LL | pub type Alias where T: PrivTr = T; see issue #112792 for more information = help: add `#![feature(lazy_type_alias)]` to the crate attributes to enable the desired semantics -error: aborting due to 34 previous errors; 2 warnings emitted +error: aborting due to 46 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/privacy/private-inferred-type.rs b/tests/ui/privacy/private-inferred-type.rs index 8c07226fe0e4..ed22ad44c449 100644 --- a/tests/ui/privacy/private-inferred-type.rs +++ b/tests/ui/privacy/private-inferred-type.rs @@ -115,11 +115,11 @@ fn main() { m::m!(); - m::leak_anon1(); //~ ERROR trait `Trait` is private + m::leak_anon1(); //~ ERROR trait `m::Trait` is private m::leak_anon2(); //~ ERROR type `Priv` is private m::leak_anon3(); //~ ERROR type `Priv` is private - m::leak_dyn1(); //~ ERROR trait `Trait` is private + m::leak_dyn1(); //~ ERROR trait `m::Trait` is private m::leak_dyn2(); //~ ERROR type `Priv` is private m::leak_dyn3(); //~ ERROR type `Priv` is private diff --git a/tests/ui/privacy/private-inferred-type.stderr b/tests/ui/privacy/private-inferred-type.stderr index fc3f9ab62bfa..0dfa799a4d95 100644 --- a/tests/ui/privacy/private-inferred-type.stderr +++ b/tests/ui/privacy/private-inferred-type.stderr @@ -172,7 +172,7 @@ LL | m::m!(); | = note: this error originates in the macro `m::m` (in Nightly builds, run with -Z macro-backtrace for more info) -error: trait `Trait` is private +error: trait `m::Trait` is private --> $DIR/private-inferred-type.rs:118:5 | LL | m::leak_anon1(); @@ -190,7 +190,7 @@ error: type `Priv` is private LL | m::leak_anon3(); | ^^^^^^^^^^^^^^^ private type -error: trait `Trait` is private +error: trait `m::Trait` is private --> $DIR/private-inferred-type.rs:122:5 | LL | m::leak_dyn1(); diff --git a/tests/ui/privacy/private-item-simple.rs b/tests/ui/privacy/private-item-simple.rs index 1f718ed9201a..68b20991a626 100644 --- a/tests/ui/privacy/private-item-simple.rs +++ b/tests/ui/privacy/private-item-simple.rs @@ -1,3 +1,5 @@ +//! regression test for issue #3993 + mod a { fn f() {} } @@ -5,3 +7,7 @@ mod a { fn main() { a::f(); //~ ERROR function `f` is private } + +fn foo() { + use a::f; //~ ERROR function `f` is private +} diff --git a/tests/ui/privacy/private-item-simple.stderr b/tests/ui/privacy/private-item-simple.stderr index 330d892e939d..95165857940e 100644 --- a/tests/ui/privacy/private-item-simple.stderr +++ b/tests/ui/privacy/private-item-simple.stderr @@ -1,15 +1,27 @@ error[E0603]: function `f` is private - --> $DIR/private-item-simple.rs:6:8 + --> $DIR/private-item-simple.rs:12:12 + | +LL | use a::f; + | ^ private function + | +note: the function `f` is defined here + --> $DIR/private-item-simple.rs:4:5 + | +LL | fn f() {} + | ^^^^^^ + +error[E0603]: function `f` is private + --> $DIR/private-item-simple.rs:8:8 | LL | a::f(); | ^ private function | note: the function `f` is defined here - --> $DIR/private-item-simple.rs:2:5 + --> $DIR/private-item-simple.rs:4:5 | LL | fn f() {} | ^^^^^^ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/privacy/private-struct-field-in-module.rs b/tests/ui/privacy/private-struct-field-in-module.rs new file mode 100644 index 000000000000..7ed8def1c691 --- /dev/null +++ b/tests/ui/privacy/private-struct-field-in-module.rs @@ -0,0 +1,15 @@ +//! regression test for + +mod sub { + pub struct S { len: usize } + impl S { + pub fn new() -> S { S { len: 0 } } + pub fn len(&self) -> usize { self.len } + } +} + +fn main() { + let s = sub::S::new(); + let v = s.len; //~ ERROR field `len` of struct `S` is private + s.len = v; //~ ERROR field `len` of struct `S` is private +} diff --git a/tests/ui/privacy/private-struct-field-in-module.stderr b/tests/ui/privacy/private-struct-field-in-module.stderr new file mode 100644 index 000000000000..2394686f69ca --- /dev/null +++ b/tests/ui/privacy/private-struct-field-in-module.stderr @@ -0,0 +1,20 @@ +error[E0616]: field `len` of struct `S` is private + --> $DIR/private-struct-field-in-module.rs:13:15 + | +LL | let v = s.len; + | ^^^ private field + | +help: a method `len` also exists, call it with parentheses + | +LL | let v = s.len(); + | ++ + +error[E0616]: field `len` of struct `S` is private + --> $DIR/private-struct-field-in-module.rs:14:7 + | +LL | s.len = v; + | ^^^ private field + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0616`. diff --git a/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs b/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs index 9e2aa898afe8..d45f2639d182 100644 --- a/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs +++ b/tests/ui/privacy/pub-priv-dep/auxiliary/pm.rs @@ -1,8 +1,3 @@ -//@ force-host -//@ no-prefer-dynamic - -#![crate_type = "proc-macro"] - extern crate proc_macro; use proc_macro::TokenStream; diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs index eae0f9756a10..ba947de7f182 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.rs +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.rs @@ -1,6 +1,6 @@ //@ aux-crate:priv:priv_dep=priv_dep.rs //@ aux-build:pub_dep.rs -//@ aux-crate:priv:pm=pm.rs +//@ proc-macro:priv:pm.rs //@ compile-flags: -Zunstable-options // Basic behavior check of exported_private_dependencies from either a public @@ -74,8 +74,12 @@ pub trait MyPubTrait { //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface fn required_impl_trait() -> impl OtherTrait; + //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface + //~| ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface fn provided_impl_trait() -> impl OtherTrait { OtherType } + //~^ ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface + //~| ERROR trait `OtherTrait` from private dependency 'priv_dep' in public interface fn required_concrete() -> OtherType; //~^ ERROR type `OtherType` from private dependency 'priv_dep' in public interface diff --git a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr index e66db53f65dd..609dbd77f9c1 100644 --- a/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr +++ b/tests/ui/privacy/pub-priv-dep/pub-priv1.stderr @@ -11,55 +11,55 @@ LL | #![deny(exported_private_dependencies)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: macro `m` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:156:9 + --> $DIR/pub-priv1.rs:160:9 | LL | pub use priv_dep::m; | ^^^^^^^^^^^ error: macro `fn_like` from private dependency 'pm' is re-exported - --> $DIR/pub-priv1.rs:158:9 + --> $DIR/pub-priv1.rs:162:9 | LL | pub use pm::fn_like; | ^^^^^^^^^^^ error: derive macro `PmDerive` from private dependency 'pm' is re-exported - --> $DIR/pub-priv1.rs:160:9 + --> $DIR/pub-priv1.rs:164:9 | LL | pub use pm::PmDerive; | ^^^^^^^^^^^^ error: attribute macro `pm_attr` from private dependency 'pm' is re-exported - --> $DIR/pub-priv1.rs:162:9 + --> $DIR/pub-priv1.rs:166:9 | LL | pub use pm::pm_attr; | ^^^^^^^^^^^ error: variant `V1` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:165:9 + --> $DIR/pub-priv1.rs:169:9 | LL | pub use priv_dep::E::V1; | ^^^^^^^^^^^^^^^ error: type alias `Unit` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:168:9 + --> $DIR/pub-priv1.rs:172:9 | LL | pub use priv_dep::Unit; | ^^^^^^^^^^^^^^ error: type alias `PubPub` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:170:9 + --> $DIR/pub-priv1.rs:174:9 | LL | pub use priv_dep::PubPub; | ^^^^^^^^^^^^^^^^ error: type alias `PubPriv` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:172:9 + --> $DIR/pub-priv1.rs:176:9 | LL | pub use priv_dep::PubPriv; | ^^^^^^^^^^^^^^^^^ error: struct `Renamed` from private dependency 'priv_dep' is re-exported - --> $DIR/pub-priv1.rs:174:9 + --> $DIR/pub-priv1.rs:178:9 | LL | pub use priv_dep::OtherType as Renamed; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -124,92 +124,120 @@ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface LL | type Foo: OtherTrait; | ^^^^^^^^^^^^^^^^^^^^ +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:76:33 + | +LL | fn required_impl_trait() -> impl OtherTrait; + | ^^^^^^^^^^^^^^^ + +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:76:33 + | +LL | fn required_impl_trait() -> impl OtherTrait; + | ^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:80:33 + | +LL | fn provided_impl_trait() -> impl OtherTrait { OtherType } + | ^^^^^^^^^^^^^^^ + +error: trait `OtherTrait` from private dependency 'priv_dep' in public interface + --> $DIR/pub-priv1.rs:80:33 + | +LL | fn provided_impl_trait() -> impl OtherTrait { OtherType } + | ^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:80:5 + --> $DIR/pub-priv1.rs:84:5 | LL | fn required_concrete() -> OtherType; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:83:5 + --> $DIR/pub-priv1.rs:87:5 | LL | fn provided_concrete() -> OtherType { OtherType } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:87:1 + --> $DIR/pub-priv1.rs:91:1 | LL | pub trait WithSuperTrait: OtherTrait {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:96:5 + --> $DIR/pub-priv1.rs:100:5 | LL | type X = OtherType; | ^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:100:1 + --> $DIR/pub-priv1.rs:104:1 | LL | pub fn in_bounds(x: T) { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:103:1 + --> $DIR/pub-priv1.rs:107:1 | LL | pub fn private_return_impl_trait() -> impl OtherTrait { OtherType } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:106:1 + --> $DIR/pub-priv1.rs:110:1 | LL | pub fn private_return() -> OtherType { OtherType } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:109:1 + --> $DIR/pub-priv1.rs:113:1 | LL | pub fn private_in_generic() -> std::num::Saturating { unimplemented!() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:112:1 + --> $DIR/pub-priv1.rs:116:1 | LL | pub static STATIC: OtherType = OtherType; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:115:1 + --> $DIR/pub-priv1.rs:119:1 | LL | pub const CONST: OtherType = OtherType; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:118:1 + --> $DIR/pub-priv1.rs:122:1 | LL | pub type Alias = OtherType; | ^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:121:1 + --> $DIR/pub-priv1.rs:125:1 | LL | pub type AliasOfAlias = priv_dep::PubPub; | ^^^^^^^^^^^^^^^^^^^^^ error: trait `OtherTrait` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:126:1 + --> $DIR/pub-priv1.rs:130:1 | LL | impl OtherTrait for PublicWithPrivateImpl {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:131:1 + --> $DIR/pub-priv1.rs:135:1 | LL | impl PubTraitOnPrivate for OtherType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:131:1 + --> $DIR/pub-priv1.rs:135:1 | LL | impl PubTraitOnPrivate for OtherType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -217,25 +245,25 @@ LL | impl PubTraitOnPrivate for OtherType {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:137:1 + --> $DIR/pub-priv1.rs:141:1 | LL | impl From for PublicWithStdImpl { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:139:5 + --> $DIR/pub-priv1.rs:143:5 | LL | fn from(val: OtherType) -> Self { Self } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:143:1 + --> $DIR/pub-priv1.rs:147:1 | LL | impl From for OtherType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:143:1 + --> $DIR/pub-priv1.rs:147:1 | LL | impl From for OtherType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -243,18 +271,18 @@ LL | impl From for OtherType { = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:146:5 + --> $DIR/pub-priv1.rs:150:5 | LL | fn from(val: PublicWithStdImpl) -> Self { Self } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: type `OtherType` from private dependency 'priv_dep' in public interface - --> $DIR/pub-priv1.rs:146:5 + --> $DIR/pub-priv1.rs:150:5 | LL | fn from(val: PublicWithStdImpl) -> Self { Self } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 41 previous errors +error: aborting due to 45 previous errors diff --git a/tests/ui/privacy/restricted/test.rs b/tests/ui/privacy/restricted/test.rs index 82432b4db509..26018fbb01a6 100644 --- a/tests/ui/privacy/restricted/test.rs +++ b/tests/ui/privacy/restricted/test.rs @@ -48,6 +48,6 @@ fn main() { } mod pathological { - pub(in bad::path) mod m1 {} //~ ERROR failed to resolve: use of unresolved module or unlinked crate `bad` + pub(in bad::path) mod m1 {} //~ ERROR: cannot find module or crate `bad` pub(in foo) mod m2 {} //~ ERROR visibilities can only be restricted to ancestor modules } diff --git a/tests/ui/privacy/restricted/test.stderr b/tests/ui/privacy/restricted/test.stderr index 8d7925cf99fc..ae56e0bf7844 100644 --- a/tests/ui/privacy/restricted/test.stderr +++ b/tests/ui/privacy/restricted/test.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `bad` +error[E0433]: cannot find module or crate `bad` in the crate root --> $DIR/test.rs:51:12 | LL | pub(in bad::path) mod m1 {} diff --git a/tests/ui/privacy/suggest-box-new.rs b/tests/ui/privacy/suggest-box-new.rs index ff585387020e..87ee13d15edb 100644 --- a/tests/ui/privacy/suggest-box-new.rs +++ b/tests/ui/privacy/suggest-box-new.rs @@ -14,7 +14,7 @@ fn main() { let _ = std::collections::HashMap(); //~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` let _ = std::collections::HashMap {}; - //~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + //~^ ERROR cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields let _ = Box {}; //~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields // test that we properly instantiate the parameter of `Box::::new` with an inference variable diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index e3a7e5f62017..7367672351d6 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -5,6 +5,7 @@ LL | let _ = std::collections::HashMap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + ::: $SRC_DIR/std/src/collections/hash/map.rs:LL:COL | = note: `std::collections::HashMap` defined here help: you might have meant to use an associated function to build this type @@ -12,14 +13,15 @@ help: you might have meant to use an associated function to build this type LL | let _ = std::collections::HashMap::new(); | +++++ LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap(); LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL | let _ = ::default(); @@ -73,7 +75,7 @@ LL - })), LL + wtf: Some(::default()), | -error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields +error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields --> $DIR/suggest-box-new.rs:16:13 | LL | let _ = std::collections::HashMap {}; @@ -86,14 +88,15 @@ LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::new(); | LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL - let _ = std::collections::HashMap {}; diff --git a/tests/ui/privacy/trait_more_private_than_item.rs b/tests/ui/privacy/trait_more_private_than_item.rs new file mode 100644 index 000000000000..f55a494abd21 --- /dev/null +++ b/tests/ui/privacy/trait_more_private_than_item.rs @@ -0,0 +1,21 @@ +//! regression test for +//@ check-pass + +use std::any::Any; +use std::any::TypeId; + +trait Private { + fn call(&self, p: P, r: R); +} +pub trait Public: Private< +//~^ WARNING trait `Private<::P, ::R>` is more private than the item `Public` + ::P, + ::R +> { + type P; + type R; + + fn call_inner(&self); +} + +fn main() {} diff --git a/tests/ui/privacy/trait_more_private_than_item.stderr b/tests/ui/privacy/trait_more_private_than_item.stderr new file mode 100644 index 000000000000..03bffcd390c5 --- /dev/null +++ b/tests/ui/privacy/trait_more_private_than_item.stderr @@ -0,0 +1,19 @@ +warning: trait `Private<::P, ::R>` is more private than the item `Public` + --> $DIR/trait_more_private_than_item.rs:10:1 + | +LL | / pub trait Public: Private< +LL | | +LL | | ::P, +LL | | ::R +LL | | > { + | |_^ trait `Public` is reachable at visibility `pub` + | +note: but trait `Private<::P, ::R>` is only usable at visibility `pub(crate)` + --> $DIR/trait_more_private_than_item.rs:7:1 + | +LL | trait Private { + | ^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(private_bounds)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/privacy/unreachable-issue-121455.rs b/tests/ui/privacy/unreachable-issue-121455.rs index 5da30d6ed639..c1822034eb19 100644 --- a/tests/ui/privacy/unreachable-issue-121455.rs +++ b/tests/ui/privacy/unreachable-issue-121455.rs @@ -1,5 +1,6 @@ fn test(s: &Self::Id) { -//~^ ERROR failed to resolve: `Self` is only available in impls, traits, and type definitions +//~^ ERROR: cannot find `Self` +//~| NOTE: `Self` is only available in impls, traits, and type definitions match &s[0..3] {} } diff --git a/tests/ui/privacy/unreachable-issue-121455.stderr b/tests/ui/privacy/unreachable-issue-121455.stderr index 864e950a98eb..fe4c38081b74 100644 --- a/tests/ui/privacy/unreachable-issue-121455.stderr +++ b/tests/ui/privacy/unreachable-issue-121455.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find `Self` in this scope --> $DIR/unreachable-issue-121455.rs:1:13 | LL | fn test(s: &Self::Id) { diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs index 63d3c79055ca..e36a12beb818 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -9,7 +9,7 @@ use builtin_attrs::{bench, test}; #[repr(C)] //~ ERROR `repr` is ambiguous struct S; -#[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous +#[cfg_attr(true, repr(C))] //~ ERROR `repr` is ambiguous struct SCond; #[test] // OK, shadowed diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr index ff7894a41eab..d05701986260 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -20,10 +20,10 @@ LL | use builtin_attrs::*; = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:12:19 + --> $DIR/ambiguous-builtin-attrs.rs:12:18 | -LL | #[cfg_attr(all(), repr(C))] - | ^^^^ ambiguous name +LL | #[cfg_attr(true, repr(C))] + | ^^^^ ambiguous name | = note: ambiguous because of a name conflict with a builtin attribute = note: `repr` could refer to a built-in attribute diff --git a/tests/ui/proc-macro/amputate-span.stderr b/tests/ui/proc-macro/amputate-span.stderr index aa797339be46..bd2f39edec4f 100644 --- a/tests/ui/proc-macro/amputate-span.stderr +++ b/tests/ui/proc-macro/amputate-span.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `Command` +error[E0433]: cannot find type `Command` in this scope --> $DIR/amputate-span.rs:49:5 | LL | Command::new("git"); @@ -9,7 +9,7 @@ help: consider importing this struct LL + use std::process::Command; | -error[E0433]: failed to resolve: use of undeclared type `Command` +error[E0433]: cannot find type `Command` in this scope --> $DIR/amputate-span.rs:63:9 | LL | Command::new("git"); diff --git a/tests/ui/proc-macro/attribute.stderr b/tests/ui/proc-macro/attribute.stderr index e7127c8ef1d2..24962cf270a4 100644 --- a/tests/ui/proc-macro/attribute.stderr +++ b/tests/ui/proc-macro/attribute.stderr @@ -16,7 +16,9 @@ error[E0539]: malformed `proc_macro_derive` attribute input --> $DIR/attribute.rs:15:1 | LL | #[proc_macro_derive = ""] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^----^ + | | + | expected this to be a list | = note: for more information, visit help: try changing it to one of the following valid forms of the attribute diff --git a/tests/ui/proc-macro/auxiliary/api/ident.rs b/tests/ui/proc-macro/auxiliary/api/ident.rs new file mode 100644 index 000000000000..4451b896b65c --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/api/ident.rs @@ -0,0 +1,37 @@ +use proc_macro::{Ident, Span}; + +// FIXME: `Ident` does not yet implement `PartialEq` directly (#146553) +fn assert_eq(l: Ident, r: Ident) { + assert_eq!(l.to_string(), r.to_string()); +} + +fn assert_ne(l: Ident, r: Ident) { + assert_ne!(l.to_string(), r.to_string()); +} + +fn new(s: &str) -> Ident { + Ident::new(s, Span::call_site()) +} + +fn new_raw(s: &str) -> Ident { + Ident::new_raw(s, Span::call_site()) +} + +const LATIN_CAPITAL_LETTER_K: &str = "K"; +const KELVIN_SIGN: &str = "K"; + +const NORMAL_MIDDLE_DOT: &str = "L·L"; +const GREEK_ANO_TELEIA: &str = "L·L"; + +pub fn test() { + assert_eq(new("foo"), new("foo")); + assert_ne(new("foo"), new_raw("foo")); + + assert_ne!(LATIN_CAPITAL_LETTER_K, KELVIN_SIGN); + assert_eq(new(LATIN_CAPITAL_LETTER_K), new(KELVIN_SIGN)); + assert_eq(new_raw(LATIN_CAPITAL_LETTER_K), new_raw(KELVIN_SIGN)); + + assert_ne!(NORMAL_MIDDLE_DOT, GREEK_ANO_TELEIA); + assert_eq(new(NORMAL_MIDDLE_DOT), new(GREEK_ANO_TELEIA)); + assert_eq(new_raw(NORMAL_MIDDLE_DOT), new_raw(GREEK_ANO_TELEIA)); +} diff --git a/tests/ui/proc-macro/auxiliary/api/proc_macro_api_tests.rs b/tests/ui/proc-macro/auxiliary/api/proc_macro_api_tests.rs index abd667d8ce1d..d778e46da6b9 100644 --- a/tests/ui/proc-macro/auxiliary/api/proc_macro_api_tests.rs +++ b/tests/ui/proc-macro/auxiliary/api/proc_macro_api_tests.rs @@ -6,7 +6,9 @@ extern crate proc_macro; mod cmp; +mod ident; mod literal; +mod tokenstream; use proc_macro::TokenStream; @@ -15,7 +17,9 @@ pub fn run(input: TokenStream) -> TokenStream { assert!(input.is_empty()); cmp::test(); + ident::test(); literal::test(); + tokenstream::test(); TokenStream::new() } diff --git a/tests/ui/proc-macro/auxiliary/api/tokenstream.rs b/tests/ui/proc-macro/auxiliary/api/tokenstream.rs new file mode 100644 index 000000000000..7078f4413051 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/api/tokenstream.rs @@ -0,0 +1,28 @@ +use proc_macro::*; + +fn assert_eq(l: TokenStream, r: TokenStream) { + assert_eq!(l.to_string(), r.to_string()); + for (lt, rt) in l.into_iter().zip(r) { + assert_eq!(lt.to_string(), rt.to_string()); + } +} + +pub fn test() { + assert_eq(TokenStream::new(), TokenStream::new()); + let mut stream = TokenStream::new(); + assert!(stream.is_empty()); + stream.extend(TokenStream::new()); + assert_eq(stream.clone(), TokenStream::new()); + + let old = stream.clone(); + stream.extend(vec![TokenTree::Ident(Ident::new("foo", Span::call_site()))]); + assert!(!stream.is_empty()); + assert!(old.is_empty()); + + let stream2 = stream + .clone() + .into_iter() + .inspect(|tree| assert_eq!(tree.to_string(), "foo")) + .collect::(); + assert_eq(stream.clone(), stream2); +} diff --git a/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs b/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs index cb60c182a43c..b1da93de2a6e 100644 --- a/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs +++ b/tests/ui/proc-macro/auxiliary/derive-attr-cfg.rs @@ -4,6 +4,6 @@ use proc_macro::TokenStream; #[proc_macro_derive(Foo, attributes(foo))] pub fn derive(input: TokenStream) -> TokenStream { - assert!(!input.to_string().contains("#[cfg(any())]")); + assert!(!input.to_string().contains("#[cfg(false)]")); "".parse().unwrap() } diff --git a/tests/ui/proc-macro/auxiliary/env.rs b/tests/ui/proc-macro/auxiliary/env.rs index d01e3b42d4ce..f0f0328e131e 100644 --- a/tests/ui/proc-macro/auxiliary/env.rs +++ b/tests/ui/proc-macro/auxiliary/env.rs @@ -3,11 +3,11 @@ extern crate proc_macro; use proc_macro::TokenStream; -use proc_macro::tracked_env::var; +use proc_macro::tracked::env_var; #[proc_macro] pub fn generate_const(input: TokenStream) -> TokenStream { - let the_const = match var("THE_CONST") { + let the_const = match env_var("THE_CONST") { Ok(x) if x == "12" => { "const THE_CONST: u32 = 12;" } @@ -15,7 +15,7 @@ pub fn generate_const(input: TokenStream) -> TokenStream { "const THE_CONST: u32 = 0;" } }; - let another = if var("ANOTHER").is_ok() { + let another = if env_var("ANOTHER").is_ok() { "const ANOTHER: u32 = 1;" } else { "const ANOTHER: u32 = 2;" diff --git a/tests/ui/proc-macro/auxiliary/nested-empty-proc-macro.rs b/tests/ui/proc-macro/auxiliary/nested-empty-proc-macro.rs new file mode 100644 index 000000000000..a1cb4c1c7638 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/nested-empty-proc-macro.rs @@ -0,0 +1,18 @@ +// Auxiliary proc-macro for issue #99173 +// Tests that nested proc-macro calls with empty output don't cause ICE + +extern crate proc_macro; + +use proc_macro::TokenStream; + +// This macro returns an empty TokenStream +#[proc_macro] +pub fn ignore(_input: TokenStream) -> TokenStream { + TokenStream::new() +} + +// This macro generates code that calls the `ignore` macro +#[proc_macro] +pub fn outer_macro(_input: TokenStream) -> TokenStream { + "nested_empty_proc_macro::ignore!(42)".parse().unwrap() +} diff --git a/tests/ui/proc-macro/auxiliary/sub-error-diag.rs b/tests/ui/proc-macro/auxiliary/sub-error-diag.rs new file mode 100644 index 000000000000..5ce8c5d90304 --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/sub-error-diag.rs @@ -0,0 +1,17 @@ +#![feature(proc_macro_diagnostic)] + +extern crate proc_macro; + +use proc_macro::{Diagnostic, Level, Span}; + +#[proc_macro_attribute] +pub fn proc_emit_err( + _: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + Diagnostic::new(Level::Error, "Parent message") + .span_error(Span::call_site(), "Child message") + .emit(); + + input +} diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr index f2981499367b..5b472d407044 100644 --- a/tests/ui/proc-macro/bad-projection.stderr +++ b/tests/ui/proc-macro/bad-projection.stderr @@ -33,7 +33,7 @@ LL | pub fn uwu() -> <() as Project>::Assoc {} | takes 0 arguments | required by a bound introduced by this call | -note: required by a bound in `ProcMacro::bang` +note: required by a bound in `proc_macro::bridge::client::ProcMacro::bang` --> $SRC_DIR/proc_macro/src/bridge/client.rs:LL:COL error[E0277]: the trait bound `(): Project` is not satisfied diff --git a/tests/ui/proc-macro/cfg-eval.rs b/tests/ui/proc-macro/cfg-eval.rs index 9e9e46912588..60c94ad2a752 100644 --- a/tests/ui/proc-macro/cfg-eval.rs +++ b/tests/ui/proc-macro/cfg-eval.rs @@ -17,9 +17,9 @@ extern crate test_macros; struct S1 { #[cfg(false)] field_false: u8, - #[cfg(all(/*true*/))] + #[cfg(true)] #[cfg_attr(FALSE, unknown_attr)] - #[cfg_attr(all(/*true*/), allow())] //~ WARN unused attribute + #[cfg_attr(true, allow())] //~ WARN unused attribute field_true: u8, } @@ -29,9 +29,9 @@ struct S2 {} fn main() { // Subtle - we need a trailing comma after the '1' - otherwise, `#[cfg_eval]` will - // turn this into `(#[cfg(all())] 1)`, which is a parenthesized expression, not a tuple + // turn this into `(#[cfg(true)] 1)`, which is a parenthesized expression, not a tuple // expression. `#[cfg]` is not supported inside parenthesized expressions, so this will // produce an error when attribute collection runs. let _ = #[cfg_eval] #[print_attr] #[cfg_attr(not(FALSE), rustc_dummy)] - (#[cfg(false)] 0, #[cfg(all(/*true*/))] 1,); + (#[cfg(false)] 0, #[cfg(true)] 1,); } diff --git a/tests/ui/proc-macro/cfg-eval.stderr b/tests/ui/proc-macro/cfg-eval.stderr index 1429dbde7bfc..72c452c7a08a 100644 --- a/tests/ui/proc-macro/cfg-eval.stderr +++ b/tests/ui/proc-macro/cfg-eval.stderr @@ -1,8 +1,8 @@ warning: unused attribute --> $DIR/cfg-eval.rs:22:5 | -LL | #[cfg_attr(all(/*true*/), allow())] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute +LL | #[cfg_attr(true, allow())] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | = note: attribute `allow` with an empty list has no effect = note: requested on the command line with `-W unused-attributes` diff --git a/tests/ui/proc-macro/cfg-eval.stdout b/tests/ui/proc-macro/cfg-eval.stdout index 5d88297ad688..6493eee46547 100644 --- a/tests/ui/proc-macro/cfg-eval.stdout +++ b/tests/ui/proc-macro/cfg-eval.stdout @@ -1,5 +1,5 @@ -PRINT-ATTR INPUT (DISPLAY): struct S1 { #[cfg(all())] #[allow()] field_true: u8, } -PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): struct S1 { #[cfg(all())] #[allow()] field_true : u8, } +PRINT-ATTR INPUT (DISPLAY): struct S1 { #[cfg(true)] #[allow()] field_true: u8, } +PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): struct S1 { #[cfg(true)] #[allow()] field_true : u8, } PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", @@ -28,19 +28,14 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "all", - span: $DIR/cfg-eval.rs:20:11: 20:14 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [], - span: $DIR/cfg-eval.rs:20:14: 20:24 (#0), + ident: "true", + span: $DIR/cfg-eval.rs:20:11: 20:15 (#0), }, ], - span: $DIR/cfg-eval.rs:20:10: 20:25 (#0), + span: $DIR/cfg-eval.rs:20:10: 20:16 (#0), }, ], - span: $DIR/cfg-eval.rs:20:6: 20:26 (#0), + span: $DIR/cfg-eval.rs:20:6: 20:17 (#0), }, Punct { ch: '#', @@ -52,15 +47,15 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ stream: TokenStream [ Ident { ident: "allow", - span: $DIR/cfg-eval.rs:22:31: 22:36 (#0), + span: $DIR/cfg-eval.rs:22:22: 22:27 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/cfg-eval.rs:22:36: 22:38 (#0), + span: $DIR/cfg-eval.rs:22:27: 22:29 (#0), }, ], - span: $DIR/cfg-eval.rs:22:6: 22:40 (#0), + span: $DIR/cfg-eval.rs:22:6: 22:31 (#0), }, Ident { ident: "field_true", @@ -84,7 +79,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/cfg-eval.rs:17:11: 24:2 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] (#[cfg(all())] 1,) +PRINT-ATTR INPUT (DISPLAY): #[rustc_dummy] (#[cfg(true)] 1,) PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '#', @@ -120,32 +115,27 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ delimiter: Parenthesis, stream: TokenStream [ Ident { - ident: "all", - span: $DIR/cfg-eval.rs:36:29: 36:32 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [], - span: $DIR/cfg-eval.rs:36:32: 36:42 (#0), + ident: "true", + span: $DIR/cfg-eval.rs:36:29: 36:33 (#0), }, ], - span: $DIR/cfg-eval.rs:36:28: 36:43 (#0), + span: $DIR/cfg-eval.rs:36:28: 36:34 (#0), }, ], - span: $DIR/cfg-eval.rs:36:24: 36:44 (#0), + span: $DIR/cfg-eval.rs:36:24: 36:35 (#0), }, Literal { kind: Integer, symbol: "1", suffix: None, - span: $DIR/cfg-eval.rs:36:45: 36:46 (#0), + span: $DIR/cfg-eval.rs:36:36: 36:37 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/cfg-eval.rs:36:46: 36:47 (#0), + span: $DIR/cfg-eval.rs:36:37: 36:38 (#0), }, ], - span: $DIR/cfg-eval.rs:36:5: 36:48 (#0), + span: $DIR/cfg-eval.rs:36:5: 36:39 (#0), }, ] diff --git a/tests/ui/proc-macro/derive-attr-cfg.rs b/tests/ui/proc-macro/derive-attr-cfg.rs index 2f3516cabae9..21d3a93ffa6c 100644 --- a/tests/ui/proc-macro/derive-attr-cfg.rs +++ b/tests/ui/proc-macro/derive-attr-cfg.rs @@ -9,7 +9,7 @@ use derive_attr_cfg::Foo; #[derive(Foo)] #[foo] struct S { - #[cfg(any())] + #[cfg(false)] x: i32 } diff --git a/tests/ui/proc-macro/derive-b.rs b/tests/ui/proc-macro/derive-b.rs index 68d341478f18..c04152f629ca 100644 --- a/tests/ui/proc-macro/derive-b.rs +++ b/tests/ui/proc-macro/derive-b.rs @@ -4,7 +4,7 @@ extern crate derive_b_rpass as derive_b; #[derive(Debug, PartialEq, derive_b::B, Eq, Copy, Clone)] -#[cfg_attr(all(), B[arbitrary tokens])] +#[cfg_attr(true, B[arbitrary tokens])] struct B { #[C] a: u64 diff --git a/tests/ui/proc-macro/derive-helper-configured.rs b/tests/ui/proc-macro/derive-helper-configured.rs index b753e29b8bf3..b96ebdebaebb 100644 --- a/tests/ui/proc-macro/derive-helper-configured.rs +++ b/tests/ui/proc-macro/derive-helper-configured.rs @@ -7,9 +7,9 @@ extern crate test_macros; #[derive(Empty)] -#[cfg_attr(all(), empty_helper)] +#[cfg_attr(true, empty_helper)] struct S { - #[cfg_attr(all(), empty_helper)] + #[cfg_attr(true, empty_helper)] field: u8, } diff --git a/tests/ui/proc-macro/derive-macro-invalid-placement.rs b/tests/ui/proc-macro/derive-macro-invalid-placement.rs new file mode 100644 index 000000000000..fd24bd7284a9 --- /dev/null +++ b/tests/ui/proc-macro/derive-macro-invalid-placement.rs @@ -0,0 +1,39 @@ +//! regression test for + +#![feature(stmt_expr_attributes)] + +fn foo<#[derive(Debug)] T>() { //~ ERROR expected non-macro attribute, found attribute macro + match 0 { + #[derive(Debug)] //~ ERROR expected non-macro attribute, found attribute macro + _ => (), + } +} + +fn main() { + // fold_stmt (Item) + #[allow(dead_code)] + #[derive(Debug)] // should not warn + struct Foo; + + // fold_stmt (Mac) + #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s + println!("Hello, world!"); + + // fold_stmt (Semi) + #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s + "Hello, world!"; + + // fold_stmt (Local) + #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s + let _ = "Hello, world!"; + + // visit_expr + let _ = #[derive(Debug)] "Hello, world!"; + //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s + + let _ = [ + // filter_map_expr + #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s + "Hello, world!", + ]; +} diff --git a/tests/ui/proc-macro/derive-macro-invalid-placement.stderr b/tests/ui/proc-macro/derive-macro-invalid-placement.stderr new file mode 100644 index 000000000000..48111f4d3a14 --- /dev/null +++ b/tests/ui/proc-macro/derive-macro-invalid-placement.stderr @@ -0,0 +1,55 @@ +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/derive-macro-invalid-placement.rs:5:10 + | +LL | fn foo<#[derive(Debug)] T>() { + | ^^^^^^ not a non-macro attribute + +error: expected non-macro attribute, found attribute macro `derive` + --> $DIR/derive-macro-invalid-placement.rs:7:11 + | +LL | #[derive(Debug)] + | ^^^^^^ not a non-macro attribute + +error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s + --> $DIR/derive-macro-invalid-placement.rs:19:5 + | +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ not applicable here +LL | println!("Hello, world!"); + | -------------------------- not a `struct`, `enum` or `union` + +error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s + --> $DIR/derive-macro-invalid-placement.rs:23:5 + | +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ not applicable here +LL | "Hello, world!"; + | ---------------- not a `struct`, `enum` or `union` + +error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s + --> $DIR/derive-macro-invalid-placement.rs:27:5 + | +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ not applicable here +LL | let _ = "Hello, world!"; + | ------------------------ not a `struct`, `enum` or `union` + +error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s + --> $DIR/derive-macro-invalid-placement.rs:31:13 + | +LL | let _ = #[derive(Debug)] "Hello, world!"; + | ^^^^^^^^^^^^^^^^ --------------- not a `struct`, `enum` or `union` + | | + | not applicable here + +error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s + --> $DIR/derive-macro-invalid-placement.rs:36:9 + | +LL | #[derive(Debug)] + | ^^^^^^^^^^^^^^^^ not applicable here +LL | "Hello, world!", + | --------------- not a `struct`, `enum` or `union` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0774`. diff --git a/tests/ui/proc-macro/dollar-crate-issue-62325.stdout b/tests/ui/proc-macro/dollar-crate-issue-62325.stdout index bfd013476f3a..d1b7227c138d 100644 --- a/tests/ui/proc-macro/dollar-crate-issue-62325.stdout +++ b/tests/ui/proc-macro/dollar-crate-issue-62325.stdout @@ -57,54 +57,54 @@ PRINT-ATTR INPUT (DISPLAY): struct B(identity! ($crate :: S)); PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: $DIR/auxiliary/dollar-crate-external.rs:21:5: 21:11 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:5: 21:11 (#12), }, Ident { ident: "B", - span: $DIR/auxiliary/dollar-crate-external.rs:21:12: 21:13 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:12: 21:13 (#12), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "identity", - span: $DIR/auxiliary/dollar-crate-external.rs:21:14: 21:22 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:14: 21:22 (#12), }, Punct { ch: '!', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:21:22: 21:23 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:22: 21:23 (#12), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: $DIR/auxiliary/dollar-crate-external.rs:21:24: 21:30 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:24: 21:30 (#12), }, Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:31 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:31 (#12), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:21:31: 21:32 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:31: 21:32 (#12), }, Ident { ident: "S", - span: $DIR/auxiliary/dollar-crate-external.rs:21:32: 21:33 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:32: 21:33 (#12), }, ], - span: $DIR/auxiliary/dollar-crate-external.rs:21:23: 21:34 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:23: 21:34 (#12), }, ], - span: $DIR/auxiliary/dollar-crate-external.rs:21:13: 21:35 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:13: 21:35 (#12), }, Punct { ch: ';', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:21:35: 21:36 (#11), + span: $DIR/auxiliary/dollar-crate-external.rs:21:35: 21:36 (#12), }, ] diff --git a/tests/ui/proc-macro/dollar-crate.stdout b/tests/ui/proc-macro/dollar-crate.stdout index 0278ef1ad0fc..f39d03540916 100644 --- a/tests/ui/proc-macro/dollar-crate.stdout +++ b/tests/ui/proc-macro/dollar-crate.stdout @@ -122,119 +122,119 @@ PRINT-BANG INPUT (DISPLAY): struct M($crate :: S); PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: $DIR/auxiliary/dollar-crate-external.rs:7:13: 7:19 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:13: 7:19 (#15), }, Ident { ident: "M", - span: $DIR/auxiliary/dollar-crate-external.rs:7:20: 7:21 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:20: 7:21 (#15), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: $DIR/auxiliary/dollar-crate-external.rs:7:22: 7:28 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:22: 7:28 (#15), }, Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:29 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:29 (#15), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:7:29: 7:30 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:29: 7:30 (#15), }, Ident { ident: "S", - span: $DIR/auxiliary/dollar-crate-external.rs:7:30: 7:31 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:30: 7:31 (#15), }, ], - span: $DIR/auxiliary/dollar-crate-external.rs:7:21: 7:32 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:21: 7:32 (#15), }, Punct { ch: ';', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:7:32: 7:33 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:7:32: 7:33 (#15), }, ] PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S); PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: $DIR/auxiliary/dollar-crate-external.rs:11:9: 11:15 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:9: 11:15 (#15), }, Ident { ident: "A", - span: $DIR/auxiliary/dollar-crate-external.rs:11:16: 11:17 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:16: 11:17 (#15), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: $DIR/auxiliary/dollar-crate-external.rs:11:18: 11:24 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:18: 11:24 (#15), }, Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:25 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:25 (#15), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:11:25: 11:26 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:25: 11:26 (#15), }, Ident { ident: "S", - span: $DIR/auxiliary/dollar-crate-external.rs:11:26: 11:27 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:26: 11:27 (#15), }, ], - span: $DIR/auxiliary/dollar-crate-external.rs:11:17: 11:28 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:17: 11:28 (#15), }, Punct { ch: ';', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:11:28: 11:29 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:11:28: 11:29 (#15), }, ] PRINT-DERIVE INPUT (DISPLAY): struct D($crate :: S); PRINT-DERIVE INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: $DIR/auxiliary/dollar-crate-external.rs:14:9: 14:15 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:9: 14:15 (#15), }, Ident { ident: "D", - span: $DIR/auxiliary/dollar-crate-external.rs:14:16: 14:17 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:16: 14:17 (#15), }, Group { delimiter: Parenthesis, stream: TokenStream [ Ident { ident: "$crate", - span: $DIR/auxiliary/dollar-crate-external.rs:14:18: 14:24 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:18: 14:24 (#15), }, Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:25 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:25 (#15), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:14:25: 14:26 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:25: 14:26 (#15), }, Ident { ident: "S", - span: $DIR/auxiliary/dollar-crate-external.rs:14:26: 14:27 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:26: 14:27 (#15), }, ], - span: $DIR/auxiliary/dollar-crate-external.rs:14:17: 14:28 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:17: 14:28 (#15), }, Punct { ch: ';', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:14:28: 14:29 (#14), + span: $DIR/auxiliary/dollar-crate-external.rs:14:28: 14:29 (#15), }, ] diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr index ed8ee4dc52cb..46cdbaccaeb6 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -13,7 +13,7 @@ error[E0425]: cannot find value `local_use` in this scope --> $DIR/gen-macro-rules-hygiene.rs:13:1 | LL | gen_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` + | ^^^^^^^^^^^^^^^^^^ ... LL | generated!(); | ------------ in this macro invocation @@ -24,12 +24,17 @@ help: an identifier with the same name exists, but is not accessible due to macr LL | let local_use = 1; | ^^^^^^^^^ = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - gen_macro_rules!(); +LL + local_def; + | error[E0425]: cannot find value `local_def` in this scope --> $DIR/gen-macro-rules-hygiene.rs:22:9 | LL | local_def; - | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` + | ^^^^^^^^^ | help: an identifier with the same name is defined here, but is not accessible due to macro hygiene --> $DIR/gen-macro-rules-hygiene.rs:13:1 @@ -40,6 +45,11 @@ LL | gen_macro_rules!(); LL | generated!(); | ------------ in this macro invocation = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - local_def; +LL + local_use; + | error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs index d420f2641daf..0c66b47b3941 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs @@ -12,12 +12,11 @@ struct PriorityQueueEntry { } #[derive(PartialOrd, AddImpl)] -//~^ ERROR can't compare `PriorityQueue` with `PriorityQueue` -//~| ERROR the trait bound `PriorityQueue: Eq` is not satisfied -//~| ERROR can't compare `T` with `T` -//~| ERROR no method named `cmp` found for struct `BinaryHeap>` -//~| ERROR no field `height` on type `&PriorityQueue` - +//~^ ERROR: the trait bound `PriorityQueue: Eq` is not satisfied +//~| ERROR: can't compare `T` with `T` +//~| ERROR: no method named `cmp` found for struct `BinaryHeap>` +//~| ERROR: no field `height` on type `&PriorityQueue` struct PriorityQueue(BinaryHeap>); -//~^ ERROR can't compare `BinaryHeap>` with `_` +//~^ ERROR: can't compare `PriorityQueue` with `PriorityQueue` +//~| ERROR: can't compare `BinaryHeap>` with `_` fn main() {} diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index b7aed4a8485a..b53ebe9f7271 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -1,11 +1,14 @@ error[E0277]: can't compare `PriorityQueue` with `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:8 | LL | #[derive(PartialOrd, AddImpl)] - | ^^^^^^^^^^ no implementation for `PriorityQueue == PriorityQueue` + | ---------- in this derive macro expansion +... +LL | struct PriorityQueue(BinaryHeap>); + | ^^^^^^^^^^^^^ no implementation for `PriorityQueue == PriorityQueue` | help: the trait `PartialEq` is not implemented for `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:1 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:1 | LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +22,7 @@ LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ unsatisfied trait bound | help: the trait `Eq` is not implemented for `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:1 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:1 | LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,15 +37,19 @@ LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ no implementation for `T < T` and `T > T` | note: required for `PriorityQueue` to implement `PartialOrd` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:8 | LL | #[derive(PartialOrd, AddImpl)] - | ^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ---------- in this derive macro expansion +... +LL | struct PriorityQueue(BinaryHeap>); + | ^^^^^^^^^^^^^ - type parameter would need to implement `PartialOrd` + = help: consider manually implementing `PartialOrd` to avoid undesired bounds note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: can't compare `BinaryHeap>` with `_` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:25 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:19:25 | LL | #[derive(PartialOrd, AddImpl)] | ---------- in this derive macro expansion diff --git a/tests/ui/proc-macro/lints_in_proc_macros.stderr b/tests/ui/proc-macro/lints_in_proc_macros.stderr index 016b236bda88..0b8df1b348d7 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.stderr +++ b/tests/ui/proc-macro/lints_in_proc_macros.stderr @@ -2,9 +2,14 @@ error[E0425]: cannot find value `foobar2` in this scope --> $DIR/lints_in_proc_macros.rs:10:5 | LL | bang_proc_macro2!(); - | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar` + | ^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `bang_proc_macro2` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - bang_proc_macro2!(); +LL + foobar; + | error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index 452598c372c1..b5db9922b31a 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -16,7 +16,6 @@ Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro // in the stdout #![no_std /* 0#0 */] -#[macro_use /* 0#1 */] extern crate core /* 0#1 */; #[prelude_import /* 0#1 */] use core /* 0#1 */::prelude /* 0#1 */::rust_2018 /* 0#1 */::*; diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index 97e3f3e3dea8..fd941f65b788 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -112,10 +112,13 @@ LL | test!(); = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:69:5 + --> $DIR/mixed-site-span.rs:67:9 | +LL | invoke_with_ident!{$crate call proc_macro_item} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root +LL | }} LL | test!(); - | ^^^^^^^ no `proc_macro_item` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -262,10 +265,13 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:110:5 + --> $DIR/mixed-site-span.rs:106:9 | +LL | invoke_with_ident!{$crate mixed TokenItem} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root +... LL | test!(); - | ^^^^^^^ no `TokenItem` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead @@ -417,10 +423,13 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:150:5 + --> $DIR/mixed-site-span.rs:145:9 | +LL | invoke_with_ident!{$crate mixed ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root +... LL | test!(); - | ^^^^^^^ no `ItemUse` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead @@ -447,10 +456,13 @@ LL + ItemUse as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:150:5 + --> $DIR/mixed-site-span.rs:148:9 | +LL | invoke_with_ident!{$crate call ItemUse} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root +LL | }} LL | test!(); - | ^^^^^^^ no `ItemUse` in the root + | ------- in this macro invocation | = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing this struct instead @@ -592,7 +604,7 @@ error[E0425]: cannot find value `local_use` in this scope --> $DIR/mixed-site-span.rs:23:9 | LL | proc_macro_rules!(); - | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` + | ^^^^^^^^^^^^^^^^^^^ | help: an identifier with the same name exists, but is not accessible due to macro hygiene --> $DIR/mixed-site-span.rs:22:13 @@ -600,12 +612,17 @@ help: an identifier with the same name exists, but is not accessible due to macr LL | let local_use = 1; | ^^^^^^^^^ = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - proc_macro_rules!(); +LL + local_def; + | error[E0425]: cannot find value `local_def` in this scope --> $DIR/mixed-site-span.rs:28:9 | LL | local_def; - | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` + | ^^^^^^^^^ | help: an identifier with the same name is defined here, but is not accessible due to macro hygiene --> $DIR/mixed-site-span.rs:23:9 @@ -613,6 +630,11 @@ help: an identifier with the same name is defined here, but is not accessible du LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a local variable with a similar name exists + | +LL - local_def; +LL + local_use; + | error: aborting due to 52 previous errors diff --git a/tests/ui/proc-macro/nested-empty-proc-macro.rs b/tests/ui/proc-macro/nested-empty-proc-macro.rs new file mode 100644 index 000000000000..d1c2c8a01412 --- /dev/null +++ b/tests/ui/proc-macro/nested-empty-proc-macro.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ proc-macro: nested-empty-proc-macro.rs + +// Regression test for issue #99173 +// Tests that nested proc-macro calls where the inner macro returns +// an empty TokenStream don't cause an ICE. + +extern crate nested_empty_proc_macro; + +fn main() { + nested_empty_proc_macro::outer_macro!(1 * 2 * 3 * 7); +} diff --git a/tests/ui/proc-macro/nested-macro-rules.stdout b/tests/ui/proc-macro/nested-macro-rules.stdout index 5b678554b9e0..89fb7b042218 100644 --- a/tests/ui/proc-macro/nested-macro-rules.stdout +++ b/tests/ui/proc-macro/nested-macro-rules.stdout @@ -2,45 +2,45 @@ PRINT-BANG INPUT (DISPLAY): FirstStruct PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "FirstStruct", - span: $DIR/auxiliary/nested-macro-rules.rs:16:14: 16:25 (#6), + span: $DIR/auxiliary/nested-macro-rules.rs:16:14: 16:25 (#7), }, ] PRINT-ATTR INPUT (DISPLAY): struct FirstAttrStruct {} PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#5), + span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#6), }, Ident { ident: "FirstAttrStruct", - span: $DIR/auxiliary/nested-macro-rules.rs:16:27: 16:42 (#6), + span: $DIR/auxiliary/nested-macro-rules.rs:16:27: 16:42 (#7), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#5), + span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#6), }, ] PRINT-BANG INPUT (DISPLAY): SecondStruct PRINT-BANG INPUT (DEBUG): TokenStream [ Ident { ident: "SecondStruct", - span: $DIR/nested-macro-rules.rs:23:38: 23:50 (#15), + span: $DIR/nested-macro-rules.rs:23:38: 23:50 (#16), }, ] PRINT-ATTR INPUT (DISPLAY): struct SecondAttrStruct {} PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { ident: "struct", - span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#14), + span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#15), }, Ident { ident: "SecondAttrStruct", - span: $DIR/nested-macro-rules.rs:23:52: 23:68 (#15), + span: $DIR/nested-macro-rules.rs:23:52: 23:68 (#16), }, Group { delimiter: Brace, stream: TokenStream [], - span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#14), + span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#15), }, ] diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index e10a5199f179..e45abab03b4c 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -36,7 +36,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ #![feature /* 0#0 */(decl_macro)] #![no_std /* 0#0 */] -#[macro_use /* 0#1 */] extern crate core /* 0#2 */; #[prelude_import /* 0#1 */] use ::core /* 0#1 */::prelude /* 0#1 */::rust_2015 /* 0#1 */::*; diff --git a/tests/ui/proc-macro/parent-source-spans.stderr b/tests/ui/proc-macro/parent-source-spans.stderr index 28a70eea873d..87b8dae74f48 100644 --- a/tests/ui/proc-macro/parent-source-spans.stderr +++ b/tests/ui/proc-macro/parent-source-spans.stderr @@ -140,7 +140,7 @@ error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | one!("hello", "world"); | ---------------------- in this macro invocation @@ -150,12 +150,17 @@ LL | one!("hello", "world"); = note: similarly named tuple variant `Ok` defined here | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a tuple variant with a similar name exists + | +LL - parent_source_spans!($($tokens)*); +LL + Ok; + | error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | two!("yay", "rust"); | ------------------- in this macro invocation @@ -165,12 +170,17 @@ LL | two!("yay", "rust"); = note: similarly named tuple variant `Ok` defined here | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `two` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a tuple variant with a similar name exists + | +LL - parent_source_spans!($($tokens)*); +LL + Ok; + | error[E0425]: cannot find value `ok` in this scope --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... LL | three!("hip", "hop"); | -------------------- in this macro invocation @@ -180,6 +190,11 @@ LL | three!("hip", "hop"); = note: similarly named tuple variant `Ok` defined here | = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `three` (in Nightly builds, run with -Z macro-backtrace for more info) +help: a tuple variant with a similar name exists + | +LL - parent_source_spans!($($tokens)*); +LL + Ok; + | error: aborting due to 21 previous errors diff --git a/tests/ui/proc-macro/pretty-print-hack-hide.rs b/tests/ui/proc-macro/pretty-print-hack-hide.rs deleted file mode 100644 index fd98f16a780e..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack-hide.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ proc-macro: test-macros.rs -//@ compile-flags: -Z span-debug -//@ check-pass - -#![no_std] // Don't load unnecessary hygiene information from std -extern crate std; - -#[macro_use] extern crate test_macros; - -include!("pretty-print-hack/rental-0.5.6/src/lib.rs"); - -fn main() {} diff --git a/tests/ui/proc-macro/pretty-print-hack-hide.stdout b/tests/ui/proc-macro/pretty-print-hack-hide.stdout deleted file mode 100644 index ea796bb26976..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack-hide.stdout +++ /dev/null @@ -1,21 +0,0 @@ -PRINT-DERIVE INPUT (DISPLAY): enum ProceduralMasqueradeDummyType { Input } -PRINT-DERIVE INPUT (DEBUG): TokenStream [ - Ident { - ident: "enum", - span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:1: 4:5 (#0), - }, - Ident { - ident: "ProceduralMasqueradeDummyType", - span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:6: 4:35 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [ - Ident { - ident: "Input", - span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:13:5: 13:10 (#0), - }, - ], - span: $DIR/pretty-print-hack/rental-0.5.6/src/lib.rs:4:36: 14:2 (#0), - }, -] diff --git a/tests/ui/proc-macro/pretty-print-hack-show.local.stderr b/tests/ui/proc-macro/pretty-print-hack-show.local.stderr deleted file mode 100644 index 889cd0c90ebb..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack-show.local.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: using an old version of `rental` - | - = note: older versions of the `rental` crate no longer compile; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives - -error: aborting due to 1 previous error - diff --git a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr b/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr deleted file mode 100644 index 889cd0c90ebb..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack-show.remapped.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: using an old version of `rental` - | - = note: older versions of the `rental` crate no longer compile; please update to `rental` v0.5.6, or switch to one of the `rental` alternatives - -error: aborting due to 1 previous error - diff --git a/tests/ui/proc-macro/pretty-print-hack-show.rs b/tests/ui/proc-macro/pretty-print-hack-show.rs deleted file mode 100644 index 08e26c811427..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack-show.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ proc-macro: test-macros.rs -//@ compile-flags: -Z span-debug -//@ revisions: local remapped -//@ [remapped] remap-src-base - -#![no_std] // Don't load unnecessary hygiene information from std -extern crate std; - -#[macro_use] extern crate test_macros; - -mod first { - include!("pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs"); -} - -mod second { - include!("pretty-print-hack/rental-0.5.5/src/lib.rs"); -} - -fn main() {} - -//~? ERROR using an old version of `rental` diff --git a/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs deleted file mode 100644 index a27176a38e22..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ ignore-auxiliary (used by `../../../pretty-print-hack-show.rs`) - -#[derive(Print)] -enum ProceduralMasqueradeDummyType { -//~^ ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously - Input -} diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs deleted file mode 100644 index a27176a38e22..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ ignore-auxiliary (used by `../../../pretty-print-hack-show.rs`) - -#[derive(Print)] -enum ProceduralMasqueradeDummyType { -//~^ ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously - Input -} diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs deleted file mode 100644 index 765ee4be656e..000000000000 --- a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ ignore-auxiliary (used by `../../../pretty-print-hack/hide.rs`) - -#[derive(Print)] -enum ProceduralMasqueradeDummyType { -//~^ ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously -//~| ERROR using -//~| WARN this was previously - Input -} diff --git a/tests/ui/proc-macro/proc-macro-abi.stderr b/tests/ui/proc-macro/proc-macro-abi.stderr index ccc72e5187ed..ccefdbfa3a86 100644 --- a/tests/ui/proc-macro/proc-macro-abi.stderr +++ b/tests/ui/proc-macro/proc-macro-abi.stderr @@ -4,8 +4,8 @@ error: function-like proc macro has incorrect signature LL | pub extern "C" fn abi(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `extern "C" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `extern "C" fn(TokenStream) -> TokenStream` error: function-like proc macro has incorrect signature --> $DIR/proc-macro-abi.rs:17:1 @@ -13,8 +13,8 @@ error: function-like proc macro has incorrect signature LL | pub extern "system" fn abi2(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "system" fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `extern "system" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `extern "system" fn(TokenStream) -> TokenStream` error: function-like proc macro has incorrect signature --> $DIR/proc-macro-abi.rs:23:1 @@ -22,8 +22,8 @@ error: function-like proc macro has incorrect signature LL | pub extern fn abi3(a: TokenStream) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected "Rust" fn, found "C" fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `extern "C" fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `extern "C" fn(TokenStream) -> TokenStream` error: aborting due to 3 previous errors diff --git a/tests/ui/proc-macro/quote/debug.stdout b/tests/ui/proc-macro/quote/debug.stdout index 77c52f02a33c..896c809fedab 100644 --- a/tests/ui/proc-macro/quote/debug.stdout +++ b/tests/ui/proc-macro/quote/debug.stdout @@ -12,7 +12,6 @@ #![feature(proc_macro_quote)] #![crate_type = "proc-macro"] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr index 0bcea9b85f47..86a00713a456 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated-dup.stderr @@ -5,7 +5,7 @@ LL | quote!($($nonrep $nonrep)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | here the type of `has_iter` is inferred to be `proc_macro::ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr index d945ab41a12e..325e50f9796a 100644 --- a/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr +++ b/tests/ui/proc-macro/quote/does-not-have-iter-interpolated.stderr @@ -5,7 +5,7 @@ LL | quote!($($nonrep)*); | ^^^^^^^^^^^^^^^^^^^ | | | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` + | here the type of `has_iter` is inferred to be `proc_macro::ThereIsNoIteratorInRepetition` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/not-quotable.stderr b/tests/ui/proc-macro/quote/not-quotable.stderr index 62a02638e548..4177d9c672b5 100644 --- a/tests/ui/proc-macro/quote/not-quotable.stderr +++ b/tests/ui/proc-macro/quote/not-quotable.stderr @@ -4,18 +4,18 @@ error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied LL | let _ = quote! { $ip }; | ^^^^^^^^^^^^^^ | | - | the trait `ToTokens` is not implemented for `Ipv4Addr` + | the nightly-only, unstable trait `ToTokens` is not implemented for `Ipv4Addr` | required by a bound introduced by this call | = help: the following other types implement trait `ToTokens`: &T &mut T Box + CStr CString Cow<'_, T> Option Rc - bool and 24 others error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/not-repeatable.rs b/tests/ui/proc-macro/quote/not-repeatable.rs index 373f0e74dbda..55ba1669f1b1 100644 --- a/tests/ui/proc-macro/quote/not-repeatable.rs +++ b/tests/ui/proc-macro/quote/not-repeatable.rs @@ -10,5 +10,4 @@ fn main() { let ip = Ipv4Addr; let _ = quote! { $($ip)* }; //~^ ERROR the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied - //~| ERROR type annotations needed } diff --git a/tests/ui/proc-macro/quote/not-repeatable.stderr b/tests/ui/proc-macro/quote/not-repeatable.stderr index 5943111efd58..611da37f3a1f 100644 --- a/tests/ui/proc-macro/quote/not-repeatable.stderr +++ b/tests/ui/proc-macro/quote/not-repeatable.stderr @@ -2,7 +2,7 @@ error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its --> $DIR/not-repeatable.rs:11:13 | LL | struct Ipv4Addr; - | --------------- method `quote_into_iter` not found for this struct because it doesn't satisfy `Ipv4Addr: Iterator`, `Ipv4Addr: ToTokens`, `Ipv4Addr: proc_macro::ext::RepIteratorExt` or `Ipv4Addr: proc_macro::ext::RepToTokensExt` + | --------------- method `quote_into_iter` not found for this struct because `Ipv4Addr` doesn't implement `Iterator` or `ToTokens` ... LL | let _ = quote! { $($ip)* }; | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds @@ -20,13 +20,6 @@ note: the traits `Iterator` and `ToTokens` must be implemented --> $SRC_DIR/proc_macro/src/to_tokens.rs:LL:COL --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL -error[E0282]: type annotations needed - --> $DIR/not-repeatable.rs:11:25 - | -LL | let _ = quote! { $($ip)* }; - | ^^ cannot infer type +error: aborting due to 1 previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0282, E0599. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/proc-macro/resolve-error.stderr b/tests/ui/proc-macro/resolve-error.stderr index 45b71a3e7b3a..7efb751caaec 100644 --- a/tests/ui/proc-macro/resolve-error.stderr +++ b/tests/ui/proc-macro/resolve-error.stderr @@ -2,12 +2,18 @@ error: cannot find macro `bang_proc_macrp` in this scope --> $DIR/resolve-error.rs:60:5 | LL | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro` + | ^^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/test-macros.rs:10:1 | LL | pub fn empty(_: TokenStream) -> TokenStream { | ------------------------------------------- similarly named macro `bang_proc_macro` defined here + | +help: a macro with a similar name exists + | +LL - bang_proc_macrp!(); +LL + bang_proc_macro!(); + | error: cannot find macro `Dlona` in this scope --> $DIR/resolve-error.rs:57:5 @@ -22,7 +28,13 @@ LL | macro_rules! attr_proc_mac { | -------------------------- similarly named macro `attr_proc_mac` defined here ... LL | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac` + | ^^^^^^^^^^^^^^^ + | +help: a macro with a similar name exists + | +LL - attr_proc_macra!(); +LL + attr_proc_mac!(); + | error: cannot find macro `FooWithLongNama` in this scope --> $DIR/resolve-error.rs:51:5 @@ -31,7 +43,13 @@ LL | macro_rules! FooWithLongNam { | --------------------------- similarly named macro `FooWithLongNam` defined here ... LL | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam` + | ^^^^^^^^^^^^^^^ + | +help: a macro with a similar name exists + | +LL - FooWithLongNama!(); +LL + FooWithLongNam!(); + | error: cannot find derive macro `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:45:10 @@ -51,18 +69,24 @@ error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | ^^^^^ | ::: $DIR/auxiliary/derive-clona.rs:6:1 | LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here + | +help: a derive macro with a similar name exists + | +LL - #[derive(Dlona)] +LL + #[derive(Clona)] + | error: cannot find derive macro `Dlona` in this scope --> $DIR/resolve-error.rs:40:10 | LL | #[derive(Dlona)] - | ^^^^^ help: a derive macro with a similar name exists: `Clona` + | ^^^^^ | ::: $DIR/auxiliary/derive-clona.rs:6:1 | @@ -70,28 +94,43 @@ LL | pub fn derive_clonea(input: TokenStream) -> TokenStream { | ------------------------------------------------------- similarly named derive macro `Clona` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(Dlona)] +LL + #[derive(Clona)] + | error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] - | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | ^^^^^ | --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here +help: a derive macro with a similar name exists + | +LL - #[derive(Dlone)] +LL + #[derive(Clone)] + | error: cannot find derive macro `Dlone` in this scope --> $DIR/resolve-error.rs:35:10 | LL | #[derive(Dlone)] - | ^^^^^ help: a derive macro with a similar name exists: `Clone` + | ^^^^^ | --> $SRC_DIR/core/src/clone.rs:LL:COL | = note: similarly named derive macro `Clone` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(Dlone)] +LL + #[derive(Clone)] + | error: cannot find attribute `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:32:3 @@ -103,29 +142,41 @@ error: cannot find attribute `attr_proc_macra` in this scope --> $DIR/resolve-error.rs:28:3 | LL | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro` + | ^^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/test-macros.rs:15:1 | LL | pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream { | ---------------------------------------------------------------- similarly named attribute macro `attr_proc_macro` defined here + | +help: an attribute macro with a similar name exists + | +LL - #[attr_proc_macra] +LL + #[attr_proc_macro] + | error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | ^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/derive-foo.rs:6:1 | LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here + | +help: a derive macro with a similar name exists + | +LL - #[derive(FooWithLongNan)] +LL + #[derive(FooWithLongName)] + | error: cannot find derive macro `FooWithLongNan` in this scope --> $DIR/resolve-error.rs:22:10 | LL | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName` + | ^^^^^^^^^^^^^^ | ::: $DIR/auxiliary/derive-foo.rs:6:1 | @@ -133,6 +184,11 @@ LL | pub fn derive_foo(input: TokenStream) -> TokenStream { | ---------------------------------------------------- similarly named derive macro `FooWithLongName` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(FooWithLongNan)] +LL + #[derive(FooWithLongName)] + | error: aborting due to 14 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr index ce832eaa5c7a..9dfb081a10e6 100644 --- a/tests/ui/proc-macro/signature-proc-macro-attribute.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-attribute.stderr @@ -4,8 +4,8 @@ error: attribute proc macro has incorrect signature LL | pub fn bad_input(input: String) -> TokenStream { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(String) -> TokenStream` error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:16:1 @@ -13,8 +13,8 @@ error: attribute proc macro has incorrect signature LL | pub fn bad_output(input: TokenStream) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream) -> std::string::String` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(TokenStream) -> String` error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:22:1 @@ -22,8 +22,8 @@ error: attribute proc macro has incorrect signature LL | pub fn bad_everything(input: String) -> String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> std::string::String` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(String) -> String` error: attribute proc macro has incorrect signature --> $DIR/signature-proc-macro-attribute.rs:28:52 @@ -31,8 +31,8 @@ error: attribute proc macro has incorrect signature LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream, proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream, TokenStream) -> TokenStream` + found signature `fn(TokenStream, TokenStream, String) -> TokenStream` error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro-derive.stderr b/tests/ui/proc-macro/signature-proc-macro-derive.stderr index 03c6abad17d9..3539ae7c2e17 100644 --- a/tests/ui/proc-macro/signature-proc-macro-derive.stderr +++ b/tests/ui/proc-macro/signature-proc-macro-derive.stderr @@ -2,28 +2,28 @@ error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> TokenStream` error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream) -> String` error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> String` error: derive proc macro has incorrect signature --> $DIR/signature-proc-macro-derive.rs:28:36 @@ -31,8 +31,8 @@ error: derive proc macro has incorrect signature LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream, TokenStream, String) -> TokenStream` error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature-proc-macro.stderr b/tests/ui/proc-macro/signature-proc-macro.stderr index dd2cb0570daa..1959d8c6d615 100644 --- a/tests/ui/proc-macro/signature-proc-macro.stderr +++ b/tests/ui/proc-macro/signature-proc-macro.stderr @@ -2,28 +2,28 @@ error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:10:25 | LL | pub fn bad_input(input: String) -> TokenStream { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> TokenStream` error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:16:42 | LL | pub fn bad_output(input: TokenStream) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream) -> String` error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:22:30 | LL | pub fn bad_everything(input: String) -> String { - | ^^^^^^ expected `proc_macro::TokenStream`, found `std::string::String` + | ^^^^^^ expected `TokenStream`, found `String` | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(std::string::String) -> std::string::String` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(String) -> String` error: function-like proc macro has incorrect signature --> $DIR/signature-proc-macro.rs:28:36 @@ -31,8 +31,8 @@ error: function-like proc macro has incorrect signature LL | pub fn too_many(a: TokenStream, b: TokenStream, c: String) -> TokenStream { | ^^^^^^^^^^^ incorrect number of function parameters | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` - found signature `fn(proc_macro::TokenStream, proc_macro::TokenStream, std::string::String) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` + found signature `fn(TokenStream, TokenStream, String) -> TokenStream` error: aborting due to 4 previous errors diff --git a/tests/ui/proc-macro/signature.stderr b/tests/ui/proc-macro/signature.stderr index fd679442b6af..2c1973eb6e6d 100644 --- a/tests/ui/proc-macro/signature.stderr +++ b/tests/ui/proc-macro/signature.stderr @@ -4,7 +4,7 @@ error: derive proc macro has incorrect signature LL | pub unsafe extern "C" fn foo(a: i32, b: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected safe fn, found unsafe fn | - = note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + = note: expected signature `fn(TokenStream) -> TokenStream` found signature `unsafe extern "C" fn(i32, u32) -> u32` error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/sub-error-diag.rs b/tests/ui/proc-macro/sub-error-diag.rs new file mode 100644 index 000000000000..11218fc66a37 --- /dev/null +++ b/tests/ui/proc-macro/sub-error-diag.rs @@ -0,0 +1,13 @@ +//@ proc-macro: sub-error-diag.rs + +// Regression test for issue https://github.com/rust-lang/rust/issues/145305, which used to cause an ICE +// due to an assertion in the compiler that errors could not be subdiagnostics. + +extern crate sub_error_diag; + +//~? ERROR: Parent message +#[sub_error_diag::proc_emit_err] +//~^ ERROR: Child message +fn foo() {} + +fn main() {} diff --git a/tests/ui/proc-macro/sub-error-diag.stderr b/tests/ui/proc-macro/sub-error-diag.stderr new file mode 100644 index 000000000000..b5d83e4d52ae --- /dev/null +++ b/tests/ui/proc-macro/sub-error-diag.stderr @@ -0,0 +1,11 @@ +error: Parent message + | +error: Child message + --> $DIR/sub-error-diag.rs:9:1 + | +LL | #[sub_error_diag::proc_emit_err] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `sub_error_diag::proc_emit_err` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index e87e20773702..51521f1dcf42 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -11,6 +11,7 @@ //@ ignore-visionos no 'head' //@ ignore-backends: gcc //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ compile-flags: -Zon-broken-pipe=error // Test what the error message looks like when `println!()` panics because of diff --git a/tests/ui/query-system/query-cycle-printing-issue-151226.rs b/tests/ui/query-system/query-cycle-printing-issue-151226.rs new file mode 100644 index 000000000000..9d0a20737c9f --- /dev/null +++ b/tests/ui/query-system/query-cycle-printing-issue-151226.rs @@ -0,0 +1,8 @@ +struct A(std::sync::OnceLock); +//~^ ERROR recursive type `A` has infinite size +//~| ERROR cycle detected when computing layout of `A<()>` + +static B: A<()> = todo!(); +//~^ ERROR cycle occurred during layout computation + +fn main() {} diff --git a/tests/ui/query-system/query-cycle-printing-issue-151226.stderr b/tests/ui/query-system/query-cycle-printing-issue-151226.stderr new file mode 100644 index 000000000000..7e574b5911a3 --- /dev/null +++ b/tests/ui/query-system/query-cycle-printing-issue-151226.stderr @@ -0,0 +1,36 @@ +error[E0072]: recursive type `A` has infinite size + --> $DIR/query-cycle-printing-issue-151226.rs:1:1 + | +LL | struct A(std::sync::OnceLock); + | ^^^^^^^^^^^ ------------------------- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | struct A(Box>); + | ++++ + + +error[E0391]: cycle detected when computing layout of `A<()>` + | + = note: ...which requires computing layout of `std::sync::once_lock::OnceLock>`... + = note: ...which requires computing layout of `core::cell::UnsafeCell>>`... + = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit>`... + = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop>`... + = note: ...which requires computing layout of `core::mem::maybe_dangling::MaybeDangling>`... + = note: ...which again requires computing layout of `A<()>`, completing the cycle +note: cycle used when checking that `B` is well-formed + --> $DIR/query-cycle-printing-issue-151226.rs:5:1 + | +LL | static B: A<()> = todo!(); + | ^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0080]: a cycle occurred during layout computation + --> $DIR/query-cycle-printing-issue-151226.rs:5:1 + | +LL | static B: A<()> = todo!(); + | ^^^^^^^^^^^^^^^ evaluation of `B` failed here + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0072, E0080, E0391. +For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/query-system/query-cycle-printing-issue-151358.rs b/tests/ui/query-system/query-cycle-printing-issue-151358.rs new file mode 100644 index 000000000000..04d8664420be --- /dev/null +++ b/tests/ui/query-system/query-cycle-printing-issue-151358.rs @@ -0,0 +1,7 @@ +//~ ERROR: cycle detected when looking up span for `Default` +trait Default {} +use std::num::NonZero; +fn main() { + NonZero(); + format!("{}", 0); +} diff --git a/tests/ui/query-system/query-cycle-printing-issue-151358.stderr b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr new file mode 100644 index 000000000000..9c1d7b1de33a --- /dev/null +++ b/tests/ui/query-system/query-cycle-printing-issue-151358.stderr @@ -0,0 +1,9 @@ +error[E0391]: cycle detected when looking up span for `Default` + | + = note: ...which immediately requires looking up span for `Default` again + = note: cycle used when perform lints prior to AST lowering + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/range/new_range_stability.rs b/tests/ui/range/new_range_stability.rs new file mode 100644 index 000000000000..7200e1ac95d2 --- /dev/null +++ b/tests/ui/range/new_range_stability.rs @@ -0,0 +1,28 @@ +// Stable + +use std::range::{RangeInclusive, RangeInclusiveIter}; + +fn range_inclusive(mut r: RangeInclusive) { + r.start; + r.last; + r.contains(&5); + r.is_empty(); + r.iter(); + + let mut i = r.into_iter(); + i.next(); + i.remainder(); +} + +// Unstable module + +use std::range::legacy; //~ ERROR unstable + +// Unstable types + +use std::range::RangeFrom; //~ ERROR unstable +use std::range::Range; //~ ERROR unstable +use std::range::RangeFromIter; //~ ERROR unstable +use std::range::RangeIter; //~ ERROR unstable + +fn main() {} diff --git a/tests/ui/range/new_range_stability.stderr b/tests/ui/range/new_range_stability.stderr new file mode 100644 index 000000000000..871d691794ff --- /dev/null +++ b/tests/ui/range/new_range_stability.stderr @@ -0,0 +1,53 @@ +error[E0658]: use of unstable library feature `new_range_api` + --> $DIR/new_range_stability.rs:19:5 + | +LL | use std::range::legacy; + | ^^^^^^^^^^^^^^^^^^ + | + = note: see issue #125687 for more information + = help: add `#![feature(new_range_api)]` 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[E0658]: use of unstable library feature `new_range_api` + --> $DIR/new_range_stability.rs:23:5 + | +LL | use std::range::RangeFrom; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #125687 for more information + = help: add `#![feature(new_range_api)]` 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[E0658]: use of unstable library feature `new_range_api` + --> $DIR/new_range_stability.rs:24:5 + | +LL | use std::range::Range; + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #125687 for more information + = help: add `#![feature(new_range_api)]` 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[E0658]: use of unstable library feature `new_range_api` + --> $DIR/new_range_stability.rs:25:5 + | +LL | use std::range::RangeFromIter; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #125687 for more information + = help: add `#![feature(new_range_api)]` 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[E0658]: use of unstable library feature `new_range_api` + --> $DIR/new_range_stability.rs:26:5 + | +LL | use std::range::RangeIter; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #125687 for more information + = help: add `#![feature(new_range_api)]` 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: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/range/range-1.rs b/tests/ui/range/range-1.rs index 192426fe228f..8fbfae55b8a6 100644 --- a/tests/ui/range/range-1.rs +++ b/tests/ui/range/range-1.rs @@ -7,7 +7,7 @@ pub fn main() { // Bool => does not implement iterator. for i in false..true {} - //~^ ERROR `bool: Step` is not satisfied + //~^ ERROR `std::ops::Range` is not an iterator // Unsized type. let arr: &[_] = &[1, 2, 3]; diff --git a/tests/ui/range/range-1.stderr b/tests/ui/range/range-1.stderr index 8878ba143097..d7d0f87ac991 100644 --- a/tests/ui/range/range-1.stderr +++ b/tests/ui/range/range-1.stderr @@ -4,12 +4,14 @@ error[E0308]: mismatched types LL | let _ = 0u32..10i32; | ^^^^^ expected `u32`, found `i32` -error[E0277]: the trait bound `bool: Step` is not satisfied +error[E0277]: `std::ops::Range` is not an iterator --> $DIR/range-1.rs:9:14 | LL | for i in false..true {} - | ^^^^^^^^^^^ the trait `Step` is not implemented for `bool` + | ^^^^^^^^^^^ `Range` is not an iterator | + = help: the nightly-only, unstable trait `Step` is not implemented for `bool` + = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait = note: required for `std::ops::Range` to implement `Iterator` = note: required for `std::ops::Range` to implement `IntoIterator` diff --git a/tests/ui/range/range-negative-literal-unsigned-type.rs b/tests/ui/range/range-negative-literal-unsigned-type.rs new file mode 100644 index 000000000000..b6152abb340e --- /dev/null +++ b/tests/ui/range/range-negative-literal-unsigned-type.rs @@ -0,0 +1,21 @@ +// Regression tests for: https://github.com/rust-lang/rust/issues/136514 + +#![allow(unreachable_patterns)] +fn main() { + match 0u8 { + -1..=2 => {} + //~^ ERROR the trait bound `u8: Neg` is not satisfied + -0..=0 => {} + //~^ ERROR the trait bound `u8: Neg` is not satisfied + -256..=2 => {} + //~^ ERROR the trait bound `u8: Neg` is not satisfied + -255..=2 => {} + //~^ ERROR the trait bound `u8: Neg` is not satisfied + 0..=-1 => {} + //~^ ERROR the trait bound `u8: Neg` is not satisfied + -2..=-1 => {} + //~^ ERROR the trait bound `u8: Neg` is not satisfied + //~| ERROR the trait bound `u8: Neg` is not satisfied + _ => {} + } +} diff --git a/tests/ui/range/range-negative-literal-unsigned-type.stderr b/tests/ui/range/range-negative-literal-unsigned-type.stderr new file mode 100644 index 000000000000..7ca14c3d7790 --- /dev/null +++ b/tests/ui/range/range-negative-literal-unsigned-type.stderr @@ -0,0 +1,122 @@ +error[E0277]: the trait bound `u8: Neg` is not satisfied + --> $DIR/range-negative-literal-unsigned-type.rs:6:9 + | +LL | -1..=2 => {} + | ^^ the trait `Neg` is not implemented for `u8` + | + = help: the following other types implement trait `Neg`: + &f128 + &f16 + &f32 + &f64 + &i128 + &i16 + &i32 + &i64 + and 12 others + +error[E0277]: the trait bound `u8: Neg` is not satisfied + --> $DIR/range-negative-literal-unsigned-type.rs:8:9 + | +LL | -0..=0 => {} + | ^^ the trait `Neg` is not implemented for `u8` + | + = help: the following other types implement trait `Neg`: + &f128 + &f16 + &f32 + &f64 + &i128 + &i16 + &i32 + &i64 + and 12 others + +error[E0277]: the trait bound `u8: Neg` is not satisfied + --> $DIR/range-negative-literal-unsigned-type.rs:10:9 + | +LL | -256..=2 => {} + | ^^^^ the trait `Neg` is not implemented for `u8` + | + = help: the following other types implement trait `Neg`: + &f128 + &f16 + &f32 + &f64 + &i128 + &i16 + &i32 + &i64 + and 12 others + +error[E0277]: the trait bound `u8: Neg` is not satisfied + --> $DIR/range-negative-literal-unsigned-type.rs:12:9 + | +LL | -255..=2 => {} + | ^^^^ the trait `Neg` is not implemented for `u8` + | + = help: the following other types implement trait `Neg`: + &f128 + &f16 + &f32 + &f64 + &i128 + &i16 + &i32 + &i64 + and 12 others + +error[E0277]: the trait bound `u8: Neg` is not satisfied + --> $DIR/range-negative-literal-unsigned-type.rs:14:13 + | +LL | 0..=-1 => {} + | ^^ the trait `Neg` is not implemented for `u8` + | + = help: the following other types implement trait `Neg`: + &f128 + &f16 + &f32 + &f64 + &i128 + &i16 + &i32 + &i64 + and 12 others + +error[E0277]: the trait bound `u8: Neg` is not satisfied + --> $DIR/range-negative-literal-unsigned-type.rs:16:9 + | +LL | -2..=-1 => {} + | ^^ the trait `Neg` is not implemented for `u8` + | + = help: the following other types implement trait `Neg`: + &f128 + &f16 + &f32 + &f64 + &i128 + &i16 + &i32 + &i64 + and 12 others + +error[E0277]: the trait bound `u8: Neg` is not satisfied + --> $DIR/range-negative-literal-unsigned-type.rs:16:14 + | +LL | -2..=-1 => {} + | ^^ the trait `Neg` is not implemented for `u8` + | + = help: the following other types implement trait `Neg`: + &f128 + &f16 + &f32 + &f64 + &i128 + &i16 + &i32 + &i64 + and 12 others + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/range/range_traits-2.rs b/tests/ui/range/range_traits-2.rs index 234d7a64dc8b..7dd91243082c 100644 --- a/tests/ui/range/range_traits-2.rs +++ b/tests/ui/range/range_traits-2.rs @@ -1,6 +1,6 @@ use std::ops::*; -#[derive(Copy, Clone)] //~ ERROR Copy -struct R(Range); +#[derive(Copy, Clone)] +struct R(Range); //~ ERROR Copy fn main() {} diff --git a/tests/ui/range/range_traits-2.stderr b/tests/ui/range/range_traits-2.stderr index 2001c85c4348..f38539cc648c 100644 --- a/tests/ui/range/range_traits-2.stderr +++ b/tests/ui/range/range_traits-2.stderr @@ -1,10 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/range_traits-2.rs:3:10 + --> $DIR/range_traits-2.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | struct R(Range); - | ------------ this field does not implement `Copy` + | ^ ------------ this field does not implement `Copy` error: aborting due to 1 previous error diff --git a/tests/ui/range/range_traits-3.rs b/tests/ui/range/range_traits-3.rs index 2d597cce5ad5..79ba1842f62f 100644 --- a/tests/ui/range/range_traits-3.rs +++ b/tests/ui/range/range_traits-3.rs @@ -1,6 +1,6 @@ use std::ops::*; -#[derive(Copy, Clone)] //~ ERROR Copy -struct R(RangeFrom); +#[derive(Copy, Clone)] +struct R(RangeFrom); //~ ERROR Copy fn main() {} diff --git a/tests/ui/range/range_traits-3.stderr b/tests/ui/range/range_traits-3.stderr index 71210379c79c..1f3768ad8d84 100644 --- a/tests/ui/range/range_traits-3.stderr +++ b/tests/ui/range/range_traits-3.stderr @@ -1,10 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/range_traits-3.rs:3:10 + --> $DIR/range_traits-3.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | struct R(RangeFrom); - | ---------------- this field does not implement `Copy` + | ^ ---------------- this field does not implement `Copy` error: aborting due to 1 previous error diff --git a/tests/ui/range/range_traits-6.rs b/tests/ui/range/range_traits-6.rs index bce106bbfe79..72c6cecc88d6 100644 --- a/tests/ui/range/range_traits-6.rs +++ b/tests/ui/range/range_traits-6.rs @@ -1,6 +1,6 @@ use std::ops::*; -#[derive(Copy, Clone)] //~ ERROR Copy -struct R(RangeInclusive); +#[derive(Copy, Clone)] +struct R(RangeInclusive); //~ ERROR Copy fn main() {} diff --git a/tests/ui/range/range_traits-6.stderr b/tests/ui/range/range_traits-6.stderr index a58022ef7e4f..53fe2fed0a61 100644 --- a/tests/ui/range/range_traits-6.stderr +++ b/tests/ui/range/range_traits-6.stderr @@ -1,10 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/range_traits-6.rs:3:10 + --> $DIR/range_traits-6.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | struct R(RangeInclusive); - | --------------------- this field does not implement `Copy` + | ^ --------------------- this field does not implement `Copy` error: aborting due to 1 previous error diff --git a/tests/ui/reachable/expr_again.stderr b/tests/ui/reachable/expr_again.stderr index 5dec512ba5de..2e00fdc7b431 100644 --- a/tests/ui/reachable/expr_again.stderr +++ b/tests/ui/reachable/expr_again.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/reachable/expr_block.stderr b/tests/ui/reachable/expr_block.stderr index d5f248a24910..aaca4053f27f 100644 --- a/tests/ui/reachable/expr_block.stderr +++ b/tests/ui/reachable/expr_block.stderr @@ -19,8 +19,6 @@ LL | return; | ------ any code following this expression is unreachable LL | println!("foo"); | ^^^^^^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/reachable/expr_if.stderr b/tests/ui/reachable/expr_if.stderr index ebd0b5a3ebef..662692ed6f28 100644 --- a/tests/ui/reachable/expr_if.stderr +++ b/tests/ui/reachable/expr_if.stderr @@ -23,8 +23,6 @@ LL | return; ... LL | println!("But I am."); | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/reachable/expr_loop.stderr b/tests/ui/reachable/expr_loop.stderr index 918584686050..83b8d024c4fc 100644 --- a/tests/ui/reachable/expr_loop.stderr +++ b/tests/ui/reachable/expr_loop.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:21:5 @@ -20,8 +19,6 @@ LL | loop { return; } | ------ any code following this expression is unreachable LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_loop.rs:32:5 @@ -30,8 +27,6 @@ LL | loop { 'middle: loop { loop { break 'middle; } } } | -------------------------------------------------- any code following this expression is unreachable LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/reachable/expr_match.stderr b/tests/ui/reachable/expr_match.stderr index ae202a6e0c34..92f6d6758d99 100644 --- a/tests/ui/reachable/expr_match.stderr +++ b/tests/ui/reachable/expr_match.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/expr_match.rs:19:5 @@ -20,8 +19,6 @@ LL | match () { () if false => return, () => return } | ------------------------------------------------ any code following this `match` expression is unreachable, as all arms diverge LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable expression --> $DIR/expr_match.rs:25:25 @@ -42,8 +39,6 @@ LL | | } | |_____- any code following this `match` expression is unreachable, as all arms diverge LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/reachable/guard_read_for_never.rs b/tests/ui/reachable/guard_read_for_never.rs index 7061da635301..763dfd354b58 100644 --- a/tests/ui/reachable/guard_read_for_never.rs +++ b/tests/ui/reachable/guard_read_for_never.rs @@ -2,7 +2,7 @@ // //@ check-pass #![feature(guard_patterns, never_type)] -#![expect(incomplete_features, unused_parens)] +#![expect(incomplete_features)] #![deny(unreachable_code)] fn main() { diff --git a/tests/ui/reachable/unreachable-code-ret.stderr b/tests/ui/reachable/unreachable-code-ret.stderr index d86def536df8..f51273eb4207 100644 --- a/tests/ui/reachable/unreachable-code-ret.stderr +++ b/tests/ui/reachable/unreachable-code-ret.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr index de402d65e6d6..39cd0eb35a63 100644 --- a/tests/ui/recursion/issue-23122-2.stderr +++ b/tests/ui/recursion/issue-23122-2.stderr @@ -11,7 +11,7 @@ note: required for `GetNext<<<<... as Next>::Next as Next>::Next as Next>::Next> LL | impl Next for GetNext { | - ^^^^ ^^^^^^^^^^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here = note: the full name for the type has been written to '$TEST_BUILD_DIR/issue-23122-2.long-type-$LONG_TYPE_HASH.txt' = note: consider using `--verbose` to print the full type name to the console diff --git a/tests/ui/reflection/feature_gate.rs b/tests/ui/reflection/feature_gate.rs new file mode 100644 index 000000000000..2dde26809793 --- /dev/null +++ b/tests/ui/reflection/feature_gate.rs @@ -0,0 +1,8 @@ +use std::mem::type_info::Type; +//~^ ERROR: use of unstable library feature `type_info` + +fn main() { + let ty = std::mem::type_info::Type::of::<()>(); + //~^ ERROR: use of unstable library feature `type_info` + //~| ERROR: use of unstable library feature `type_info` +} diff --git a/tests/ui/reflection/feature_gate.stderr b/tests/ui/reflection/feature_gate.stderr new file mode 100644 index 000000000000..76ad18ffb0ba --- /dev/null +++ b/tests/ui/reflection/feature_gate.stderr @@ -0,0 +1,33 @@ +error[E0658]: use of unstable library feature `type_info` + --> $DIR/feature_gate.rs:1:5 + | +LL | use std::mem::type_info::Type; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146922 for more information + = help: add `#![feature(type_info)]` 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[E0658]: use of unstable library feature `type_info` + --> $DIR/feature_gate.rs:5:14 + | +LL | let ty = std::mem::type_info::Type::of::<()>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146922 for more information + = help: add `#![feature(type_info)]` 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[E0658]: use of unstable library feature `type_info` + --> $DIR/feature_gate.rs:5:14 + | +LL | let ty = std::mem::type_info::Type::of::<()>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #146922 for more information + = help: add `#![feature(type_info)]` 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: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/regions/closure-prop-issue-104477-case1.rs b/tests/ui/regions/closure-prop-issue-104477-case1.rs new file mode 100644 index 000000000000..307ca930baea --- /dev/null +++ b/tests/ui/regions/closure-prop-issue-104477-case1.rs @@ -0,0 +1,14 @@ +//@ check-pass +// This checks that the compiler does not require that 'a: 'b. '_ has 'a and 'b as non-local +// upper bounds, but the compiler should not propagate 'a: 'b OR 'b: 'a when checking +// the closures. If it did, this would fail to compile, eventhough it's a valid program. +// PR #148329 explains this in detail. + +struct MyTy<'x, 'a, 'b>(std::cell::Cell<(&'x &'a u8, &'x &'b u8)>); +fn wf(_: T) {} +fn test<'a, 'b>() { + |_: &'a u8, x: MyTy<'_, 'a, 'b>| wf(x); + |x: MyTy<'_, 'a, 'b>, _: &'a u8| wf(x); +} + +fn main(){} diff --git a/tests/ui/regions/closure-prop-issue-104477-case2.rs b/tests/ui/regions/closure-prop-issue-104477-case2.rs new file mode 100644 index 000000000000..a77a11d0eceb --- /dev/null +++ b/tests/ui/regions/closure-prop-issue-104477-case2.rs @@ -0,0 +1,12 @@ +//@ check-pass +// This test checks that the compiler propagates outlives requirements for both +// non-local lower bounds ['a, 'b] of '_, instead of conservatively finding a post-dominiting one +// from those 2. + +struct MyTy<'a, 'b, 'x>(std::cell::Cell<(&'a &'x str, &'b &'x str)>); +fn wf(_: T) {} +fn test<'a, 'b, 'x>() { + |x: MyTy<'a, 'b, '_>| wf(x); +} + +fn main() {} diff --git a/tests/ui/regions/closure-prop-issue-148289.rs b/tests/ui/regions/closure-prop-issue-148289.rs new file mode 100644 index 000000000000..7f89927a76e0 --- /dev/null +++ b/tests/ui/regions/closure-prop-issue-148289.rs @@ -0,0 +1,26 @@ +//@ check-pass +// This test checks that the compiler does not propagate 'd: 'c when propagating region errors +// for the closure argument. If it did, this would fail to compile, eventhough it's a valid program. +// It should only propagate 'd: 'b. +// PR #148329 explains this in detail. + +#[derive(Clone, Copy)] +struct Inv<'a>(*mut &'a ()); +impl<'a> Inv<'a> { + fn outlived_by<'b: 'a>(self, _: Inv<'b>) {} +} +struct OutlivedBy<'a, 'b: 'a>(Inv<'a>, Inv<'b>); + +fn closure_arg<'b, 'c, 'd>( + _: impl for<'a> FnOnce(Inv<'a>, OutlivedBy<'a, 'b>, OutlivedBy<'a, 'c>, Inv<'d>), +) { +} +fn foo<'b, 'c, 'd: 'b>() { + closure_arg::<'b, 'c, 'd>(|a, b, c, d| { + a.outlived_by(b.1); + a.outlived_by(c.1); + b.1.outlived_by(d); + }); +} + +fn main() {} diff --git a/tests/ui/regions/forall-wf-ref-reflexive.stderr b/tests/ui/regions/forall-wf-ref-reflexive.stderr index 5ee7cc7866c9..71debe7c297b 100644 --- a/tests/ui/regions/forall-wf-ref-reflexive.stderr +++ b/tests/ui/regions/forall-wf-ref-reflexive.stderr @@ -2,7 +2,7 @@ error: `T` does not live long enough --> $DIR/forall-wf-ref-reflexive.rs:12:5 | LL | self_wf2::(); - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/regions/outlives-with-missing.stderr b/tests/ui/regions/outlives-with-missing.stderr index b8762e9cb8f3..25fac1970635 100644 --- a/tests/ui/regions/outlives-with-missing.stderr +++ b/tests/ui/regions/outlives-with-missing.stderr @@ -5,7 +5,13 @@ LL | impl HandlerWrapper { | - similarly named type parameter `H` defined here ... LL | T: Send + Sync + 'static, - | ^ help: a type parameter with a similar name exists: `H` + | ^ + | +help: a type parameter with a similar name exists + | +LL - T: Send + Sync + 'static, +LL + H: Send + Sync + 'static, + | error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-bound-lists-feature-gate-2.rs b/tests/ui/regions/regions-bound-lists-feature-gate-2.rs index f4f27a4456df..6cdae0d49081 100644 --- a/tests/ui/regions/regions-bound-lists-feature-gate-2.rs +++ b/tests/ui/regions/regions-bound-lists-feature-gate-2.rs @@ -1,8 +1,5 @@ //@ run-pass #![allow(dead_code)] -#![allow(stable_features)] - -#![feature(issue_5723_bootstrap)] trait Foo { fn dummy(&self) { } diff --git a/tests/ui/regions/regions-bound-lists-feature-gate.rs b/tests/ui/regions/regions-bound-lists-feature-gate.rs index 1bc2b7dd03ef..23878f5b406f 100644 --- a/tests/ui/regions/regions-bound-lists-feature-gate.rs +++ b/tests/ui/regions/regions-bound-lists-feature-gate.rs @@ -1,9 +1,6 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -#![allow(stable_features)] - -#![feature(issue_5723_bootstrap)] trait Foo { fn dummy(&self) { } diff --git a/tests/ui/regions/regions-normalize-in-where-clause-list.rs b/tests/ui/regions/regions-normalize-in-where-clause-list.rs index 9b046e6baed6..bcc5da406b4e 100644 --- a/tests/ui/regions/regions-normalize-in-where-clause-list.rs +++ b/tests/ui/regions/regions-normalize-in-where-clause-list.rs @@ -25,6 +25,7 @@ fn bar<'a, 'b>() where <() as Project<'a, 'b>>::Item: Eq, //~^ ERROR cannot infer + //~| ERROR cannot infer { } diff --git a/tests/ui/regions/regions-normalize-in-where-clause-list.stderr b/tests/ui/regions/regions-normalize-in-where-clause-list.stderr index 9a5c9ae53de3..1a20055836ac 100644 --- a/tests/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/tests/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -22,6 +22,31 @@ LL | <() as Project<'a, 'b>>::Item: Eq, = note: expected `Project<'a, 'b>` found `Project<'_, '_>` -error: aborting due to 1 previous error +error[E0803]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/regions-normalize-in-where-clause-list.rs:26:36 + | +LL | <() as Project<'a, 'b>>::Item: Eq, + | ^^ + | +note: first, the lifetime cannot outlive the lifetime `'a` as defined here... + --> $DIR/regions-normalize-in-where-clause-list.rs:24:8 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...but the lifetime must also be valid for the lifetime `'b` as defined here... + --> $DIR/regions-normalize-in-where-clause-list.rs:24:12 + | +LL | fn bar<'a, 'b>() + | ^^ +note: ...so that the types are compatible + --> $DIR/regions-normalize-in-where-clause-list.rs:26:36 + | +LL | <() as Project<'a, 'b>>::Item: Eq, + | ^^ + = note: expected `Project<'a, 'b>` + found `Project<'_, '_>` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0803`. diff --git a/tests/ui/regions/wf-bound-region-in-local-issue-115175.rs b/tests/ui/regions/wf-bound-region-in-local-issue-115175.rs new file mode 100644 index 000000000000..b19f96357ad6 --- /dev/null +++ b/tests/ui/regions/wf-bound-region-in-local-issue-115175.rs @@ -0,0 +1,11 @@ +// A regression test for https://github.com/rust-lang/rust/issues/115175. +// This used to compile without error despite of unsatisfied outlives bound `T: 'static` on local. + +struct Static(T); + +fn test() { + let _ = None::>; + //~^ ERROR the parameter type `T` may not live long enough +} + +fn main() {} diff --git a/tests/ui/regions/wf-bound-region-in-local-issue-115175.stderr b/tests/ui/regions/wf-bound-region-in-local-issue-115175.stderr new file mode 100644 index 000000000000..1a1b142b9d1d --- /dev/null +++ b/tests/ui/regions/wf-bound-region-in-local-issue-115175.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/wf-bound-region-in-local-issue-115175.rs:7:13 + | +LL | let _ = None::>; + | ^^^^^^^^^^^^^^^^^ + | | + | the parameter type `T` must be valid for the static lifetime... + | ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | fn test() { + | +++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/regions/wf-bound-region-in-local-soundness-issue-148854.rs b/tests/ui/regions/wf-bound-region-in-local-soundness-issue-148854.rs new file mode 100644 index 000000000000..b21669cf7842 --- /dev/null +++ b/tests/ui/regions/wf-bound-region-in-local-soundness-issue-148854.rs @@ -0,0 +1,51 @@ +// A regression test for https://github.com/rust-lang/rust/issues/148854. + +use std::cell::OnceCell; +use std::fmt::Display; +use std::marker::PhantomData; +use std::rc::Rc; + +type Storage = Rc>>; + +trait IntoDyn { + fn into_dyn(input: T, output: Storage); +} + +struct Inner(PhantomData); +impl IntoDyn for Inner { + fn into_dyn(input: T, output: Storage) { + output.set(Box::new(input)).ok().unwrap(); + } +} + +struct Outer> { + input: Option, + output: Storage, + _phantom: PhantomData, +} +impl> Drop for Outer { + fn drop(&mut self) { + U::into_dyn(self.input.take().unwrap(), self.output.clone()); + } +} + +fn extend(x: T) -> Box { + let storage = Rc::new(OnceCell::new()); + { + // This has to error due to an unsatisfied outlives bound on + // `Inner` as its implicit drop relies on that + // bound. + let _ = + Outer::> { input: Some(x), output: storage.clone(), _phantom: PhantomData }; + //~^ ERROR: the parameter type `T` may not live long enough + } + Rc::into_inner(storage).unwrap().into_inner().unwrap() +} + +fn main() { + let wrong = { + let data = String::from("abc"); + extend::<&String>(&data) + }; + println!("{wrong}"); +} diff --git a/tests/ui/regions/wf-bound-region-in-local-soundness-issue-148854.stderr b/tests/ui/regions/wf-bound-region-in-local-soundness-issue-148854.stderr new file mode 100644 index 000000000000..d79daaf2a6ad --- /dev/null +++ b/tests/ui/regions/wf-bound-region-in-local-soundness-issue-148854.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/wf-bound-region-in-local-soundness-issue-148854.rs:39:13 + | +LL | Outer::> { input: Some(x), output: storage.clone(), _phantom: PhantomData }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the parameter type `T` must be valid for the static lifetime... + | ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound + | +LL | fn extend(x: T) -> Box { + | +++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs b/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs new file mode 100644 index 000000000000..274942f9379f --- /dev/null +++ b/tests/ui/repeat-expr/can-have-side-effects-consider-element.rs @@ -0,0 +1,20 @@ +//@ check-pass + +#![allow(unused)] + +// Test if `Expr::can_have_side_effects` considers element of repeat expressions. + +fn drop_repeat_in_arm_body() { + // Built-in lint `dropping_copy_types` relies on `Expr::can_have_side_effects` + // (See rust-clippy#9482 and rust#113231) + + match () { + () => drop([0; 1]), // No side effects + //~^ WARNING calls to `std::mem::drop` with a value that implements `Copy` does nothing + } + match () { + () => drop([return; 1]), // Definitely has side effects + } +} + +fn main() {} diff --git a/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr b/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr new file mode 100644 index 000000000000..70c7e8b404e0 --- /dev/null +++ b/tests/ui/repeat-expr/can-have-side-effects-consider-element.stderr @@ -0,0 +1,13 @@ +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/can-have-side-effects-consider-element.rs:12:15 + | +LL | () => drop([0; 1]), // No side effects + | ^^^^^------^ + | | + | argument has type `[i32; 1]` + | + = note: use `let _ = ...` to ignore the expression or result + = note: `#[warn(dropping_copy_types)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs index a6bd5b299c96..02cd9f4a3b29 100644 --- a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs +++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs @@ -1,6 +1,6 @@ // Test when deferring repeat expr copy checks to end of typechecking whether they're // checked before integer fallback occurs or not. We accomplish this by having a repeat -// count that can only be inferred after integer fallback has occured. This test will +// count that can only be inferred after integer fallback has occurred. This test will // pass if we were to check repeat exprs after integer fallback. use std::marker::PhantomData; diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr index c98b9bb38fdb..ba44beb76dbb 100644 --- a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr +++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr @@ -7,7 +7,7 @@ LL | LL | extract(x).max(2); | ---------- type must be known at this point | -help: consider giving `x` an explicit type, where the placeholders `_` are specified +help: consider giving `x` an explicit type, where the type for type parameter `T` is specified | LL | let x: [Foo; 2] = [Foo(PhantomData); 2]; | +++++++++++++ diff --git a/tests/ui/repeat-expr/repeat_count.rs b/tests/ui/repeat-expr/repeat_count.rs index 2febcdc07c2a..b1e3a9d8cb3b 100644 --- a/tests/ui/repeat-expr/repeat_count.rs +++ b/tests/ui/repeat-expr/repeat_count.rs @@ -21,16 +21,21 @@ fn main() { let f = [0; -4_isize]; //~^ ERROR mismatched types //~| NOTE expected `usize`, found `isize` - let f = [0_usize; -1_isize]; + //~| NOTE `-4_isize` cannot fit into type `usize` + let g = [0_usize; -1_isize]; //~^ ERROR mismatched types //~| NOTE expected `usize`, found `isize` - let f = [0; 4u8]; - //~^ ERROR mismatched types + //~| NOTE `-1_isize` cannot fit into type `usize` + let h = [0; 4u8]; + //~^ ERROR the constant `4` is not of type `usize` //~| NOTE expected `usize`, found `u8` - struct G { - g: (), + //~| NOTE the length of array `[{integer}; 4]` must be type `usize` + //~| ERROR mismatched types + //~| NOTE expected `usize`, found `u8` + struct I { + i: (), } - let g = [0; G { g: () }]; + let i = [0; I { i: () }]; //~^ ERROR mismatched types - //~| NOTE expected `usize`, found `G` + //~| NOTE expected `usize`, found `I` } diff --git a/tests/ui/repeat-expr/repeat_count.stderr b/tests/ui/repeat-expr/repeat_count.stderr index cf94ad41ee36..5da9dbe03209 100644 --- a/tests/ui/repeat-expr/repeat_count.stderr +++ b/tests/ui/repeat-expr/repeat_count.stderr @@ -16,12 +16,6 @@ error[E0308]: mismatched types LL | let b = [0; ()]; | ^^ expected `usize`, found `()` -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:33:17 - | -LL | let g = [0; G { g: () }]; - | ^^^^^^^^^^^ expected `usize`, found `G` - error[E0308]: mismatched types --> $DIR/repeat_count.rs:12:17 | @@ -49,26 +43,40 @@ LL | let f = [0; -4_isize]; = note: `-4_isize` cannot fit into type `usize` error[E0308]: mismatched types - --> $DIR/repeat_count.rs:24:23 + --> $DIR/repeat_count.rs:25:23 | -LL | let f = [0_usize; -1_isize]; +LL | let g = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` | = note: `-1_isize` cannot fit into type `usize` -error[E0308]: mismatched types - --> $DIR/repeat_count.rs:27:17 +error: the constant `4` is not of type `usize` + --> $DIR/repeat_count.rs:29:13 | -LL | let f = [0; 4u8]; +LL | let h = [0; 4u8]; + | ^^^^^^^^ expected `usize`, found `u8` + | + = note: the length of array `[{integer}; 4]` must be type `usize` + +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:38:17 + | +LL | let i = [0; I { i: () }]; + | ^^^^^^^^^^^ expected `usize`, found `I` + +error[E0308]: mismatched types + --> $DIR/repeat_count.rs:29:17 + | +LL | let h = [0; 4u8]; | ^^^ expected `usize`, found `u8` | help: change the type of the numeric literal from `u8` to `usize` | -LL - let f = [0; 4u8]; -LL + let f = [0; 4usize]; +LL - let h = [0; 4u8]; +LL + let h = [0; 4usize]; | -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0308, E0435. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/repr/align-with-extern-c-fn.rs b/tests/ui/repr/align-with-extern-c-fn.rs index 4d17d1e8816f..a695f4bffe94 100644 --- a/tests/ui/repr/align-with-extern-c-fn.rs +++ b/tests/ui/repr/align-with-extern-c-fn.rs @@ -1,12 +1,9 @@ //@ run-pass -#![allow(stable_features)] #![allow(unused_variables)] // #45662 -#![feature(repr_align)] - #[repr(align(16))] pub struct A(#[allow(dead_code)] i64); diff --git a/tests/ui/repr/invalid_repr_list_help.rs b/tests/ui/repr/invalid_repr_list_help.rs index 77f2a68537b3..e8bf5fdcd3fd 100644 --- a/tests/ui/repr/invalid_repr_list_help.rs +++ b/tests/ui/repr/invalid_repr_list_help.rs @@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #[repr(uwu)] //~ERROR: unrecognized representation hint diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr index f9d1593275ee..322650814828 100644 --- a/tests/ui/repr/invalid_repr_list_help.stderr +++ b/tests/ui/repr/invalid_repr_list_help.stderr @@ -1,5 +1,5 @@ error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:3:8 + --> $DIR/invalid_repr_list_help.rs:4:8 | LL | #[repr(uwu)] | ^^^ @@ -8,7 +8,7 @@ LL | #[repr(uwu)] = note: for more information, visit error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:6:8 + --> $DIR/invalid_repr_list_help.rs:7:8 | LL | #[repr(uwu = "a")] | ^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #[repr(uwu = "a")] = note: for more information, visit error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:9:8 + --> $DIR/invalid_repr_list_help.rs:10:8 | LL | #[repr(uwu(4))] | ^^^^^^ @@ -26,7 +26,7 @@ LL | #[repr(uwu(4))] = note: for more information, visit error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:14:8 + --> $DIR/invalid_repr_list_help.rs:15:8 | LL | #[repr(uwu, u8)] | ^^^ @@ -35,7 +35,7 @@ LL | #[repr(uwu, u8)] = note: for more information, visit error[E0552]: unrecognized representation hint - --> $DIR/invalid_repr_list_help.rs:19:8 + --> $DIR/invalid_repr_list_help.rs:20:8 | LL | #[repr(uwu)] | ^^^ @@ -44,12 +44,16 @@ LL | #[repr(uwu)] = note: for more information, visit error: unknown `doc` attribute `owo` - --> $DIR/invalid_repr_list_help.rs:20:7 + --> $DIR/invalid_repr_list_help.rs:21:7 | LL | #[doc(owo)] | ^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/invalid_repr_list_help.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 1a1929c530ff..62f6ec92d493 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 67729e9fcef9..3e0efad974cd 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 1a1929c530ff..62f6ec92d493 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 1a1929c530ff..62f6ec92d493 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -16,7 +16,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(Univariant) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariants) = Layout { offsets: [ Size(4 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index d88a842f8848..b25e4a9b7b6f 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -16,7 +16,7 @@ error: layout_of(UnivariantU8) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -60,7 +60,7 @@ error: layout_of(UnivariantU8) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -108,7 +108,7 @@ error: layout_of(TwoVariantsU8) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -158,7 +158,7 @@ error: layout_of(TwoVariantsU8) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -195,7 +195,7 @@ error: layout_of(TwoVariantsU8) = Layout { offsets: [ Size(1 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -231,7 +231,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -270,7 +270,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { Size(8 bytes), Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, 1, ], @@ -298,7 +298,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { offsets: [ Size(8 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/repr/repr.stderr b/tests/ui/repr/repr.stderr index d4faea125176..a842590c9639 100644 --- a/tests/ui/repr/repr.stderr +++ b/tests/ui/repr/repr.stderr @@ -5,63 +5,26 @@ LL | #[repr] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[repr()] - | ++++++++++++++++ -LL | #[repr(C)] - | +++ -LL | #[repr(Rust)] - | ++++++ -LL | #[repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0539]: malformed `repr` attribute input --> $DIR/repr.rs:4:1 | LL | #[repr = "B"] - | ^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^-----^ + | | + | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[repr = "B"] -LL + #[repr()] - | -LL - #[repr = "B"] -LL + #[repr(C)] - | -LL - #[repr = "B"] -LL + #[repr(Rust)] - | -LL - #[repr = "B"] -LL + #[repr(align(...))] - | - = and 2 other candidates error[E0539]: malformed `repr` attribute input --> $DIR/repr.rs:7:1 | LL | #[repr = "C"] - | ^^^^^^^^^^^^^ expected this to be a list + | ^^^^^^^-----^ + | | + | expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[repr = "C"] -LL + #[repr()] - | -LL - #[repr = "C"] -LL + #[repr(C)] - | -LL - #[repr = "C"] -LL + #[repr(Rust)] - | -LL - #[repr = "C"] -LL + #[repr(align(...))] - | - = and 2 other candidates error: aborting due to 3 previous errors diff --git a/tests/ui/repr/repr_align_greater_usize.msp430.stderr b/tests/ui/repr/repr_align_greater_usize.msp430.stderr index db25cb1b5f2e..a7b06acb6752 100644 --- a/tests/ui/repr/repr_align_greater_usize.msp430.stderr +++ b/tests/ui/repr/repr_align_greater_usize.msp430.stderr @@ -1,5 +1,5 @@ error[E0589]: alignment must not be greater than `isize::MAX` bytes - --> $DIR/repr_align_greater_usize.rs:22:8 + --> $DIR/repr_align_greater_usize.rs:23:8 | LL | #[repr(align(32768))] | ^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[repr(align(32768))] = note: `isize::MAX` is 32767 for the current target error[E0589]: alignment must not be greater than `isize::MAX` bytes - --> $DIR/repr_align_greater_usize.rs:25:8 + --> $DIR/repr_align_greater_usize.rs:26:8 | LL | #[repr(align(65536))] | ^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr_align_greater_usize.rs b/tests/ui/repr/repr_align_greater_usize.rs index d8eb03ef9525..52a4d23b1eca 100644 --- a/tests/ui/repr/repr_align_greater_usize.rs +++ b/tests/ui/repr/repr_align_greater_usize.rs @@ -5,6 +5,7 @@ //@[aarch32] build-pass //@[aarch32] needs-llvm-components: arm //@[aarch32] compile-flags: --target=thumbv7m-none-eabi +//@ ignore-backends: gcc // We should fail to compute alignment for types aligned higher than usize::MAX. // We can't handle alignments that require all 32 bits, so this only affects 16-bit. diff --git a/tests/ui/reserved/meta-is-not-reserved.rs b/tests/ui/reserved/meta-is-not-reserved.rs new file mode 100644 index 000000000000..ceefe345ff0c --- /dev/null +++ b/tests/ui/reserved/meta-is-not-reserved.rs @@ -0,0 +1,7 @@ +// Regression test for +// A test for the issue where the variable meta is mistakenly treated as a reserved keyword. + +fn main() { + let xyz = meta; + //~^ ERROR cannot find value `meta` in this scope [E0425] +} diff --git a/tests/ui/reserved/meta-is-not-reserved.stderr b/tests/ui/reserved/meta-is-not-reserved.stderr new file mode 100644 index 000000000000..33f8fd82df85 --- /dev/null +++ b/tests/ui/reserved/meta-is-not-reserved.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `meta` in this scope + --> $DIR/meta-is-not-reserved.rs:5:15 + | +LL | let xyz = meta; + | ^^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/112590-2.fixed b/tests/ui/resolve/112590-2.fixed index bbc8d4b2954a..2bda2197d6d4 100644 --- a/tests/ui/resolve/112590-2.fixed +++ b/tests/ui/resolve/112590-2.fixed @@ -16,7 +16,7 @@ mod u { use foo::bar::baz::MyVec; fn _a() { - let _: Vec = MyVec::new(); //~ ERROR failed to resolve + let _: Vec = MyVec::new(); //~ ERROR cannot find } } @@ -24,12 +24,12 @@ mod v { use foo::bar::baz::MyVec; fn _b() { - let _: Vec = MyVec::new(); //~ ERROR failed to resolve + let _: Vec = MyVec::new(); //~ ERROR cannot find } } fn main() { - let _t: Vec = Vec::new(); //~ ERROR failed to resolve - type _B = vec::Vec::; //~ ERROR failed to resolve - let _t = AtomicBool::new(true); //~ ERROR failed to resolve + let _t: Vec = Vec::new(); //~ ERROR cannot find + type _B = vec::Vec::; //~ ERROR cannot find + let _t = AtomicBool::new(true); //~ ERROR cannot find } diff --git a/tests/ui/resolve/112590-2.rs b/tests/ui/resolve/112590-2.rs index 97d0b0bf2a94..a458ff501f97 100644 --- a/tests/ui/resolve/112590-2.rs +++ b/tests/ui/resolve/112590-2.rs @@ -10,18 +10,18 @@ mod foo { mod u { fn _a() { - let _: Vec = super::foo::baf::baz::MyVec::new(); //~ ERROR failed to resolve + let _: Vec = super::foo::baf::baz::MyVec::new(); //~ ERROR cannot find } } mod v { fn _b() { - let _: Vec = fox::bar::baz::MyVec::new(); //~ ERROR failed to resolve + let _: Vec = fox::bar::baz::MyVec::new(); //~ ERROR cannot find } } fn main() { - let _t: Vec = vec::new(); //~ ERROR failed to resolve - type _B = vec::Vec::; //~ ERROR failed to resolve - let _t = std::sync_error::atomic::AtomicBool::new(true); //~ ERROR failed to resolve + let _t: Vec = vec::new(); //~ ERROR cannot find + type _B = vec::Vec::; //~ ERROR cannot find + let _t = std::sync_error::atomic::AtomicBool::new(true); //~ ERROR cannot find } diff --git a/tests/ui/resolve/112590-2.stderr b/tests/ui/resolve/112590-2.stderr index 28d23ccf8537..8569dd0c3fa0 100644 --- a/tests/ui/resolve/112590-2.stderr +++ b/tests/ui/resolve/112590-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `baf` in `foo` +error[E0433]: cannot find `baf` in `foo` --> $DIR/112590-2.rs:13:39 | LL | let _: Vec = super::foo::baf::baz::MyVec::new(); @@ -14,7 +14,7 @@ LL - let _: Vec = super::foo::baf::baz::MyVec::new(); LL + let _: Vec = MyVec::new(); | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `fox` +error[E0433]: cannot find module or crate `fox` in this scope --> $DIR/112590-2.rs:19:27 | LL | let _: Vec = fox::bar::baz::MyVec::new(); @@ -31,7 +31,7 @@ LL - let _: Vec = fox::bar::baz::MyVec::new(); LL + let _: Vec = MyVec::new(); | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `vec` +error[E0433]: cannot find module or crate `vec` in this scope --> $DIR/112590-2.rs:25:15 | LL | type _B = vec::Vec::; @@ -43,7 +43,7 @@ help: consider importing this module LL + use std::vec; | -error[E0433]: failed to resolve: could not find `sync_error` in `std` +error[E0433]: cannot find `sync_error` in `std` --> $DIR/112590-2.rs:26:19 | LL | let _t = std::sync_error::atomic::AtomicBool::new(true); @@ -59,16 +59,18 @@ LL - let _t = std::sync_error::atomic::AtomicBool::new(true); LL + let _t = AtomicBool::new(true); | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `vec` +error[E0433]: cannot find module or crate `vec` in this scope --> $DIR/112590-2.rs:24:24 | LL | let _t: Vec = vec::new(); - | ^^^ - | | - | use of unresolved module or unlinked crate `vec` - | help: a struct with a similar name exists (notice the capitalization): `Vec` + | ^^^ use of unresolved module or unlinked crate `vec` | = help: you might be missing a crate named `vec` +help: a struct with a similar name exists (notice the capitalization) + | +LL - let _t: Vec = vec::new(); +LL + let _t: Vec = Vec::new(); + | error: aborting due to 5 previous errors diff --git a/tests/ui/issues/auxiliary/i8.rs b/tests/ui/resolve/auxiliary/i8.rs similarity index 100% rename from tests/ui/issues/auxiliary/i8.rs rename to tests/ui/resolve/auxiliary/i8.rs diff --git a/tests/ui/resolve/bad-module.rs b/tests/ui/resolve/bad-module.rs index 9fe06ab0f52e..0d59222e746f 100644 --- a/tests/ui/resolve/bad-module.rs +++ b/tests/ui/resolve/bad-module.rs @@ -1,7 +1,7 @@ fn main() { let foo = thing::len(Vec::new()); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `thing` + //~^ ERROR cannot find module or crate `thing` let foo = foo::bar::baz(); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `foo` + //~^ ERROR cannot find module or crate `foo` } diff --git a/tests/ui/resolve/bad-module.stderr b/tests/ui/resolve/bad-module.stderr index 0f597e126fdc..82c93ca973d1 100644 --- a/tests/ui/resolve/bad-module.stderr +++ b/tests/ui/resolve/bad-module.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `foo` +error[E0433]: cannot find module or crate `foo` in this scope --> $DIR/bad-module.rs:5:15 | LL | let foo = foo::bar::baz(); @@ -6,7 +6,7 @@ LL | let foo = foo::bar::baz(); | = help: you might be missing a crate named `foo` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `thing` +error[E0433]: cannot find module or crate `thing` in this scope --> $DIR/bad-module.rs:2:15 | LL | let foo = thing::len(Vec::new()); diff --git a/tests/ui/resolve/const-iter-no-conflict-for-loop.rs b/tests/ui/resolve/const-iter-no-conflict-for-loop.rs new file mode 100644 index 000000000000..ddbba64e5a31 --- /dev/null +++ b/tests/ui/resolve/const-iter-no-conflict-for-loop.rs @@ -0,0 +1,15 @@ +//! regression test for +//! Ensure that a constant named `iter` does not +//! interfere with the name resolution of the `iter` methods used internally +//! by `for` loops +//@ run-pass +#![allow(dead_code)] +#![allow(non_upper_case_globals)] + +fn main() { + const iter: i32 = 0; + + for i in 1..10 { + println!("{}", i); + } +} diff --git a/tests/ui/resolve/decl-macro-use-no-ice.rs b/tests/ui/resolve/decl-macro-use-no-ice.rs new file mode 100644 index 000000000000..39b9cb03fea0 --- /dev/null +++ b/tests/ui/resolve/decl-macro-use-no-ice.rs @@ -0,0 +1,20 @@ +//@ edition: 2024 +#![feature(decl_macro)] + +// Regression test for issue +// The compiler previously ICE'd during identifier resolution +// involving `macro` items and `use` inside a public macro. + + +mod foo { + macro f() {} + + pub macro m() { + use f; //~ ERROR `f` is private, and cannot be re-exported + f!(); //~ ERROR macro import `f` is private + } +} + +fn main() { + foo::m!(); +} diff --git a/tests/ui/resolve/decl-macro-use-no-ice.stderr b/tests/ui/resolve/decl-macro-use-no-ice.stderr new file mode 100644 index 000000000000..9fb75b48b428 --- /dev/null +++ b/tests/ui/resolve/decl-macro-use-no-ice.stderr @@ -0,0 +1,47 @@ +error[E0364]: `f` is private, and cannot be re-exported + --> $DIR/decl-macro-use-no-ice.rs:13:13 + | +LL | use f; + | ^ +... +LL | foo::m!(); + | --------- in this macro invocation + | +note: consider marking `f` as `pub` in the imported module + --> $DIR/decl-macro-use-no-ice.rs:13:13 + | +LL | use f; + | ^ +... +LL | foo::m!(); + | --------- in this macro invocation + = note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0603]: macro import `f` is private + --> $DIR/decl-macro-use-no-ice.rs:14:9 + | +LL | f!(); + | ^ private macro import +... +LL | foo::m!(); + | --------- in this macro invocation + | +note: the macro import `f` is defined here... + --> $DIR/decl-macro-use-no-ice.rs:13:13 + | +LL | use f; + | ^ +... +LL | foo::m!(); + | --------- in this macro invocation +note: ...and refers to the macro `f` which is defined here + --> $DIR/decl-macro-use-no-ice.rs:10:5 + | +LL | macro f() {} + | ^^^^^^^^^ + = note: this error originates in the macro `foo::m` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0364, E0603. +For more information about an error, try `rustc --explain E0364`. diff --git a/tests/ui/resolve/editions-crate-root-2015.rs b/tests/ui/resolve/editions-crate-root-2015.rs index a2e19bfdf1c5..163984b4e8f7 100644 --- a/tests/ui/resolve/editions-crate-root-2015.rs +++ b/tests/ui/resolve/editions-crate-root-2015.rs @@ -2,17 +2,17 @@ mod inner { fn global_inner(_: ::nonexistant::Foo) { - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `nonexistant` + //~^ ERROR: cannot find module or crate `nonexistant` } fn crate_inner(_: crate::nonexistant::Foo) { - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `nonexistant` + //~^ ERROR: cannot find module or crate `nonexistant` } fn bare_global(_: ::nonexistant) { - //~^ ERROR cannot find type `nonexistant` in the crate root + //~^ ERROR: cannot find type `nonexistant` in the crate root } fn bare_crate(_: crate::nonexistant) { - //~^ ERROR cannot find type `nonexistant` in the crate root + //~^ ERROR: cannot find type `nonexistant` in the crate root } } diff --git a/tests/ui/resolve/editions-crate-root-2015.stderr b/tests/ui/resolve/editions-crate-root-2015.stderr index 989ee547a7c6..a4002349387a 100644 --- a/tests/ui/resolve/editions-crate-root-2015.stderr +++ b/tests/ui/resolve/editions-crate-root-2015.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nonexistant` +error[E0433]: cannot find module or crate `nonexistant` in the crate root --> $DIR/editions-crate-root-2015.rs:4:26 | LL | fn global_inner(_: ::nonexistant::Foo) { @@ -9,7 +9,7 @@ help: you might be missing a crate named `nonexistant`, add it to your project a LL + extern crate nonexistant; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nonexistant` +error[E0433]: cannot find module or crate `nonexistant` in `crate` --> $DIR/editions-crate-root-2015.rs:7:30 | LL | fn crate_inner(_: crate::nonexistant::Foo) { diff --git a/tests/ui/resolve/editions-crate-root-2018.rs b/tests/ui/resolve/editions-crate-root-2018.rs index 0e964d20f9c0..c07f617455ef 100644 --- a/tests/ui/resolve/editions-crate-root-2018.rs +++ b/tests/ui/resolve/editions-crate-root-2018.rs @@ -2,17 +2,17 @@ mod inner { fn global_inner(_: ::nonexistant::Foo) { - //~^ ERROR failed to resolve: could not find `nonexistant` in the list of imported crates + //~^ ERROR: cannot find `nonexistant` } fn crate_inner(_: crate::nonexistant::Foo) { - //~^ ERROR failed to resolve: could not find `nonexistant` in the crate root + //~^ ERROR: cannot find `nonexistant` } fn bare_global(_: ::nonexistant) { - //~^ ERROR cannot find crate `nonexistant` in the list of imported crates + //~^ ERROR: cannot find crate `nonexistant` } fn bare_crate(_: crate::nonexistant) { - //~^ ERROR cannot find type `nonexistant` in the crate root + //~^ ERROR: cannot find type `nonexistant` in the crate root } } diff --git a/tests/ui/resolve/editions-crate-root-2018.stderr b/tests/ui/resolve/editions-crate-root-2018.stderr index 1bcef3396199..c7ce93670051 100644 --- a/tests/ui/resolve/editions-crate-root-2018.stderr +++ b/tests/ui/resolve/editions-crate-root-2018.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: could not find `nonexistant` in the list of imported crates +error[E0433]: cannot find `nonexistant` in the crate root --> $DIR/editions-crate-root-2018.rs:4:26 | LL | fn global_inner(_: ::nonexistant::Foo) { | ^^^^^^^^^^^ could not find `nonexistant` in the list of imported crates -error[E0433]: failed to resolve: could not find `nonexistant` in the crate root +error[E0433]: cannot find `nonexistant` in `crate` --> $DIR/editions-crate-root-2018.rs:7:30 | LL | fn crate_inner(_: crate::nonexistant::Foo) { diff --git a/tests/ui/resolve/enum-variant-import-2904.rs b/tests/ui/resolve/enum-variant-import-2904.rs new file mode 100644 index 000000000000..3272ee5fb500 --- /dev/null +++ b/tests/ui/resolve/enum-variant-import-2904.rs @@ -0,0 +1,101 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2904 + +//@ build-pass +#![allow(unused_must_use)] +#![allow(dead_code)] +#![allow(unused_mut)] + +// Map representation + +use Square::{Bot, ClosedLift, Earth, Empty, Lambda, OpenLift, Rock, Wall}; +use std::fmt; +use std::io::prelude::*; + +enum Square { + Bot, + Wall, + Rock, + Lambda, + ClosedLift, + OpenLift, + Earth, + Empty, +} + +impl fmt::Debug for Square { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "{}", + match *self { + Bot => { + "R".to_string() + } + Wall => { + "#".to_string() + } + Rock => { + "*".to_string() + } + Lambda => { + "\\".to_string() + } + ClosedLift => { + "L".to_string() + } + OpenLift => { + "O".to_string() + } + Earth => { + ".".to_string() + } + Empty => { + " ".to_string() + } + } + ) + } +} + +fn square_from_char(c: char) -> Square { + match c { + 'R' => Bot, + '#' => Wall, + '*' => Rock, + '\\' => Lambda, + 'L' => ClosedLift, + 'O' => OpenLift, + '.' => Earth, + ' ' => Empty, + _ => { + println!("invalid Square: {}", c); + panic!() + } + } +} + +fn read_board_grid(mut input: Rdr) -> Vec> { + let mut input: &mut dyn Read = &mut input; + let mut grid = Vec::new(); + let mut line = [0; 10]; + input.read(&mut line); + let mut row = Vec::new(); + for c in &line { + row.push(square_from_char(*c as char)) + } + grid.push(row); + let width = grid[0].len(); + for row in &grid { + assert_eq!(row.len(), width) + } + grid +} + +mod test { + #[test] + pub fn trivial_to_string() { + assert_eq!(Lambda.to_string(), "\\") + } +} + +pub fn main() {} diff --git a/tests/ui/resolve/export-fully-qualified-2018.rs b/tests/ui/resolve/export-fully-qualified-2018.rs index ce78b64bf256..a6121c2e800c 100644 --- a/tests/ui/resolve/export-fully-qualified-2018.rs +++ b/tests/ui/resolve/export-fully-qualified-2018.rs @@ -5,7 +5,8 @@ // want to change eventually. mod foo { - pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of unresolved module or unlinked crate `foo` + pub fn bar() { foo::baz(); } //~ ERROR: cannot find + //~^ NOTE: use of unresolved module or unlinked crate `foo` fn baz() { } } diff --git a/tests/ui/resolve/export-fully-qualified-2018.stderr b/tests/ui/resolve/export-fully-qualified-2018.stderr index a985669b8b41..25c9e6fbdab9 100644 --- a/tests/ui/resolve/export-fully-qualified-2018.stderr +++ b/tests/ui/resolve/export-fully-qualified-2018.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `foo` +error[E0433]: cannot find module or crate `foo` in this scope --> $DIR/export-fully-qualified-2018.rs:8:20 | LL | pub fn bar() { foo::baz(); } diff --git a/tests/ui/resolve/export-fully-qualified.rs b/tests/ui/resolve/export-fully-qualified.rs index 0be3b81ebb8f..db0570d64f26 100644 --- a/tests/ui/resolve/export-fully-qualified.rs +++ b/tests/ui/resolve/export-fully-qualified.rs @@ -5,7 +5,7 @@ // want to change eventually. mod foo { - pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of unresolved module or unlinked crate `foo` + pub fn bar() { foo::baz(); } //~ ERROR cannot find module or crate `foo` fn baz() { } } diff --git a/tests/ui/resolve/export-fully-qualified.stderr b/tests/ui/resolve/export-fully-qualified.stderr index e65483e57eb5..f8433dcfb892 100644 --- a/tests/ui/resolve/export-fully-qualified.stderr +++ b/tests/ui/resolve/export-fully-qualified.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `foo` +error[E0433]: cannot find module or crate `foo` in this scope --> $DIR/export-fully-qualified.rs:8:20 | LL | pub fn bar() { foo::baz(); } diff --git a/tests/ui/resolve/exported-macro-in-mod-147958.rs b/tests/ui/resolve/exported-macro-in-mod-147958.rs new file mode 100644 index 000000000000..5003c410b692 --- /dev/null +++ b/tests/ui/resolve/exported-macro-in-mod-147958.rs @@ -0,0 +1,21 @@ +//! Regression test for + +//@ check-pass + +#![feature(decl_macro)] + +macro_rules! exported { + () => { + #[macro_export] + macro_rules! exported { + () => {}; + } + }; +} +use inner1::*; +exported!(); +mod inner1 { + pub macro exported() {} +} + +fn main() {} diff --git a/tests/ui/resolve/extern-prelude-fail.rs b/tests/ui/resolve/extern-prelude-fail.rs index 7d0df03e57bb..d86ee9550b33 100644 --- a/tests/ui/resolve/extern-prelude-fail.rs +++ b/tests/ui/resolve/extern-prelude-fail.rs @@ -6,5 +6,5 @@ fn main() { use extern_prelude::S; //~ ERROR unresolved import `extern_prelude` - let s = ::extern_prelude::S; //~ ERROR failed to resolve + let s = ::extern_prelude::S; //~ ERROR cannot find module or crate `extern_prelude` } diff --git a/tests/ui/resolve/extern-prelude-fail.stderr b/tests/ui/resolve/extern-prelude-fail.stderr index b9668154f446..a6192051e95a 100644 --- a/tests/ui/resolve/extern-prelude-fail.stderr +++ b/tests/ui/resolve/extern-prelude-fail.stderr @@ -9,7 +9,7 @@ help: you might be missing a crate named `extern_prelude`, add it to your projec LL + extern crate extern_prelude; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `extern_prelude` +error[E0433]: cannot find module or crate `extern_prelude` in the crate root --> $DIR/extern-prelude-fail.rs:9:15 | LL | let s = ::extern_prelude::S; diff --git a/tests/ui/resolve/function-module-ambiguity-error-71406.rs b/tests/ui/resolve/function-module-ambiguity-error-71406.rs index a7964de9ba5e..21163e3486b4 100644 --- a/tests/ui/resolve/function-module-ambiguity-error-71406.rs +++ b/tests/ui/resolve/function-module-ambiguity-error-71406.rs @@ -3,5 +3,6 @@ use std::sync::mpsc; fn main() { let (tx, rx) = mpsc::channel::new(1); - //~^ ERROR expected type, found function `channel` in `mpsc` + //~^ ERROR: cannot find `channel` + //~| NOTE: expected type, found function `channel` in `mpsc` } diff --git a/tests/ui/resolve/function-module-ambiguity-error-71406.stderr b/tests/ui/resolve/function-module-ambiguity-error-71406.stderr index c25bafa0a5dd..e5b00f294f3c 100644 --- a/tests/ui/resolve/function-module-ambiguity-error-71406.stderr +++ b/tests/ui/resolve/function-module-ambiguity-error-71406.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: expected type, found function `channel` in `mpsc` +error[E0433]: cannot find `channel` in `mpsc` --> $DIR/function-module-ambiguity-error-71406.rs:5:26 | LL | let (tx, rx) = mpsc::channel::new(1); diff --git a/tests/ui/resolve/ice-inconsistent-resolution-149821.rs b/tests/ui/resolve/ice-inconsistent-resolution-149821.rs new file mode 100644 index 000000000000..19b8a2f4330c --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-149821.rs @@ -0,0 +1,17 @@ +//@ edition: 2024 + +mod m { + use crate::*; + use core; +} + +macro_rules! define_other_core { + () => { + extern crate std as core; + //~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern` + }; +} + +define_other_core! {} + +fn main() {} diff --git a/tests/ui/resolve/ice-inconsistent-resolution-149821.stderr b/tests/ui/resolve/ice-inconsistent-resolution-149821.stderr new file mode 100644 index 000000000000..cd75a2f3e19b --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-149821.stderr @@ -0,0 +1,13 @@ +error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` + --> $DIR/ice-inconsistent-resolution-149821.rs:10:9 + | +LL | extern crate std as core; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | define_other_core! {} + | --------------------- in this macro invocation + | + = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + diff --git a/tests/ui/resolve/ice-inconsistent-resolution-151213.rs b/tests/ui/resolve/ice-inconsistent-resolution-151213.rs new file mode 100644 index 000000000000..ea0f1c2858ef --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-151213.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 + +#[attr] +//~^ ERROR cannot find attribute `attr` in this scope +extern crate core as std; +//~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern` + +mod inner { + use std::str; + + use crate::*; +} + +fn main() {} diff --git a/tests/ui/resolve/ice-inconsistent-resolution-151213.stderr b/tests/ui/resolve/ice-inconsistent-resolution-151213.stderr new file mode 100644 index 000000000000..deb1e6c3e1cf --- /dev/null +++ b/tests/ui/resolve/ice-inconsistent-resolution-151213.stderr @@ -0,0 +1,14 @@ +error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` + --> $DIR/ice-inconsistent-resolution-151213.rs:5:1 + | +LL | extern crate core as std; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot find attribute `attr` in this scope + --> $DIR/ice-inconsistent-resolution-151213.rs:3:3 + | +LL | #[attr] + | ^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/resolve/impl-items-vis-unresolved.rs b/tests/ui/resolve/impl-items-vis-unresolved.rs index 1494c1cf9680..bbdc8170d4f6 100644 --- a/tests/ui/resolve/impl-items-vis-unresolved.rs +++ b/tests/ui/resolve/impl-items-vis-unresolved.rs @@ -19,7 +19,7 @@ pub struct RawFloatState; impl RawFloatState { perftools_inline! { pub(super) fn new() {} - //~^ ERROR failed to resolve: there are too many leading `super` keywords + //~^ ERROR: too many leading `super` keywords } } diff --git a/tests/ui/resolve/impl-items-vis-unresolved.stderr b/tests/ui/resolve/impl-items-vis-unresolved.stderr index cccffdcbf541..e433cb607cda 100644 --- a/tests/ui/resolve/impl-items-vis-unresolved.stderr +++ b/tests/ui/resolve/impl-items-vis-unresolved.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: too many leading `super` keywords --> $DIR/impl-items-vis-unresolved.rs:21:13 | LL | pub(super) fn new() {} diff --git a/tests/ui/resolve/impl-on-non-type.rs b/tests/ui/resolve/impl-on-non-type.rs new file mode 100644 index 000000000000..3db13d520f9f --- /dev/null +++ b/tests/ui/resolve/impl-on-non-type.rs @@ -0,0 +1,13 @@ +//! regression test for +const X: u8 = 1; +static Y: u8 = 1; +fn foo() {} + +impl X {} +//~^ ERROR expected type, found constant `X` +impl Y {} +//~^ ERROR expected type, found static `Y` +impl foo {} +//~^ ERROR expected type, found function `foo` + +fn main() {} diff --git a/tests/ui/resolve/impl-on-non-type.stderr b/tests/ui/resolve/impl-on-non-type.stderr new file mode 100644 index 000000000000..99cc405015b5 --- /dev/null +++ b/tests/ui/resolve/impl-on-non-type.stderr @@ -0,0 +1,21 @@ +error[E0573]: expected type, found constant `X` + --> $DIR/impl-on-non-type.rs:6:6 + | +LL | impl X {} + | ^ not a type + +error[E0573]: expected type, found static `Y` + --> $DIR/impl-on-non-type.rs:8:6 + | +LL | impl Y {} + | ^ not a type + +error[E0573]: expected type, found function `foo` + --> $DIR/impl-on-non-type.rs:10:6 + | +LL | impl foo {} + | ^^^ not a type + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/resolve/issue-101749-2.rs b/tests/ui/resolve/issue-101749-2.rs index 636ff07c71ce..60846713f63f 100644 --- a/tests/ui/resolve/issue-101749-2.rs +++ b/tests/ui/resolve/issue-101749-2.rs @@ -12,5 +12,5 @@ fn main() { let rect = Rectangle::new(3, 4); // `area` is not implemented for `Rectangle`, so this should not suggest let _ = rect::area(); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `rect` + //~^ ERROR: cannot find module or crate `rect` } diff --git a/tests/ui/resolve/issue-101749-2.stderr b/tests/ui/resolve/issue-101749-2.stderr index 96a20b4bf5a0..f8ed9ceb830d 100644 --- a/tests/ui/resolve/issue-101749-2.stderr +++ b/tests/ui/resolve/issue-101749-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `rect` +error[E0433]: cannot find module or crate `rect` in this scope --> $DIR/issue-101749-2.rs:14:13 | LL | let _ = rect::area(); diff --git a/tests/ui/resolve/issue-101749.fixed b/tests/ui/resolve/issue-101749.fixed index 3244ad7a0313..ebd6533fe0e0 100644 --- a/tests/ui/resolve/issue-101749.fixed +++ b/tests/ui/resolve/issue-101749.fixed @@ -15,5 +15,5 @@ impl Rectangle { fn main() { let rect = Rectangle::new(3, 4); let _ = rect.area(); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `rect` + //~^ ERROR: cannot find module or crate `rect` } diff --git a/tests/ui/resolve/issue-101749.rs b/tests/ui/resolve/issue-101749.rs index c977df41d2f5..4c1a2e0f4403 100644 --- a/tests/ui/resolve/issue-101749.rs +++ b/tests/ui/resolve/issue-101749.rs @@ -15,5 +15,5 @@ impl Rectangle { fn main() { let rect = Rectangle::new(3, 4); let _ = rect::area(); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `rect` + //~^ ERROR: cannot find module or crate `rect` } diff --git a/tests/ui/resolve/issue-101749.stderr b/tests/ui/resolve/issue-101749.stderr index 09e800ec7c31..8a508f590161 100644 --- a/tests/ui/resolve/issue-101749.stderr +++ b/tests/ui/resolve/issue-101749.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `rect` +error[E0433]: cannot find module or crate `rect` in this scope --> $DIR/issue-101749.rs:17:13 | LL | let _ = rect::area(); diff --git a/tests/ui/resolve/issue-10200.stderr b/tests/ui/resolve/issue-10200.stderr index 4b6d9b6f1dfa..62731960191f 100644 --- a/tests/ui/resolve/issue-10200.stderr +++ b/tests/ui/resolve/issue-10200.stderr @@ -5,9 +5,14 @@ LL | struct Foo(bool); | ----------------- similarly named tuple struct `Foo` defined here ... LL | foo(x) - | ^^^ help: a tuple struct with a similar name exists (notice the capitalization): `Foo` + | ^^^ | = note: function calls are not allowed in patterns: +help: a tuple struct with a similar name exists (notice the capitalization) + | +LL - foo(x) +LL + Foo(x) + | error: aborting due to 1 previous error diff --git a/tests/ui/resolve/issue-109250.rs b/tests/ui/resolve/issue-109250.rs index 68e33f693cef..99fcae9647bf 100644 --- a/tests/ui/resolve/issue-109250.rs +++ b/tests/ui/resolve/issue-109250.rs @@ -1,3 +1,3 @@ fn main() { //~ HELP consider importing - HashMap::new; //~ ERROR failed to resolve: use of undeclared type `HashMap` + HashMap::new; //~ ERROR cannot find type `HashMap` } diff --git a/tests/ui/resolve/issue-109250.stderr b/tests/ui/resolve/issue-109250.stderr index ad6cc6986229..d631232f73bf 100644 --- a/tests/ui/resolve/issue-109250.stderr +++ b/tests/ui/resolve/issue-109250.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `HashMap` +error[E0433]: cannot find type `HashMap` in this scope --> $DIR/issue-109250.rs:2:5 | LL | HashMap::new; diff --git a/tests/ui/resolve/issue-117920.rs b/tests/ui/resolve/issue-117920.rs index 928f194c59c3..6fbc412001f5 100644 --- a/tests/ui/resolve/issue-117920.rs +++ b/tests/ui/resolve/issue-117920.rs @@ -1,6 +1,6 @@ #![crate_type = "lib"] -use super::A; //~ ERROR failed to resolve +use super::A; //~ ERROR too many leading `super` keywords mod b { pub trait A {} diff --git a/tests/ui/resolve/issue-117920.stderr b/tests/ui/resolve/issue-117920.stderr index c4528d467e9f..810c2c06efe7 100644 --- a/tests/ui/resolve/issue-117920.stderr +++ b/tests/ui/resolve/issue-117920.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: too many leading `super` keywords --> $DIR/issue-117920.rs:3:5 | LL | use super::A; diff --git a/tests/ui/resolve/issue-24968.rs b/tests/ui/resolve/issue-24968.rs index 19e16abcee3c..22f5ea520467 100644 --- a/tests/ui/resolve/issue-24968.rs +++ b/tests/ui/resolve/issue-24968.rs @@ -19,12 +19,12 @@ const FOO: Self = 0; //~^ ERROR cannot find type `Self` const FOO2: u32 = Self::bar(); -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find `Self` static FOO_S: Self = 0; //~^ ERROR cannot find type `Self` static FOO_S2: u32 = Self::bar(); -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find `Self` fn main() {} diff --git a/tests/ui/resolve/issue-24968.stderr b/tests/ui/resolve/issue-24968.stderr index 82f5a1d5b57b..ce8ded2714f4 100644 --- a/tests/ui/resolve/issue-24968.stderr +++ b/tests/ui/resolve/issue-24968.stderr @@ -39,13 +39,13 @@ LL | static FOO_S: Self = 0; | | | `Self` not allowed in a static item -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find `Self` in this scope --> $DIR/issue-24968.rs:21:19 | LL | const FOO2: u32 = Self::bar(); | ^^^^ `Self` is only available in impls, traits, and type definitions -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find `Self` in this scope --> $DIR/issue-24968.rs:27:22 | LL | static FOO_S2: u32 = Self::bar(); diff --git a/tests/ui/resolve/issue-49074.stderr b/tests/ui/resolve/issue-49074.stderr index bbfeb4ea9483..16a4ede0c0b5 100644 --- a/tests/ui/resolve/issue-49074.stderr +++ b/tests/ui/resolve/issue-49074.stderr @@ -10,7 +10,13 @@ error: cannot find attribute `marco_use` in this scope --> $DIR/issue-49074.rs:3:3 | LL | #[marco_use] // typo - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use` + | ^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL - #[marco_use] // typo +LL + #[macro_use] // typo + | error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-81508.rs b/tests/ui/resolve/issue-81508.rs index 23605cd2fd91..96d5f52feba0 100644 --- a/tests/ui/resolve/issue-81508.rs +++ b/tests/ui/resolve/issue-81508.rs @@ -8,7 +8,7 @@ fn main() { let Baz: &str = ""; - println!("{}", Baz::Bar); //~ ERROR: failed to resolve: use of undeclared type `Baz` + println!("{}", Baz::Bar); //~ ERROR: cannot find type `Baz` } #[allow(non_upper_case_globals)] @@ -17,6 +17,6 @@ pub const Foo: &str = ""; mod submod { use super::Foo; fn function() { - println!("{}", Foo::Bar); //~ ERROR: failed to resolve: use of undeclared type `Foo` + println!("{}", Foo::Bar); //~ ERROR: cannot find type `Foo` } } diff --git a/tests/ui/resolve/issue-81508.stderr b/tests/ui/resolve/issue-81508.stderr index 7258174ba89b..49fe9fbf6211 100644 --- a/tests/ui/resolve/issue-81508.stderr +++ b/tests/ui/resolve/issue-81508.stderr @@ -1,20 +1,14 @@ -error[E0433]: failed to resolve: use of undeclared type `Baz` +error[E0433]: cannot find type `Baz` in this scope --> $DIR/issue-81508.rs:11:20 | -LL | let Baz: &str = ""; - | --- help: `Baz` is defined here, but is not a type -LL | LL | println!("{}", Baz::Bar); - | ^^^ use of undeclared type `Baz` + | ^^^ `Baz` is declared as a local binding at `issue-81508.rs:9:9`, not a type -error[E0433]: failed to resolve: use of undeclared type `Foo` +error[E0433]: cannot find type `Foo` in this scope --> $DIR/issue-81508.rs:20:24 | -LL | use super::Foo; - | ---------- help: `Foo` is defined here, but is not a type -LL | fn function() { LL | println!("{}", Foo::Bar); - | ^^^ use of undeclared type `Foo` + | ^^^ `Foo` is declared as a constant at `issue-81508.rs:18:9`, not a type error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-82156.rs b/tests/ui/resolve/issue-82156.rs index 6215259e4865..fc6840faf636 100644 --- a/tests/ui/resolve/issue-82156.rs +++ b/tests/ui/resolve/issue-82156.rs @@ -1,3 +1,3 @@ fn main() { - super(); //~ ERROR failed to resolve: there are too many leading `super` keywords + super(); //~ ERROR: too many leading `super` keywords } diff --git a/tests/ui/resolve/issue-82156.stderr b/tests/ui/resolve/issue-82156.stderr index 3894b9573a45..6fe0d4c4ea15 100644 --- a/tests/ui/resolve/issue-82156.stderr +++ b/tests/ui/resolve/issue-82156.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: there are too many leading `super` keywords +error[E0433]: too many leading `super` keywords --> $DIR/issue-82156.rs:2:5 | LL | super(); diff --git a/tests/ui/resolve/issue-82865.rs b/tests/ui/resolve/issue-82865.rs index 30084b133e0f..545ca63e0b82 100644 --- a/tests/ui/resolve/issue-82865.rs +++ b/tests/ui/resolve/issue-82865.rs @@ -3,7 +3,7 @@ #![feature(decl_macro)] -use x::y::z; //~ ERROR: failed to resolve: use of unresolved module or unlinked crate `x` +use x::y::z; //~ ERROR: cannot find module or crate `x` macro mac () { Box::z //~ ERROR: no function or associated item diff --git a/tests/ui/resolve/issue-82865.stderr b/tests/ui/resolve/issue-82865.stderr index c9184bafd4c9..90059ad5a965 100644 --- a/tests/ui/resolve/issue-82865.stderr +++ b/tests/ui/resolve/issue-82865.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `x` +error[E0433]: cannot find module or crate `x` in the crate root --> $DIR/issue-82865.rs:6:5 | LL | use x::y::z; diff --git a/tests/ui/resolve/levenshtein.stderr b/tests/ui/resolve/levenshtein.stderr index 7a1abd134330..48515b9e6bd5 100644 --- a/tests/ui/resolve/levenshtein.stderr +++ b/tests/ui/resolve/levenshtein.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find type `esize` in this scope --> $DIR/levenshtein.rs:5:11 | LL | fn foo(c: esize) {} // Misspelled primitive type name. - | ^^^^^ help: a builtin type with a similar name exists: `isize` + | ^^^^^ + | +help: a builtin type with a similar name exists + | +LL - fn foo(c: esize) {} // Misspelled primitive type name. +LL + fn foo(c: isize) {} // Misspelled primitive type name. + | error[E0425]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:10:10 @@ -11,17 +17,28 @@ LL | enum Bar { } | -------- similarly named enum `Bar` defined here LL | LL | type A = Baz; // Misspelled type name. - | ^^^ help: an enum with a similar name exists: `Bar` + | ^^^ + | +help: an enum with a similar name exists + | +LL - type A = Baz; // Misspelled type name. +LL + type A = Bar; // Misspelled type name. + | error[E0425]: cannot find type `Opiton` in this scope --> $DIR/levenshtein.rs:12:10 | LL | type B = Opiton; // Misspelled type name from the prelude. - | ^^^^^^ help: an enum with a similar name exists: `Option` + | ^^^^^^ | --> $SRC_DIR/core/src/option.rs:LL:COL | = note: similarly named enum `Option` defined here +help: an enum with a similar name exists + | +LL - type B = Opiton; // Misspelled type name from the prelude. +LL + type B = Option; // Misspelled type name from the prelude. + | error[E0425]: cannot find type `Baz` in this scope --> $DIR/levenshtein.rs:16:14 @@ -36,7 +53,12 @@ LL | const MAX_ITEM: usize = 10; | --------------------------- similarly named constant `MAX_ITEM` defined here ... LL | let v = [0u32; MAXITEM]; // Misspelled constant name. - | ^^^^^^^ help: a constant with a similar name exists: `MAX_ITEM` + | ^^^^^^^ + | +help: a constant with a similar name exists + | +LL | let v = [0u32; MAX_ITEM]; // Misspelled constant name. + | + error[E0425]: cannot find type `first` in module `m` --> $DIR/levenshtein.rs:28:15 @@ -45,7 +67,13 @@ LL | pub struct First; | ----------------- similarly named struct `First` defined here ... LL | let b: m::first = m::second; // Misspelled item in module. - | ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First` + | ^^^^^ + | +help: a struct with a similar name exists (notice the capitalization) + | +LL - let b: m::first = m::second; // Misspelled item in module. +LL + let b: m::First = m::second; // Misspelled item in module. + | error[E0425]: cannot find value `second` in module `m` --> $DIR/levenshtein.rs:28:26 @@ -54,7 +82,13 @@ LL | pub struct Second; | ------------------ similarly named unit struct `Second` defined here ... LL | let b: m::first = m::second; // Misspelled item in module. - | ^^^^^^ help: a unit struct with a similar name exists (notice the capitalization): `Second` + | ^^^^^^ + | +help: a unit struct with a similar name exists (notice the capitalization) + | +LL - let b: m::first = m::second; // Misspelled item in module. +LL + let b: m::first = m::Second; // Misspelled item in module. + | error[E0425]: cannot find function `foobar` in this scope --> $DIR/levenshtein.rs:26:5 @@ -63,7 +97,12 @@ LL | fn foo_bar() {} | ------------ similarly named function `foo_bar` defined here ... LL | foobar(); // Misspelled function name. - | ^^^^^^ help: a function with a similar name exists: `foo_bar` + | ^^^^^^ + | +help: a function with a similar name exists + | +LL | foo_bar(); // Misspelled function name. + | + error: aborting due to 8 previous errors diff --git a/tests/ui/resolve/missing-associated-items.rs b/tests/ui/resolve/missing-associated-items.rs new file mode 100644 index 000000000000..72d6cbb3f149 --- /dev/null +++ b/tests/ui/resolve/missing-associated-items.rs @@ -0,0 +1,21 @@ +//! regression test for issue +enum Token { + LeftParen, + RightParen, + Plus, + Minus, /* etc */ +} +struct Struct { + a: usize, +} + +fn use_token(token: &Token) { + unimplemented!() +} + +fn main() { + use_token(&Token::Homura); //~ ERROR no variant or associated item named `Homura` + Struct::method(); //~ ERROR no function or associated item named `method` found + Struct::method; //~ ERROR no function or associated item named `method` found + Struct::Assoc; //~ ERROR no associated item named `Assoc` found +} diff --git a/tests/ui/resolve/missing-associated-items.stderr b/tests/ui/resolve/missing-associated-items.stderr new file mode 100644 index 000000000000..d27a3a644aee --- /dev/null +++ b/tests/ui/resolve/missing-associated-items.stderr @@ -0,0 +1,39 @@ +error[E0599]: no variant or associated item named `Homura` found for enum `Token` in the current scope + --> $DIR/missing-associated-items.rs:17:23 + | +LL | enum Token { + | ---------- variant or associated item `Homura` not found for this enum +... +LL | use_token(&Token::Homura); + | ^^^^^^ variant or associated item not found in `Token` + +error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope + --> $DIR/missing-associated-items.rs:18:13 + | +LL | struct Struct { + | ------------- function or associated item `method` not found for this struct +... +LL | Struct::method(); + | ^^^^^^ function or associated item not found in `Struct` + +error[E0599]: no function or associated item named `method` found for struct `Struct` in the current scope + --> $DIR/missing-associated-items.rs:19:13 + | +LL | struct Struct { + | ------------- function or associated item `method` not found for this struct +... +LL | Struct::method; + | ^^^^^^ function or associated item not found in `Struct` + +error[E0599]: no associated item named `Assoc` found for struct `Struct` in the current scope + --> $DIR/missing-associated-items.rs:20:13 + | +LL | struct Struct { + | ------------- associated item `Assoc` not found for this struct +... +LL | Struct::Assoc; + | ^^^^^ associated item not found in `Struct` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/resolve/missing-in-namespace.rs b/tests/ui/resolve/missing-in-namespace.rs index e1dedb072b77..f54d478eb03a 100644 --- a/tests/ui/resolve/missing-in-namespace.rs +++ b/tests/ui/resolve/missing-in-namespace.rs @@ -1,4 +1,4 @@ fn main() { let _map = std::hahmap::HashMap::new(); - //~^ ERROR failed to resolve: could not find `hahmap` in `std + //~^ ERROR: cannot find `hahmap` in `std } diff --git a/tests/ui/resolve/missing-in-namespace.stderr b/tests/ui/resolve/missing-in-namespace.stderr index 35585e4240a2..cefcc097b1db 100644 --- a/tests/ui/resolve/missing-in-namespace.stderr +++ b/tests/ui/resolve/missing-in-namespace.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `hahmap` in `std` +error[E0433]: cannot find `hahmap` in `std` --> $DIR/missing-in-namespace.rs:2:21 | LL | let _map = std::hahmap::HashMap::new(); diff --git a/tests/ui/resolve/module-used-as-struct-constructor.rs b/tests/ui/resolve/module-used-as-struct-constructor.rs new file mode 100644 index 000000000000..bdc7b2bf5841 --- /dev/null +++ b/tests/ui/resolve/module-used-as-struct-constructor.rs @@ -0,0 +1,6 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17001, https://github.com/rust-lang/rust/issues/21449, https://github.com/rust-lang/rust/issues/23189 +mod foo {} + +fn main() { + let p = foo { x: () }; //~ ERROR expected struct, variant or union type, found module `foo` +} diff --git a/tests/ui/resolve/module-used-as-struct-constructor.stderr b/tests/ui/resolve/module-used-as-struct-constructor.stderr new file mode 100644 index 000000000000..b94a28762a7f --- /dev/null +++ b/tests/ui/resolve/module-used-as-struct-constructor.stderr @@ -0,0 +1,9 @@ +error[E0574]: expected struct, variant or union type, found module `foo` + --> $DIR/module-used-as-struct-constructor.rs:5:13 + | +LL | let p = foo { x: () }; + | ^^^ not a struct, variant or union type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0574`. diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs index 519b989fbe87..9f1bff51a3d4 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.rs +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs @@ -7,6 +7,7 @@ //@ normalize-stderr: "note: .*\n\n" -> "" //@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ rustc-env:RUST_BACKTRACE=0 #[repr(packed)] diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr index 10ce68e506e6..b8b33e3417bf 100644 --- a/tests/ui/resolve/multiple_definitions_attribute_merging.stderr +++ b/tests/ui/resolve/multiple_definitions_attribute_merging.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Dealigned` is defined multiple times - --> $DIR/multiple_definitions_attribute_merging.rs:17:1 + --> $DIR/multiple_definitions_attribute_merging.rs:18:1 | LL | struct Dealigned(u8, T); | --------------------------- previous definition of the type `Dealigned` here @@ -8,7 +8,7 @@ LL | struct Dealigned(u8, T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Dealigned` redefined here | = error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference - --> $DIR/multiple_definitions_attribute_merging.rs:17:25 + --> $DIR/multiple_definitions_attribute_merging.rs:18:25 | LL | #[derive(PartialEq)] | --------- in this derive macro expansion @@ -19,8 +19,8 @@ LL | struct Dealigned(u8, T); Box query stack during panic: -#0 [mir_built] building MIR for `::eq` -#1 [check_unsafety] unsafety-checking `::eq` +#0 [mir_built] building MIR for `::eq` +#1 [check_unsafety] unsafety-checking `::eq` ... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/prelude-order.rs b/tests/ui/resolve/prelude-order.rs index c6683bdff22a..9bc3793dbf20 100644 --- a/tests/ui/resolve/prelude-order.rs +++ b/tests/ui/resolve/prelude-order.rs @@ -59,7 +59,7 @@ extern crate macro_helpers as _; /* lang and libs implicitly in scope */ // tool/extern -> extern -#[type_ns::inner] //~ ERROR could not find `inner` in `type_ns` +#[type_ns::inner] //~ ERROR cannot find `inner` in `type_ns` fn t1() {} // tool/lang -> tool @@ -71,7 +71,7 @@ fn t2() {} fn t3() {} // extern/lang -> extern -#[usize::inner] //~ ERROR could not find `inner` in `usize` +#[usize::inner] //~ ERROR cannot find `inner` in `usize` fn e1() {} // NOTE: testing with `-> usize` isn't valid, crates aren't considered in that scope // (unless they have generic arguments, for some reason.) diff --git a/tests/ui/resolve/prelude-order.stderr b/tests/ui/resolve/prelude-order.stderr index 4dad39fb6d24..c7929bf74d51 100644 --- a/tests/ui/resolve/prelude-order.stderr +++ b/tests/ui/resolve/prelude-order.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: could not find `inner` in `type_ns` +error[E0433]: cannot find `inner` in `type_ns` --> $DIR/prelude-order.rs:62:12 | LL | #[type_ns::inner] | ^^^^^ could not find `inner` in `type_ns` -error[E0433]: failed to resolve: could not find `inner` in `usize` +error[E0433]: cannot find `inner` in `usize` --> $DIR/prelude-order.rs:74:10 | LL | #[usize::inner] diff --git a/tests/ui/resolve/privacy-enum-ctor.stderr b/tests/ui/resolve/privacy-enum-ctor.stderr index 81356c5040f8..5349108065dc 100644 --- a/tests/ui/resolve/privacy-enum-ctor.stderr +++ b/tests/ui/resolve/privacy-enum-ctor.stderr @@ -149,13 +149,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z; +LL + let _: E = m::n::Z; + | error[E0423]: expected value, found enum `m::n::Z` --> $DIR/privacy-enum-ctor.rs:58:16 @@ -192,13 +197,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z::Fn; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z::Fn; +LL + let _: E = m::n::Z::Fn; + | error[E0425]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:65:12 @@ -207,13 +217,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z::Struct; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z::Struct; +LL + let _: E = m::n::Z::Struct; + | error[E0425]: cannot find type `Z` in this scope --> $DIR/privacy-enum-ctor.rs:69:12 @@ -222,13 +237,18 @@ LL | pub enum E { | ---------- similarly named enum `E` defined here ... LL | let _: Z = m::n::Z::Unit {}; - | ^ help: an enum with a similar name exists: `E` + | ^ | note: enum `m::Z` exists but is inaccessible --> $DIR/privacy-enum-ctor.rs:12:9 | LL | pub(in crate::m) enum Z { | ^^^^^^^^^^^^^^^^^^^^^^^ not accessible +help: an enum with a similar name exists + | +LL - let _: Z = m::n::Z::Unit {}; +LL + let _: E = m::n::Z::Unit {}; + | error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:58:22 diff --git a/tests/ui/resolve/privacy-struct-ctor.stderr b/tests/ui/resolve/privacy-struct-ctor.stderr index 96c3e6e5122d..5a01d51d24ff 100644 --- a/tests/ui/resolve/privacy-struct-ctor.stderr +++ b/tests/ui/resolve/privacy-struct-ctor.stderr @@ -5,10 +5,13 @@ LL | pub struct S(u8); | ----------------- similarly named tuple struct `S` defined here ... LL | Z; - | ^ - | | - | constructor is not visible here due to private fields - | help: a tuple struct with a similar name exists: `S` + | ^ constructor is not visible here due to private fields + | +help: a tuple struct with a similar name exists + | +LL - Z; +LL + S; + | error[E0423]: expected value, found struct `S` --> $DIR/privacy-struct-ctor.rs:34:5 diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs index 41236c732bbd..a8175895af04 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.rs +++ b/tests/ui/resolve/proc_macro_generated_packed.rs @@ -7,6 +7,7 @@ //@ normalize-stderr: "note: .*\n\n" -> "" //@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" //@ rustc-env:RUST_BACKTRACE=0 extern crate proc_macro_generate_packed; diff --git a/tests/ui/resolve/proc_macro_generated_packed.stderr b/tests/ui/resolve/proc_macro_generated_packed.stderr index 47de5be82ddf..d8e160d0c6a0 100644 --- a/tests/ui/resolve/proc_macro_generated_packed.stderr +++ b/tests/ui/resolve/proc_macro_generated_packed.stderr @@ -1,5 +1,5 @@ error: internal compiler error: compiler/rustc_mir_transform/src/check_packed_ref.rs:LL:CC: builtin derive created an unaligned reference - --> $DIR/proc_macro_generated_packed.rs:18:25 + --> $DIR/proc_macro_generated_packed.rs:19:25 | LL | #[derive(PartialEq)] | --------- in this derive macro expansion @@ -10,8 +10,8 @@ LL | struct Dealigned(u8, T); Box query stack during panic: -#0 [mir_built] building MIR for `::eq` -#1 [check_unsafety] unsafety-checking `::eq` +#0 [mir_built] building MIR for `::eq` +#1 [check_unsafety] unsafety-checking `::eq` ... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack error: aborting due to 1 previous error diff --git a/tests/ui/resolve/query-cycle-issue-124901.rs b/tests/ui/resolve/query-cycle-issue-124901.rs new file mode 100644 index 000000000000..6cb1e58b6258 --- /dev/null +++ b/tests/ui/resolve/query-cycle-issue-124901.rs @@ -0,0 +1,24 @@ +//~ ERROR: cycle detected when looking up span for `Default` +trait Default { + type Id; + + fn intu(&self) -> &Self::Id; +} + +impl, U: Copy> Default for U { + default type Id = T; + fn intu(&self) -> &Self::Id { + self + } +} + +fn specialization(t: T) -> U { + *t.intu() +} + +use std::num::NonZero; + +fn main() { + let assert_eq = NonZero::>>(0); + assert_eq!(specialization, None); +} diff --git a/tests/ui/resolve/query-cycle-issue-124901.stderr b/tests/ui/resolve/query-cycle-issue-124901.stderr new file mode 100644 index 000000000000..9c1d7b1de33a --- /dev/null +++ b/tests/ui/resolve/query-cycle-issue-124901.stderr @@ -0,0 +1,9 @@ +error[E0391]: cycle detected when looking up span for `Default` + | + = note: ...which immediately requires looking up span for `Default` again + = note: cycle used when perform lints prior to AST lowering + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr index ef519ac0d921..e6311962884f 100644 --- a/tests/ui/resolve/resolve-assoc-suggestions.stderr +++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr @@ -31,18 +31,32 @@ help: you might have meant to use the associated type | LL | let _: Self::Type; | ++++++ +help: consider importing this struct + | +LL + use std::mem::type_info::Type; + | error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:25:13 | LL | let Type(..); | ^^^^ not found in this scope + | +help: consider importing this tuple variant + | +LL + use std::mem::type_info::Generic::Type; + | error[E0425]: cannot find value `Type` in this scope --> $DIR/resolve-assoc-suggestions.rs:27:9 | LL | Type; | ^^^^ not found in this scope + | +help: consider importing this tuple variant + | +LL + use std::mem::type_info::Generic::Type; + | error[E0425]: cannot find type `method` in this scope --> $DIR/resolve-assoc-suggestions.rs:30:16 diff --git a/tests/ui/resolve/resolve-bad-visibility.rs b/tests/ui/resolve/resolve-bad-visibility.rs index 81635611fca9..55e381e8be1a 100644 --- a/tests/ui/resolve/resolve-bad-visibility.rs +++ b/tests/ui/resolve/resolve-bad-visibility.rs @@ -5,8 +5,8 @@ trait Tr {} pub(in E) struct S; //~ ERROR expected module, found enum `E` pub(in Tr) struct Z; //~ ERROR expected module, found trait `Tr` pub(in std::vec) struct F; //~ ERROR visibilities can only be restricted to ancestor modules -pub(in nonexistent) struct G; //~ ERROR failed to resolve -pub(in too_soon) struct H; //~ ERROR failed to resolve +pub(in nonexistent) struct G; //~ ERROR cannot find +pub(in too_soon) struct H; //~ ERROR cannot find // Visibilities are resolved eagerly without waiting for modules becoming fully populated. // Visibilities can only use ancestor modules legally which are always available in time, diff --git a/tests/ui/resolve/resolve-bad-visibility.stderr b/tests/ui/resolve/resolve-bad-visibility.stderr index c7bbdfbd2495..4530757c3de5 100644 --- a/tests/ui/resolve/resolve-bad-visibility.stderr +++ b/tests/ui/resolve/resolve-bad-visibility.stderr @@ -16,7 +16,7 @@ error[E0742]: visibilities can only be restricted to ancestor modules LL | pub(in std::vec) struct F; | ^^^^^^^^ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nonexistent` +error[E0433]: cannot find module or crate `nonexistent` in the crate root --> $DIR/resolve-bad-visibility.rs:8:8 | LL | pub(in nonexistent) struct G; @@ -27,7 +27,7 @@ help: you might be missing a crate named `nonexistent`, add it to your project a LL + extern crate nonexistent; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `too_soon` +error[E0433]: cannot find module or crate `too_soon` in the crate root --> $DIR/resolve-bad-visibility.rs:9:8 | LL | pub(in too_soon) struct H; diff --git a/tests/ui/resolve/resolve-variant-assoc-item.rs b/tests/ui/resolve/resolve-variant-assoc-item.rs index 7671dddc819b..edf97daa172a 100644 --- a/tests/ui/resolve/resolve-variant-assoc-item.rs +++ b/tests/ui/resolve/resolve-variant-assoc-item.rs @@ -3,6 +3,6 @@ enum E { V } use E::V; fn main() { - E::V::associated_item; //~ ERROR failed to resolve: `V` is a variant, not a module - V::associated_item; //~ ERROR failed to resolve: `V` is a variant, not a module + E::V::associated_item; //~ ERROR: cannot find + V::associated_item; //~ ERROR: cannot find } diff --git a/tests/ui/resolve/resolve-variant-assoc-item.stderr b/tests/ui/resolve/resolve-variant-assoc-item.stderr index 5528bb2495b5..460cea2dfb91 100644 --- a/tests/ui/resolve/resolve-variant-assoc-item.stderr +++ b/tests/ui/resolve/resolve-variant-assoc-item.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `V` is a variant, not a module +error[E0433]: cannot find module `V` in `E` --> $DIR/resolve-variant-assoc-item.rs:6:8 | LL | E::V::associated_item; @@ -10,7 +10,7 @@ LL - E::V::associated_item; LL + E::associated_item; | -error[E0433]: failed to resolve: `V` is a variant, not a module +error[E0433]: cannot find module `V` in this scope --> $DIR/resolve-variant-assoc-item.rs:7:5 | LL | V::associated_item; diff --git a/tests/ui/resolve/shadow-primitives.rs b/tests/ui/resolve/shadow-primitives.rs new file mode 100644 index 000000000000..17da0cd0530c --- /dev/null +++ b/tests/ui/resolve/shadow-primitives.rs @@ -0,0 +1,91 @@ +//! regression test for +//@ run-pass +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_imports)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(deprecated, deprecated_in_future)] + +//@ aux-build:i8.rs + +extern crate i8; +use std::string as i16; +static i32: i32 = 0; +const i64: i64 = 0; +fn u8(f32: f32) {} +fn f(f64: f64) {} +enum u32 {} +struct u64; +trait bool {} + +mod char { + extern crate i8; + static i32_: i32 = 0; + const i64_: i64 = 0; + fn u8_(f32: f32) {} + fn f_(f64: f64_) {} + type u16_ = u16; + enum u32_ {} + struct u64_; + trait bool_ {} + mod char_ {} + + mod str { + use super::{ + bool_ as bool, bool_ as str, char_ as char, f_ as f64, i8, i32_ as i32, i64_ as i64, + u8_ as u8, u16_ as u16, u32_ as u32, u64_ as u64, + }; + } +} + +trait isize_ { + type isize; +} + +fn usize<'usize>(usize: &'usize usize) -> &'usize usize { + usize +} + +mod reuse { + use std::mem::size_of; + + type u8 = u64; + use std::string::String as i16; + + pub fn check() { + assert_eq!(size_of::(), 8); + assert_eq!(size_of::(), 0); + assert_eq!(size_of::(), 3 * size_of::<*const ()>()); + assert_eq!(size_of::(), 0); + } +} + +mod guard { + pub fn check() { + use std::u8; // bring module u8 in scope + fn f() -> u8 { + // OK, resolves to primitive u8, not to std::u8 + u8::max_value() // OK, resolves to associated function ::max_value, + // not to non-existent std::u8::max_value + } + assert_eq!(f(), u8::MAX); // OK, resolves to std::u8::MAX + } +} + +fn main() { + let bool = true; + let _ = match bool { + str @ true => { + if str { + i32 as i64 + } else { + i64 + } + } + false => i64, + }; + + reuse::check::(); + guard::check(); +} diff --git a/tests/ui/resolve/struct-function-same-name-2445.rs b/tests/ui/resolve/struct-function-same-name-2445.rs new file mode 100644 index 000000000000..8a0490efa3aa --- /dev/null +++ b/tests/ui/resolve/struct-function-same-name-2445.rs @@ -0,0 +1,26 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2445 + +//@ run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +struct c1 { + x: T, +} + +impl c1 { + pub fn f1(&self, _x: T) {} +} + +fn c1(x: T) -> c1 { + c1 { x } +} + +impl c1 { + pub fn f2(&self, _x: T) {} +} + +pub fn main() { + c1::(3).f1(4); + c1::(3).f2(4); +} diff --git a/tests/ui/resolve/struct-function-same-name-2487.rs b/tests/ui/resolve/struct-function-same-name-2487.rs new file mode 100644 index 000000000000..5f9a61c3260b --- /dev/null +++ b/tests/ui/resolve/struct-function-same-name-2487.rs @@ -0,0 +1,32 @@ +//@ build-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +struct socket { + sock: isize, +} + +impl Drop for socket { + fn drop(&mut self) {} +} + +impl socket { + pub fn set_identity(&self) { + closure(|| setsockopt_bytes(self.sock.clone())) + } +} + +fn socket() -> socket { + socket { sock: 1 } +} + +fn closure(f: F) +where + F: FnOnce(), +{ + f() +} + +fn setsockopt_bytes(_sock: isize) {} + +pub fn main() {} diff --git a/tests/ui/resolve/struct-function-same-name-2502.rs b/tests/ui/resolve/struct-function-same-name-2502.rs new file mode 100644 index 000000000000..5305c7d0a96f --- /dev/null +++ b/tests/ui/resolve/struct-function-same-name-2502.rs @@ -0,0 +1,21 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2502 + +//@ check-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +struct font<'a> { + fontbuf: &'a Vec, +} + +impl<'a> font<'a> { + pub fn buf(&self) -> &'a Vec { + self.fontbuf + } +} + +fn font(fontbuf: &Vec) -> font<'_> { + font { fontbuf } +} + +pub fn main() {} diff --git a/tests/ui/resolve/struct-function-same-name-2550.rs b/tests/ui/resolve/struct-function-same-name-2550.rs new file mode 100644 index 000000000000..c96f58374c6d --- /dev/null +++ b/tests/ui/resolve/struct-function-same-name-2550.rs @@ -0,0 +1,19 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2550 + +//@ run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +struct C { + x: usize, +} + +fn C(x: usize) -> C { + C { x } +} + +fn f(_x: T) {} + +pub fn main() { + f(C(1)); +} diff --git a/tests/ui/resolve/struct-function-same-name-2708.rs b/tests/ui/resolve/struct-function-same-name-2708.rs new file mode 100644 index 000000000000..729a5819ae4e --- /dev/null +++ b/tests/ui/resolve/struct-function-same-name-2708.rs @@ -0,0 +1,23 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2708 + +//@ run-pass +#![allow(dead_code)] +#![allow(non_snake_case)] + +struct Font { + fontbuf: usize, + cairo_font: usize, + font_dtor: usize, +} + +impl Drop for Font { + fn drop(&mut self) {} +} + +fn Font() -> Font { + Font { fontbuf: 0, cairo_font: 0, font_dtor: 0 } +} + +pub fn main() { + let _f: Box<_> = Box::new(Font()); +} diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.rs b/tests/ui/resolve/suggest-range-struct-destructuring.rs new file mode 100644 index 000000000000..ee8a99ceaa1a --- /dev/null +++ b/tests/ui/resolve/suggest-range-struct-destructuring.rs @@ -0,0 +1,40 @@ +use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive}; + +fn test_range(r: Range) { + let start..end = r; + //~^ ERROR cannot find value `start` + //~| ERROR cannot find value `end` +} + +fn test_inclusive(r: RangeInclusive) { + let start..=end = r; + //~^ ERROR cannot find value `start` + //~| ERROR cannot find value `end` +} + +fn test_from(r: RangeFrom) { + let start.. = r; + //~^ ERROR cannot find value `start` +} + +fn test_to(r: RangeTo) { + let ..end = r; + //~^ ERROR cannot find value `end` +} + +fn test_to_inclusive(r: RangeToInclusive) { + let ..=end = r; + //~^ ERROR cannot find value `end` +} + +// Case 6: Complex Path (Keep this! It works!) +mod my { + // We don't define MISSING here to trigger the error +} +fn test_path(r: Range) { + let my::MISSING..end = r; + //~^ ERROR cannot find value `MISSING` + //~| ERROR cannot find value `end` +} + +fn main() {} diff --git a/tests/ui/resolve/suggest-range-struct-destructuring.stderr b/tests/ui/resolve/suggest-range-struct-destructuring.stderr new file mode 100644 index 000000000000..78a248ed777d --- /dev/null +++ b/tests/ui/resolve/suggest-range-struct-destructuring.stderr @@ -0,0 +1,127 @@ +error[E0425]: cannot find value `start` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:4:9 + | +LL | let start..end = r; + | ^^^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let start..end = r; +LL + let Range { start, end } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:4:16 + | +LL | let start..end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let start..end = r; +LL + let Range { start, end } = r; + | + +error[E0425]: cannot find value `start` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:9 + | +LL | let start..=end = r; + | ^^^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let start..=end = r; +LL + let RangeInclusive { start, end } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:10:17 + | +LL | let start..=end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let start..=end = r; +LL + let RangeInclusive { start, end } = r; + | + +error[E0425]: cannot find value `start` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:16:9 + | +LL | let start.. = r; + | ^^^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `start`, use the at operator + | +LL | let start @ .. = r; + | + +help: if you meant to destructure a range use a struct pattern + | +LL - let start.. = r; +LL + let RangeFrom { start } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:21:11 + | +LL | let ..end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `end`, use the at operator + | +LL - let ..end = r; +LL + let end @ .. = r; + | +help: if you meant to destructure a range use a struct pattern + | +LL - let ..end = r; +LL + let RangeTo { end } = r; + | + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:26:12 + | +LL | let ..=end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to collect the rest of the slice in `end`, use the at operator + | +LL - let ..=end = r; +LL + let end @ .. = r; + | +help: if you meant to destructure a range use a struct pattern + | +LL - let ..=end = r; +LL + let RangeToInclusive { end } = r; + | + +error[E0425]: cannot find value `MISSING` in module `my` + --> $DIR/suggest-range-struct-destructuring.rs:35:13 + | +LL | let my::MISSING..end = r; + | ^^^^^^^ not found in `my` + +error[E0425]: cannot find value `end` in this scope + --> $DIR/suggest-range-struct-destructuring.rs:35:22 + | +LL | let my::MISSING..end = r; + | ^^^ not found in this scope + | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern +help: if you meant to destructure a range use a struct pattern + | +LL - let my::MISSING..end = r; +LL + let Range { start: my::MISSING, end } = r; + | + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed index cfbf9ef38684..f6fbff175a99 100644 --- a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed +++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.fixed @@ -3,7 +3,7 @@ //@ compile-flags: -Aunused use y::z; -#[cfg(all())] +#[cfg(true)] use y::Whatever; mod y { diff --git a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs index 98be104d8fde..73f263e19aa4 100644 --- a/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs +++ b/tests/ui/resolve/suggestions/suggest-import-without-clobbering-attrs.rs @@ -2,7 +2,7 @@ //@ run-rustfix //@ compile-flags: -Aunused -#[cfg(all())] +#[cfg(true)] use y::Whatever; mod y { diff --git a/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr index 5db943cd10d0..89c0cd54faee 100644 --- a/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr +++ b/tests/ui/resolve/suggestions/suggest-path-instead-of-mod-dot-item.stderr @@ -73,9 +73,13 @@ LL | pub const I: i32 = 1; | --------------------- similarly named constant `I` defined here ... LL | v.push(a::b); - | ^^^- - | | - | help: a constant with a similar name exists: `I` + | ^^^^ + | +help: a constant with a similar name exists + | +LL - v.push(a::b); +LL + v.push(a::I); + | error[E0423]: expected value, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:52:5 @@ -104,9 +108,13 @@ LL | pub const I: i32 = 1; | --------------------- similarly named constant `I` defined here ... LL | a::b - | ^^^- - | | - | help: a constant with a similar name exists: `I` + | ^^^^ + | +help: a constant with a similar name exists + | +LL - a::b +LL + a::I + | error[E0423]: expected function, found module `a::b` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:65:5 @@ -115,9 +123,13 @@ LL | pub const I: i32 = 1; | --------------------- similarly named constant `I` defined here ... LL | a::b() - | ^^^- - | | - | help: a constant with a similar name exists: `I` + | ^^^^ + | +help: a constant with a similar name exists + | +LL - a::b() +LL + a::I() + | error[E0423]: expected value, found module `a` --> $DIR/suggest-path-instead-of-mod-dot-item.rs:72:9 diff --git a/tests/ui/resolve/tool-import.rs b/tests/ui/resolve/tool-import.rs index 951505b92a0b..bc34a64e7f93 100644 --- a/tests/ui/resolve/tool-import.rs +++ b/tests/ui/resolve/tool-import.rs @@ -1,7 +1,8 @@ //@ edition: 2018 use clippy::time::Instant; -//~^ ERROR `clippy` is a tool module +//~^ ERROR: cannot find module `clippy` +//~| NOTE: `clippy` is a tool module fn main() { Instant::now(); diff --git a/tests/ui/resolve/tool-import.stderr b/tests/ui/resolve/tool-import.stderr index b070439d72b7..02e4432fd9e5 100644 --- a/tests/ui/resolve/tool-import.stderr +++ b/tests/ui/resolve/tool-import.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `clippy` is a tool module, not a module +error[E0433]: cannot find module `clippy` in this scope --> $DIR/tool-import.rs:3:5 | LL | use clippy::time::Instant; diff --git a/tests/ui/resolve/tuple-struct-alias.stderr b/tests/ui/resolve/tuple-struct-alias.stderr index bf026a499b8c..89b536708372 100644 --- a/tests/ui/resolve/tuple-struct-alias.stderr +++ b/tests/ui/resolve/tuple-struct-alias.stderr @@ -5,7 +5,13 @@ LL | struct S(u8, u16); | ------------------ similarly named tuple struct `S` defined here ... LL | A(..) => {} - | ^ help: a tuple struct with a similar name exists: `S` + | ^ + | +help: a tuple struct with a similar name exists + | +LL - A(..) => {} +LL + S(..) => {} + | error[E0423]: expected function, tuple struct or tuple variant, found type alias `A` --> $DIR/tuple-struct-alias.rs:5:13 diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index 039410f8795f..9c874d980cbe 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -5,7 +5,13 @@ LL | config: String, | ------ a field by that name exists in `Self` ... LL | Self { config } - | ^^^^^^ help: a local variable with a similar name exists: `cofig` + | ^^^^^^ + | +help: a local variable with a similar name exists + | +LL - Self { config } +LL + Self { cofig } + | error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 @@ -14,15 +20,26 @@ LL | config: String, | ------ a field by that name exists in `Self` ... LL | println!("{config}"); - | ^^^^^^ help: a local variable with a similar name exists: `cofig` + | ^^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{config}"); +LL + println!("{cofig}"); + | error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 | LL | println!("{config}"); - | ^^^^^^ help: a local variable with a similar name exists: `cofig` + | ^^^^^^ | = help: you might have meant to use the available field in a format string: `"{}", self.config` +help: a local variable with a similar name exists + | +LL - println!("{config}"); +LL + println!("{cofig}"); + | error[E0425]: cannot find value `bah` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:33:9 diff --git a/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs b/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs index 188e2ca7f113..706564dc9b21 100644 --- a/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs +++ b/tests/ui/resolve/typo-suggestion-mistyped-in-path.rs @@ -25,18 +25,18 @@ fn main() { //~| NOTE function or associated item not found in `Struct` Struc::foo(); - //~^ ERROR failed to resolve: use of undeclared type `Struc` + //~^ ERROR cannot find type `Struc` //~| NOTE use of undeclared type `Struc` modul::foo(); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `modul` + //~^ ERROR cannot find module or crate `modul` //~| NOTE use of unresolved module or unlinked crate `modul` module::Struc::foo(); - //~^ ERROR failed to resolve: could not find `Struc` in `module` + //~^ ERROR cannot find `Struc` in `module` //~| NOTE could not find `Struc` in `module` Trai::foo(); - //~^ ERROR failed to resolve: use of undeclared type `Trai` + //~^ ERROR cannot find type `Trai` //~| NOTE use of undeclared type `Trai` } diff --git a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr index 2d0d0d0f3867..b1afa703eb03 100644 --- a/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr +++ b/tests/ui/resolve/typo-suggestion-mistyped-in-path.stderr @@ -1,11 +1,13 @@ -error[E0433]: failed to resolve: could not find `Struc` in `module` +error[E0433]: cannot find `Struc` in `module` --> $DIR/typo-suggestion-mistyped-in-path.rs:35:13 | LL | module::Struc::foo(); - | ^^^^^ - | | - | could not find `Struc` in `module` - | help: a struct with a similar name exists: `Struct` + | ^^^^^ could not find `Struc` in `module` + | +help: a struct with a similar name exists + | +LL | module::Struct::foo(); + | + error[E0599]: no function or associated item named `fob` found for struct `Struct` in the current scope --> $DIR/typo-suggestion-mistyped-in-path.rs:23:13 @@ -22,16 +24,18 @@ LL - Struct::fob(); LL + Struct::foo(); | -error[E0433]: failed to resolve: use of undeclared type `Struc` +error[E0433]: cannot find type `Struc` in this scope --> $DIR/typo-suggestion-mistyped-in-path.rs:27:5 | LL | Struc::foo(); - | ^^^^^ - | | - | use of undeclared type `Struc` - | help: a struct with a similar name exists: `Struct` + | ^^^^^ use of undeclared type `Struc` + | +help: a struct with a similar name exists + | +LL | Struct::foo(); + | + -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `modul` +error[E0433]: cannot find module or crate `modul` in this scope --> $DIR/typo-suggestion-mistyped-in-path.rs:31:5 | LL | modul::foo(); @@ -42,14 +46,16 @@ help: there is a crate or module with a similar name LL | module::foo(); | + -error[E0433]: failed to resolve: use of undeclared type `Trai` +error[E0433]: cannot find type `Trai` in this scope --> $DIR/typo-suggestion-mistyped-in-path.rs:39:5 | LL | Trai::foo(); - | ^^^^ - | | - | use of undeclared type `Trai` - | help: a trait with a similar name exists: `Trait` + | ^^^^ use of undeclared type `Trai` + | +help: a trait with a similar name exists + | +LL | Trait::foo(); + | + error: aborting due to 5 previous errors diff --git a/tests/ui/resolve/underscore-bindings-disambiguators.stderr b/tests/ui/resolve/underscore-bindings-disambiguators.stderr index ec14ede03e3f..9208b84c43a2 100644 --- a/tests/ui/resolve/underscore-bindings-disambiguators.stderr +++ b/tests/ui/resolve/underscore-bindings-disambiguators.stderr @@ -21,48 +21,36 @@ error[E0080]: evaluation panicked: not yet implemented | LL | const _: () = todo!(); | ^^^^^^^ evaluation of `impls::_` failed here - | - = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: not yet implemented --> $DIR/underscore-bindings-disambiguators.rs:20:19 | LL | const _: () = todo!(); | ^^^^^^^ evaluation of `impls::_` failed here - | - = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: not yet implemented --> $DIR/underscore-bindings-disambiguators.rs:21:19 | LL | const _: () = todo!(); | ^^^^^^^ evaluation of `impls::_` failed here - | - = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: not yet implemented --> $DIR/underscore-bindings-disambiguators.rs:22:19 | LL | const _: () = todo!(); | ^^^^^^^ evaluation of `impls::_` failed here - | - = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: not yet implemented --> $DIR/underscore-bindings-disambiguators.rs:23:19 | LL | const _: () = todo!(); | ^^^^^^^ evaluation of `impls::_` failed here - | - = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: not yet implemented --> $DIR/underscore-bindings-disambiguators.rs:28:15 | LL | const _: () = todo!(); | ^^^^^^^ evaluation of `_` failed here - | - = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 8 previous errors diff --git a/tests/ui/resolve/unresolved-module-error-33293.rs b/tests/ui/resolve/unresolved-module-error-33293.rs index 354f9914d443..18906e610dca 100644 --- a/tests/ui/resolve/unresolved-module-error-33293.rs +++ b/tests/ui/resolve/unresolved-module-error-33293.rs @@ -2,6 +2,6 @@ fn main() { match 0 { aaa::bbb(_) => () - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `aaa` + //~^ ERROR: cannot find module or crate `aaa` }; } diff --git a/tests/ui/resolve/unresolved-module-error-33293.stderr b/tests/ui/resolve/unresolved-module-error-33293.stderr index 28528148387f..e119a69d2cc2 100644 --- a/tests/ui/resolve/unresolved-module-error-33293.stderr +++ b/tests/ui/resolve/unresolved-module-error-33293.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `aaa` +error[E0433]: cannot find module or crate `aaa` in this scope --> $DIR/unresolved-module-error-33293.rs:4:9 | LL | aaa::bbb(_) => () diff --git a/tests/ui/resolve/unresolved-segments-visibility.rs b/tests/ui/resolve/unresolved-segments-visibility.rs index fc86b31adfc2..b9695de1e999 100644 --- a/tests/ui/resolve/unresolved-segments-visibility.rs +++ b/tests/ui/resolve/unresolved-segments-visibility.rs @@ -6,6 +6,7 @@ extern crate alloc as b; mod foo { mod bar { pub(in crate::b::string::String::newy) extern crate alloc as e; - //~^ ERROR failed to resolve: `String` is a struct, not a module [E0433] + //~^ ERROR: cannot find module `String` in `string` [E0433] + //~| NOTE: `String` is a struct, not a module } } diff --git a/tests/ui/resolve/unresolved-segments-visibility.stderr b/tests/ui/resolve/unresolved-segments-visibility.stderr index 082579c9fa11..bfefdd6449d4 100644 --- a/tests/ui/resolve/unresolved-segments-visibility.stderr +++ b/tests/ui/resolve/unresolved-segments-visibility.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `String` is a struct, not a module +error[E0433]: cannot find module `String` in `string` --> $DIR/unresolved-segments-visibility.rs:8:34 | LL | pub(in crate::b::string::String::newy) extern crate alloc as e; diff --git a/tests/ui/resolve/use_suggestion.rs b/tests/ui/resolve/use_suggestion.rs index 8c9bc6d76b8b..a23a61a39b84 100644 --- a/tests/ui/resolve/use_suggestion.rs +++ b/tests/ui/resolve/use_suggestion.rs @@ -1,6 +1,6 @@ fn main() { - let x1 = HashMap::new(); //~ ERROR failed to resolve - let x2 = GooMap::new(); //~ ERROR failed to resolve + let x1 = HashMap::new(); //~ ERROR cannot find + let x2 = GooMap::new(); //~ ERROR cannot find let y1: HashMap; //~ ERROR cannot find type let y2: GooMap; //~ ERROR cannot find type diff --git a/tests/ui/resolve/use_suggestion.stderr b/tests/ui/resolve/use_suggestion.stderr index 9981c97b2c17..98ef142e6b9c 100644 --- a/tests/ui/resolve/use_suggestion.stderr +++ b/tests/ui/resolve/use_suggestion.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `HashMap` +error[E0433]: cannot find type `HashMap` in this scope --> $DIR/use_suggestion.rs:2:14 | LL | let x1 = HashMap::new(); @@ -26,7 +26,7 @@ error[E0425]: cannot find type `GooMap` in this scope LL | let y2: GooMap; | ^^^^^^ not found in this scope -error[E0433]: failed to resolve: use of undeclared type `GooMap` +error[E0433]: cannot find type `GooMap` in this scope --> $DIR/use_suggestion.rs:3:14 | LL | let x2 = GooMap::new(); diff --git a/tests/ui/resolve/visibility-indeterminate.rs b/tests/ui/resolve/visibility-indeterminate.rs index 181bb2907743..8033a30b233c 100644 --- a/tests/ui/resolve/visibility-indeterminate.rs +++ b/tests/ui/resolve/visibility-indeterminate.rs @@ -2,6 +2,6 @@ foo!(); //~ ERROR cannot find macro `foo` in this scope -pub(in ::bar) struct Baz {} //~ ERROR failed to resolve: could not find `bar` in the list of imported crates +pub(in ::bar) struct Baz {} //~ ERROR cannot find `bar` fn main() {} diff --git a/tests/ui/resolve/visibility-indeterminate.stderr b/tests/ui/resolve/visibility-indeterminate.stderr index bbe28747f7c0..bd6fc11b6731 100644 --- a/tests/ui/resolve/visibility-indeterminate.stderr +++ b/tests/ui/resolve/visibility-indeterminate.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `bar` in the list of imported crates +error[E0433]: cannot find `bar` in the crate root --> $DIR/visibility-indeterminate.rs:5:10 | LL | pub(in ::bar) struct Baz {} diff --git a/tests/ui/return/issue-82612-return-mutable-reference.stderr b/tests/ui/return/issue-82612-return-mutable-reference.stderr index 59a6bb85d0fd..632f366c7551 100644 --- a/tests/ui/return/issue-82612-return-mutable-reference.stderr +++ b/tests/ui/return/issue-82612-return-mutable-reference.stderr @@ -6,7 +6,7 @@ LL | | let value = unsafe { self.values.get_unchecked_mut(index) }; LL | | value.get_or_insert_with(func) | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&mut V` LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found mutable reference `&mut V` diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr index 8105b2df3fea..be3d4b5116f2 100644 --- a/tests/ui/return/tail-expr-as-potential-return.stderr +++ b/tests/ui/return/tail-expr-as-potential-return.stderr @@ -6,7 +6,7 @@ LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` @@ -23,7 +23,7 @@ LL | | 1i32 | | ^^^^ expected `()`, found `i32` ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | help: you might have meant to return this value | @@ -38,7 +38,7 @@ LL | | Err(42) | | ^^^^^^^ expected `()`, found `Result<_, {integer}>` ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result<_, {integer}>` diff --git a/tests/ui/return/tail-expr-if-as-return.stderr b/tests/ui/return/tail-expr-if-as-return.stderr index 2631f1e426de..68acde416bc7 100644 --- a/tests/ui/return/tail-expr-if-as-return.stderr +++ b/tests/ui/return/tail-expr-if-as-return.stderr @@ -5,7 +5,7 @@ LL | / if true { LL | | "" | | ^^ expected `()`, found `&str` LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/diverge-causes-unreachable-code.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/diverge-causes-unreachable-code.stderr index c33a5855d506..a55d540dc7f2 100644 --- a/tests/ui/rfcs/rfc-0000-never_patterns/diverge-causes-unreachable-code.stderr +++ b/tests/ui/rfcs/rfc-0000-never_patterns/diverge-causes-unreachable-code.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::print` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/diverge-causes-unreachable-code.rs:16:5 @@ -20,8 +19,6 @@ LL | fn ref_never_arg(&!: &Void) -> u32 { | -- any code following a never pattern is unreachable LL | println!(); | ^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `$crate::print` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/diverge-causes-unreachable-code.rs:25:5 @@ -31,8 +28,6 @@ LL | let ! = *ptr; LL | } LL | println!(); | ^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `$crate::print` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable statement --> $DIR/diverge-causes-unreachable-code.rs:34:5 @@ -42,8 +37,6 @@ LL | match *ptr { ! }; LL | } LL | println!(); | ^^^^^^^^^^ unreachable statement - | - = note: this error originates in the macro `$crate::print` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs index 26fa6fdb57f9..35a2ef10c2e3 100644 --- a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.rs @@ -9,6 +9,5 @@ static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = //~^ ERROR missing lifetime specifier [E0106] &(non_elidable as fn(&u8, &u8) -> &u8); //~^ ERROR missing lifetime specifier [E0106] - //~| ERROR non-primitive cast fn main() {} diff --git a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr index 77fc3f0412eb..05ea6e44486f 100644 --- a/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr +++ b/tests/ui/rfcs/rfc-1623-static/rfc1623-3.stderr @@ -23,13 +23,6 @@ help: consider making the type lifetime-generic with a new `'a` lifetime LL | &(non_elidable as for<'a> fn(&'a u8, &'a u8) -> &'a u8); | +++++++ ++ ++ ++ -error[E0605]: non-primitive cast: `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {non_elidable}` as `for<'a, 'b> fn(&'a u8, &'b u8) -> &u8` - --> $DIR/rfc1623-3.rs:10:6 - | -LL | &(non_elidable as fn(&u8, &u8) -> &u8); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid cast +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0106, E0605. -For more information about an error, try `rustc --explain E0106`. +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/rfcs/rfc-1861-extern-types/comparison.rs b/tests/ui/rfcs/rfc-1861-extern-types/comparison.rs new file mode 100644 index 000000000000..6504fd64f64d --- /dev/null +++ b/tests/ui/rfcs/rfc-1861-extern-types/comparison.rs @@ -0,0 +1,35 @@ +// Foreign type tests not covering all operations +//@ only-nightly +//@ build-pass + +#![feature(extern_types)] + +#![allow(ambiguous_wide_pointer_comparisons)] + +extern "C" { + type ForeignType; +} + +#[repr(C)] +struct Example { + field: ForeignType, +} + +fn main() { + // pointer comparison + let a = std::ptr::null::(); + let b = std::ptr::null::(); + + assert!(a == b); + + // field address computation + let p = std::ptr::null::(); + unsafe { + let _ = &(*p).field; + } + + // pointer casts involving extern types + let raw = std::ptr::null::<()>(); + let ext = raw as *const ForeignType; + let _ = ext as *const (); +} diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs index b2ebab382bd9..2e40819d69ad 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-exhaustive.rs @@ -14,11 +14,6 @@ enum Local { Variant(u32), } -#[non_exhaustive] -enum LocalNonExhaustive { - Variant(u32), -} - fn main() { let mut x = ExhaustiveMonovariant::Variant(1); let y = &mut x; @@ -34,11 +29,4 @@ fn main() { _ => {}, } drop(y); - let mut x = LocalNonExhaustive::Variant(1); - let y = &mut x; - match x { - LocalNonExhaustive::Variant(_) => {}, - _ => {}, - } - drop(y); } diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs index d616f5e5e89a..a6a369e92a6c 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs @@ -6,6 +6,11 @@ extern crate monovariants; use monovariants::NonExhaustiveMonovariant; +#[non_exhaustive] +enum LocalNonExhaustive { + Variant(u32), +} + fn main() { let mut x = NonExhaustiveMonovariant::Variant(1); let y = &mut x; @@ -15,4 +20,11 @@ fn main() { _ => {}, } drop(y); + let mut x = LocalNonExhaustive::Variant(1); + let y = &mut x; + match x { //~ ERROR cannot use `x` because it was mutably borrowed + LocalNonExhaustive::Variant(_) => {}, + _ => {}, + } + drop(y); } diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr index 70f5b2b84d86..d6225adc95cb 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr @@ -1,5 +1,5 @@ error[E0503]: cannot use `x` because it was mutably borrowed - --> $DIR/borrowck-non-exhaustive.rs:12:11 + --> $DIR/borrowck-non-exhaustive.rs:17:11 | LL | let y = &mut x; | ------ `x` is borrowed here @@ -9,6 +9,17 @@ LL | match x { LL | drop(y); | - borrow later used here -error: aborting due to 1 previous error +error[E0503]: cannot use `x` because it was mutably borrowed + --> $DIR/borrowck-non-exhaustive.rs:25:11 + | +LL | let y = &mut x; + | ------ `x` is borrowed here +LL | match x { + | ^ use of borrowed `x` +... +LL | drop(y); + | - borrow later used here + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0503`. diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr index 98e8f1235e6b..d711c3f2eb12 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr @@ -21,7 +21,7 @@ error: `#[non_exhaustive]` attribute cannot be used on unions LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ | - = help: `#[non_exhaustive]` can be applied to data types and enum variants + = help: `#[non_exhaustive]` can be applied to enum variants, enums, and structs error: aborting due to 3 previous errors diff --git a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs index 038f53034ab0..c5e9d147d567 100644 --- a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs +++ b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.rs @@ -34,6 +34,7 @@ enum RefIndirect<'a, T> { enum RefDouble<'a, 'b, T> { RefDoubleVariant1(&'a RequireOutlives<'b, T>), //~^ ERROR the parameter type `T` may not live long enough [E0309] + //~| ERROR the parameter type `T` may not live long enough [E0309] } fn main() {} diff --git a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr index 5b605f3eef56..2799164bbda2 100644 --- a/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr +++ b/tests/ui/rfcs/rfc-2093-infer-outlives/regions-enum-not-wf.stderr @@ -38,6 +38,20 @@ help: consider adding an explicit lifetime bound LL | enum RefDouble<'a, 'b, T: 'b> { | ++++ -error: aborting due to 3 previous errors +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/regions-enum-not-wf.rs:35:23 + | +LL | enum RefDouble<'a, 'b, T> { + | -- the parameter type `T` must be valid for the lifetime `'b` as defined here... +LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider adding an explicit lifetime bound + | +LL | enum RefDouble<'a, 'b, T: 'b> { + | ++++ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs index efadddf3ef1d..95486e37b691 100644 --- a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs +++ b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.rs @@ -3,8 +3,8 @@ struct S; pub mod m { fn f() { - let s = ::m::crate::S; //~ ERROR failed to resolve - let s1 = ::crate::S; //~ ERROR failed to resolve + let s = ::m::crate::S; //~ ERROR: `crate` in paths can only be used in start position + let s1 = ::crate::S; //~ ERROR: global paths cannot start with `crate` let s2 = crate::S; // no error } } diff --git a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr index 6cb96e5762ad..a267c037d1ff 100644 --- a/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr +++ b/tests/ui/rfcs/rfc-2126-crate-paths/crate-path-non-absolute.stderr @@ -1,14 +1,14 @@ -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: `crate` in paths can only be used in start position --> $DIR/crate-path-non-absolute.rs:6:22 | LL | let s = ::m::crate::S; - | ^^^^^ `crate` in paths can only be used in start position + | ^^^^^ can only be used in path start position -error[E0433]: failed to resolve: global paths cannot start with `crate` +error[E0433]: global paths cannot start with `crate` --> $DIR/crate-path-non-absolute.rs:7:20 | LL | let s1 = ::crate::S; - | ^^^^^ global paths cannot start with `crate` + | ^^^^^ cannot start with this error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs index 6bbfb69800e1..f8450d2ba009 100644 --- a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs +++ b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.rs @@ -2,5 +2,5 @@ fn main() { let s = ::xcrate::S; - //~^ ERROR failed to resolve: could not find `xcrate` in the list of imported crates + //~^ ERROR cannot find `xcrate` } diff --git a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr index e3875fd843b6..553365c93223 100644 --- a/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr +++ b/tests/ui/rfcs/rfc-2126-extern-absolute-paths/non-existent-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `xcrate` in the list of imported crates +error[E0433]: cannot find `xcrate` in the crate root --> $DIR/non-existent-2.rs:4:15 | LL | let s = ::xcrate::S; diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr index f515cb62c7cd..f8ef315b9cc7 100644 --- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr +++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr @@ -8,7 +8,6 @@ LL | let _ = dbg!(a); LL | let _ = dbg!(a); | ^^^^^^^ value used here after move | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider borrowing instead of transferring ownership | LL | let _ = dbg!(&a); diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr index 4e0ae9184150..4cdeb184bd91 100644 --- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr +++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr @@ -5,7 +5,6 @@ LL | let _: NotDebug = dbg!(NotDebug); | ^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `NotDebug` | = note: add `#[derive(Debug)]` to `NotDebug` or manually `impl Debug for NotDebug` - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `NotDebug` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout index 66ba726fb9a4..9a34d6c1af7a 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/ast-pretty-check.stdout @@ -1,6 +1,5 @@ #![feature(prelude_import)] #![no_std] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr index 15e7be8c65f2..40a32880f407 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2021.stderr @@ -1137,7 +1137,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | if let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` | - = help: the trait `Try` is not implemented for `{integer}` + = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}` error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:224:11 @@ -1198,7 +1198,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | while let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` | - = help: the trait `Try` is not implemented for `{integer}` + = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}` error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:333:10 @@ -1217,7 +1217,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | let 0 = 0?; | ^^ the `?` operator cannot be applied to type `{integer}` | - = help: the trait `Try` is not implemented for `{integer}` + = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}` error: aborting due to 134 previous errors diff --git a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr index 20af65cf89a2..21167cf63d17 100644 --- a/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr +++ b/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.e2024.stderr @@ -1083,7 +1083,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | if let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` | - = help: the trait `Try` is not implemented for `{integer}` + = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}` error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:224:11 @@ -1144,7 +1144,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | while let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` | - = help: the trait `Try` is not implemented for `{integer}` + = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}` error[E0308]: mismatched types --> $DIR/disallowed-positions.rs:333:10 @@ -1163,7 +1163,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | let 0 = 0?; | ^^ the `?` operator cannot be applied to type `{integer}` | - = help: the trait `Try` is not implemented for `{integer}` + = help: the nightly-only, unstable trait `Try` is not implemented for `{integer}` error: aborting due to 125 previous errors diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr index cc08307a18d0..c234cb31bc56 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr @@ -389,7 +389,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits = note: requested on the command line with `-W unused-attributes` warning: `#[no_mangle]` attribute cannot be used on function params @@ -408,7 +408,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_mangle]` attribute cannot be used on function params --> $DIR/param-attrs-builtin-attrs.rs:70:9 @@ -426,7 +426,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_mangle]` attribute cannot be used on function params --> $DIR/param-attrs-builtin-attrs.rs:89:9 @@ -444,7 +444,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_mangle]` attribute cannot be used on function params --> $DIR/param-attrs-builtin-attrs.rs:114:9 @@ -462,7 +462,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_mangle]` attribute cannot be used on function params --> $DIR/param-attrs-builtin-attrs.rs:137:9 @@ -480,7 +480,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_mangle]` attribute cannot be used on function params --> $DIR/param-attrs-builtin-attrs.rs:156:9 @@ -498,7 +498,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_mangle]` attribute cannot be used on function params --> $DIR/param-attrs-builtin-attrs.rs:180:9 @@ -516,7 +516,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_mangle]` attribute cannot be used on function params --> $DIR/param-attrs-builtin-attrs.rs:201:9 diff --git a/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs b/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs deleted file mode 100644 index c40590ad87f4..000000000000 --- a/tests/ui/runtime/on-broken-pipe/with-rustc_main.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass -//@ aux-build:sigpipe-utils.rs -//@ compile-flags: -Zon-broken-pipe=kill -//@ only-unix because SIGPIPE is a unix thing - -#![feature(rustc_attrs)] - -#[rustc_main] -fn rustc_main() { - extern crate sigpipe_utils; - - // `-Zon-broken-pipe=kill` is active, so SIGPIPE handler shall be - // SIG_DFL. Note that we have a #[rustc_main], but it should still work. - sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default); -} diff --git a/tests/ui/rust-2018/async-ident-allowed.stderr b/tests/ui/rust-2018/async-ident-allowed.stderr index 378c81d3c770..1bdfc7bae102 100644 --- a/tests/ui/rust-2018/async-ident-allowed.stderr +++ b/tests/ui/rust-2018/async-ident-allowed.stderr @@ -5,7 +5,7 @@ LL | let async = 3; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/async-ident-allowed.rs:3:9 | diff --git a/tests/ui/rust-2018/async-ident.stderr b/tests/ui/rust-2018/async-ident.stderr index 4ab061dd6f59..2c4cb7e1d96e 100644 --- a/tests/ui/rust-2018/async-ident.stderr +++ b/tests/ui/rust-2018/async-ident.stderr @@ -5,7 +5,7 @@ LL | fn async() {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/async-ident.rs:2:9 | @@ -20,7 +20,7 @@ LL | ($async:expr, async) => {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:17:6 @@ -29,7 +29,7 @@ LL | foo!(async); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:26:11 @@ -38,7 +38,7 @@ LL | trait async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:30:10 @@ -47,7 +47,7 @@ LL | impl async for MyStruct {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:36:12 @@ -56,7 +56,7 @@ LL | static async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:42:11 @@ -65,7 +65,7 @@ LL | const async: u32 = 0; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:48:15 @@ -74,7 +74,7 @@ LL | impl Foo { fn async() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:53:12 @@ -83,7 +83,7 @@ LL | struct async {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:9 @@ -92,7 +92,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:16 @@ -101,7 +101,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:56:24 @@ -110,7 +110,7 @@ LL | let async: async = async {}; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:67:19 @@ -119,7 +119,7 @@ LL | () => (pub fn async() {}) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:74:6 @@ -128,7 +128,7 @@ LL | (async) => (1) | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 14 previous errors diff --git a/tests/ui/rust-2018/dyn-keyword.stderr b/tests/ui/rust-2018/dyn-keyword.stderr index f8245bc88f57..733583f32b9b 100644 --- a/tests/ui/rust-2018/dyn-keyword.stderr +++ b/tests/ui/rust-2018/dyn-keyword.stderr @@ -5,7 +5,7 @@ LL | let dyn = (); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/dyn-keyword.rs:5:9 | diff --git a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr index c0a322edcd64..b59604f6427e 100644 --- a/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-fully-qualified-paths.stderr @@ -5,7 +5,7 @@ LL | let _: ::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-fully-qualified-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | let _: ::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -29,7 +29,7 @@ LL | let _: <::foo::Baz as foo::Foo>::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Baz` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: aborting due to 3 previous errors diff --git a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr index 041572be8441..af02b30a99bd 100644 --- a/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-empty-paths.stderr @@ -5,7 +5,7 @@ LL | use foo::{bar::{baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-nested-empty-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:21:5 @@ -28,7 +28,7 @@ LL | use foo::{bar::{XX, baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{XX, baz::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -38,7 +38,7 @@ LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:27:5 @@ -47,7 +47,7 @@ LL | use foo::{bar::{baz::{}, baz1::{}}}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}, baz1::{}}}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 5 previous errors diff --git a/tests/ui/rust-2018/edition-lint-nested-paths.stderr b/tests/ui/rust-2018/edition-lint-nested-paths.stderr index 4a70bb7e5c87..0f60b16ac9aa 100644 --- a/tests/ui/rust-2018/edition-lint-nested-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-nested-paths.stderr @@ -5,7 +5,7 @@ LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-nested-paths.rs:4:9 | @@ -19,7 +19,7 @@ LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -29,7 +29,7 @@ LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-paths.rs:23:13 @@ -38,7 +38,7 @@ LL | use foo::{self as x, c}; | ^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{self as x, c}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 4 previous errors diff --git a/tests/ui/rust-2018/edition-lint-paths.stderr b/tests/ui/rust-2018/edition-lint-paths.stderr index fde17338d98a..26db6e402a9e 100644 --- a/tests/ui/rust-2018/edition-lint-paths.stderr +++ b/tests/ui/rust-2018/edition-lint-paths.stderr @@ -5,7 +5,7 @@ LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-lint-paths.rs:5:9 | @@ -19,7 +19,7 @@ LL | use bar; | ^^^ help: use `crate`: `crate::bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:25:9 @@ -28,7 +28,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:25:9 @@ -37,7 +37,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -47,7 +47,7 @@ LL | use {main, Bar as SomethingElse}; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::{main, Bar as SomethingElse}` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition @@ -57,7 +57,7 @@ LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:52:9 @@ -66,7 +66,7 @@ LL | use *; | ^ help: use `crate`: `crate::*` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:57:6 @@ -75,7 +75,7 @@ LL | impl ::foo::SomeTrait for u32 {} | ^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::SomeTrait` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:62:13 @@ -84,7 +84,7 @@ LL | let x = ::bar::Bar; | ^^^^^^^^^^ help: use `crate`: `crate::bar::Bar` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see error: aborting due to 9 previous errors diff --git a/tests/ui/rust-2018/extern-crate-rename.stderr b/tests/ui/rust-2018/extern-crate-rename.stderr index 36986c89c62b..bce9e73ee65a 100644 --- a/tests/ui/rust-2018/extern-crate-rename.stderr +++ b/tests/ui/rust-2018/extern-crate-rename.stderr @@ -5,7 +5,7 @@ LL | use my_crate::foo; | ^^^^^^^^^^^^^ help: use `crate`: `crate::my_crate::foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/extern-crate-rename.rs:8:9 | diff --git a/tests/ui/rust-2018/extern-crate-submod.stderr b/tests/ui/rust-2018/extern-crate-submod.stderr index 85e26d72a673..ed4266d3b091 100644 --- a/tests/ui/rust-2018/extern-crate-submod.stderr +++ b/tests/ui/rust-2018/extern-crate-submod.stderr @@ -5,7 +5,7 @@ LL | use m::edition_lint_paths::foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::m::edition_lint_paths::foo` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 + = note: for more information, see note: the lint level is defined here --> $DIR/extern-crate-submod.rs:9:9 | diff --git a/tests/ui/rust-2018/try-ident.stderr b/tests/ui/rust-2018/try-ident.stderr index aca623d7d482..3af2196ce35b 100644 --- a/tests/ui/rust-2018/try-ident.stderr +++ b/tests/ui/rust-2018/try-ident.stderr @@ -5,7 +5,7 @@ LL | try(); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/try-ident.rs:5:9 | @@ -20,7 +20,7 @@ LL | fn try() { | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see warning: 2 warnings emitted diff --git a/tests/ui/rust-2018/try-macro.stderr b/tests/ui/rust-2018/try-macro.stderr index 20105e1868f2..89366381c8c6 100644 --- a/tests/ui/rust-2018/try-macro.stderr +++ b/tests/ui/rust-2018/try-macro.stderr @@ -5,7 +5,7 @@ LL | try!(x); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/try-macro.rs:7:9 | diff --git a/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm-in-2024.rs b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm-in-2024.rs new file mode 100644 index 000000000000..5f44223df90c --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/auxiliary/unsafe-attributes-pm-in-2024.rs @@ -0,0 +1,29 @@ +//@ edition: 2024 + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn missing_unsafe(_input: TokenStream) -> TokenStream { + "#[no_mangle] pub fn abc() {}".parse().unwrap() +} + +#[proc_macro_attribute] +pub fn attr_missing_unsafe(_attr: TokenStream, _input: TokenStream) -> TokenStream { + "#[no_mangle] pub fn bar() {}".parse().unwrap() +} + +#[proc_macro_derive(AttrMissingUnsafe)] +pub fn derive_attr_missing_unsafe(_input: TokenStream) -> TokenStream { + "#[no_mangle] pub fn baz() {}".parse().unwrap() +} + +#[proc_macro] +pub fn macro_rules_missing_unsafe(_input: TokenStream) -> TokenStream { + "macro_rules! make_fn { + () => { #[no_mangle] pub fn foo() { } }; + }" + .parse() + .unwrap() +} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed index a2f04daa4b85..c1adc90161a4 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed @@ -43,7 +43,7 @@ macro_rules! meta2 { macro_rules! with_cfg_attr { () => { - #[cfg_attr(all(), unsafe(link_section = ".custom_section"))] + #[cfg_attr(true, unsafe(link_section = ".custom_section"))] //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition pub extern "C" fn abc() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs index 88c9328fd9cd..9fdf37904634 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs @@ -43,7 +43,7 @@ macro_rules! meta2 { macro_rules! with_cfg_attr { () => { - #[cfg_attr(all(), link_section = ".custom_section")] + #[cfg_attr(true, link_section = ".custom_section")] //~^ ERROR: unsafe attribute used without unsafe //~| WARN this is accepted in the current edition pub extern "C" fn abc() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr index 55df60c51d9c..279e61a9cb67 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr @@ -77,10 +77,10 @@ LL | #[unsafe($e = $l)] | +++++++ + error: unsafe attribute used without unsafe - --> $DIR/unsafe-attributes-fix.rs:46:27 + --> $DIR/unsafe-attributes-fix.rs:46:26 | -LL | #[cfg_attr(all(), link_section = ".custom_section")] - | ^^^^^^^^^^^^ usage of unsafe attribute +LL | #[cfg_attr(true, link_section = ".custom_section")] + | ^^^^^^^^^^^^ usage of unsafe attribute ... LL | with_cfg_attr!(); | ---------------- in this macro invocation @@ -90,8 +90,8 @@ LL | with_cfg_attr!(); = note: this error originates in the macro `with_cfg_attr` (in Nightly builds, run with -Z macro-backtrace for more info) help: wrap the attribute in `unsafe(...)` | -LL | #[cfg_attr(all(), unsafe(link_section = ".custom_section"))] - | +++++++ + +LL | #[cfg_attr(true, unsafe(link_section = ".custom_section"))] + | +++++++ + error: unsafe attribute used without unsafe --> $DIR/unsafe-attributes-fix.rs:67:3 diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.rs new file mode 100644 index 000000000000..dca05cc27f6e --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.rs @@ -0,0 +1,18 @@ +// Test for unsafe attributes generated by a proc-macro. + +//@ proc-macro: unsafe-attributes-pm-in-2024.rs +//@ ignore-backends: gcc + +unsafe_attributes_pm_in_2024::missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe + +#[unsafe_attributes_pm_in_2024::attr_missing_unsafe] //~ ERROR unsafe attribute used without unsafe +pub fn bar() {} + +#[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)] //~ ERROR unsafe attribute used without unsafe +struct Baz; + +unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!(); //~ ERROR unsafe attribute used without unsafe + +make_fn!(); + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.stderr new file mode 100644 index 000000000000..fa36b148bf3d --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm-in-2024.stderr @@ -0,0 +1,37 @@ +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:6:1 + | +LL | unsafe_attributes_pm_in_2024::missing_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute + | + = note: this error originates in the macro `unsafe_attributes_pm_in_2024::missing_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:8:1 + | +LL | #[unsafe_attributes_pm_in_2024::attr_missing_unsafe] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute + | + = note: this error originates in the attribute macro `unsafe_attributes_pm_in_2024::attr_missing_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:11:10 + | +LL | #[derive(unsafe_attributes_pm_in_2024::AttrMissingUnsafe)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute + | + = note: this error originates in the derive macro `unsafe_attributes_pm_in_2024::AttrMissingUnsafe` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-from-pm-in-2024.rs:14:1 + | +LL | unsafe_attributes_pm_in_2024::macro_rules_missing_unsafe!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ usage of unsafe attribute +LL | +LL | make_fn!(); + | ---------- in this macro invocation + | + = note: this error originates in the macro `make_fn` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + diff --git a/tests/ui/rust-2024/unsafe-before_exec-suggestion.fixed b/tests/ui/rust-2024/unsafe-before_exec-suggestion.fixed new file mode 100644 index 000000000000..d850428cc1a5 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-before_exec-suggestion.fixed @@ -0,0 +1,18 @@ +//@ edition:2015 +//@ only-unix +//@ run-rustfix + +#![deny(deprecated_safe_2024)] + +use std::process::Command; +use std::os::unix::process::CommandExt; + +#[allow(deprecated)] +fn main() { + let mut cmd = Command::new("sleep"); + // TODO: Audit that the closure is async-signal-safe. + unsafe { cmd.before_exec(|| Ok(())) }; + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + drop(cmd); +} diff --git a/tests/ui/rust-2024/unsafe-before_exec-suggestion.rs b/tests/ui/rust-2024/unsafe-before_exec-suggestion.rs new file mode 100644 index 000000000000..c6894ea631ae --- /dev/null +++ b/tests/ui/rust-2024/unsafe-before_exec-suggestion.rs @@ -0,0 +1,17 @@ +//@ edition:2015 +//@ only-unix +//@ run-rustfix + +#![deny(deprecated_safe_2024)] + +use std::process::Command; +use std::os::unix::process::CommandExt; + +#[allow(deprecated)] +fn main() { + let mut cmd = Command::new("sleep"); + cmd.before_exec(|| Ok(())); + //~^ ERROR call to deprecated safe function + //~| WARN this is accepted in the current edition + drop(cmd); +} diff --git a/tests/ui/rust-2024/unsafe-before_exec-suggestion.stderr b/tests/ui/rust-2024/unsafe-before_exec-suggestion.stderr new file mode 100644 index 000000000000..33893f30ceca --- /dev/null +++ b/tests/ui/rust-2024/unsafe-before_exec-suggestion.stderr @@ -0,0 +1,21 @@ +error: call to deprecated safe function `std::os::unix::process::CommandExt::before_exec` is unsafe and requires unsafe block + --> $DIR/unsafe-before_exec-suggestion.rs:13:5 + | +LL | cmd.before_exec(|| Ok(())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see +note: the lint level is defined here + --> $DIR/unsafe-before_exec-suggestion.rs:5:9 + | +LL | #![deny(deprecated_safe_2024)] + | ^^^^^^^^^^^^^^^^^^^^ +help: you can wrap the call in an `unsafe` block if you can guarantee that the closure is async-signal-safe + | +LL + // TODO: Audit that the closure is async-signal-safe. +LL ~ unsafe { cmd.before_exec(|| Ok(())) }; + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/rustc_public-ir-print/async-closure.stdout b/tests/ui/rustc_public-ir-print/async-closure.stdout index 3ec816b657f4..8df31e2f680a 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.stdout +++ b/tests/ui/rustc_public-ir-print/async-closure.stdout @@ -56,7 +56,7 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo _3 = (*_4); _5 = (); StorageDead(_3); - _0 = std::task::Poll::Ready(move _5); + _0 = Poll::Ready(move _5); discriminant((*_7)) = 1; return; } @@ -88,7 +88,7 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c _3 = (*_4); _5 = (); StorageDead(_3); - _0 = std::task::Poll::Ready(move _5); + _0 = Poll::Ready(move _5); discriminant((*_7)) = 1; return; } diff --git a/tests/ui/rustc_public-ir-print/operands.stdout b/tests/ui/rustc_public-ir-print/operands.stdout index b7775416af85..58f229be2e6e 100644 --- a/tests/ui/rustc_public-ir-print/operands.stdout +++ b/tests/ui/rustc_public-ir-print/operands.stdout @@ -206,7 +206,7 @@ fn operands(_1: u8) -> () { StorageDead(_19); StorageDead(_18); StorageLive(_21); - _21 = core::panicking::AssertKind::Eq; + _21 = AssertKind::Eq; StorageLive(_22); StorageLive(_23); _23 = move _21; @@ -219,7 +219,7 @@ fn operands(_1: u8) -> () { _27 = &(*_16); _26 = &(*_27); StorageLive(_28); - _28 = std::option::Option::None; + _28 = Option::None; _22 = core::panicking::assert_failed::(move _23, move _24, move _26, move _28) -> unwind unreachable; } bb6: { @@ -268,7 +268,7 @@ fn operands(_1: u8) -> () { StorageDead(_39); StorageDead(_38); StorageLive(_41); - _41 = core::panicking::AssertKind::Eq; + _41 = AssertKind::Eq; StorageLive(_42); StorageLive(_43); _43 = move _41; @@ -281,7 +281,7 @@ fn operands(_1: u8) -> () { _47 = &(*_36); _46 = &(*_47); StorageLive(_48); - _48 = std::option::Option::None; + _48 = Option::None; _42 = core::panicking::assert_failed::(move _43, move _44, move _46, move _48) -> unwind unreachable; } bb8: { @@ -305,7 +305,7 @@ fn operands(_1: u8) -> () { StorageDead(_62); StorageDead(_61); StorageLive(_64); - _64 = core::panicking::AssertKind::Eq; + _64 = AssertKind::Eq; StorageLive(_65); StorageLive(_66); _66 = move _64; @@ -318,7 +318,7 @@ fn operands(_1: u8) -> () { _70 = &(*_59); _69 = &(*_70); StorageLive(_71); - _71 = std::option::Option::None; + _71 = Option::None; _65 = core::panicking::assert_failed::(move _66, move _67, move _69, move _71) -> unwind unreachable; } bb10: { @@ -380,7 +380,7 @@ fn operands(_1: u8) -> () { StorageDead(_86); StorageDead(_85); StorageLive(_88); - _88 = core::panicking::AssertKind::Eq; + _88 = AssertKind::Eq; StorageLive(_89); StorageLive(_90); _90 = move _88; @@ -393,7 +393,7 @@ fn operands(_1: u8) -> () { _94 = &(*_83); _93 = &(*_94); StorageLive(_95); - _95 = std::option::Option::None; + _95 = Option::None; _89 = core::panicking::assert_failed::(move _90, move _91, move _93, move _95) -> unwind unreachable; } } diff --git a/tests/ui/rustdoc/check-doc-alias-attr-location.rs b/tests/ui/rustdoc/check-doc-alias-attr-location.rs index 10609e5d8f4d..45777c5edf4d 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr-location.rs +++ b/tests/ui/rustdoc/check-doc-alias-attr-location.rs @@ -21,11 +21,14 @@ impl Foo for Bar { type X = i32; fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { //~^ ERROR - #[doc(alias = "stmt")] //~ ERROR + #[doc(alias = "stmt")] + //~^ ERROR let x = 0; - #[doc(alias = "expr")] //~ ERROR + #[doc(alias = "expr")] + //~^ ERROR match x { - #[doc(alias = "arm")] //~ ERROR + #[doc(alias = "arm")] + //~^ ERROR _ => 0 } } diff --git a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr index 23c93a4ed8bd..f587c17c1f3e 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr-location.stderr +++ b/tests/ui/rustdoc/check-doc-alias-attr-location.stderr @@ -5,46 +5,46 @@ LL | fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { | ^^^^^^^^^^^^^^^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on foreign module - --> $DIR/check-doc-alias-attr-location.rs:9:7 + --> $DIR/check-doc-alias-attr-location.rs:9:15 | LL | #[doc(alias = "foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:12:7 + --> $DIR/check-doc-alias-attr-location.rs:12:15 | LL | #[doc(alias = "bar")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: `#[doc(alias = "...")]` isn't allowed on implementation block - --> $DIR/check-doc-alias-attr-location.rs:18:7 + --> $DIR/check-doc-alias-attr-location.rs:18:15 | LL | #[doc(alias = "foobar")] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation block - --> $DIR/check-doc-alias-attr-location.rs:20:11 + --> $DIR/check-doc-alias-attr-location.rs:20:19 | LL | #[doc(alias = "assoc")] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on statement - --> $DIR/check-doc-alias-attr-location.rs:24:15 + --> $DIR/check-doc-alias-attr-location.rs:24:23 | LL | #[doc(alias = "stmt")] - | ^^^^^^^^^^^^^^ + | ^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on expression - --> $DIR/check-doc-alias-attr-location.rs:26:15 + --> $DIR/check-doc-alias-attr-location.rs:27:23 | LL | #[doc(alias = "expr")] - | ^^^^^^^^^^^^^^ + | ^^^^^^ error: `#[doc(alias = "...")]` isn't allowed on match arm - --> $DIR/check-doc-alias-attr-location.rs:28:19 + --> $DIR/check-doc-alias-attr-location.rs:30:27 | LL | #[doc(alias = "arm")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: aborting due to 8 previous errors diff --git a/tests/ui/rustdoc/check-doc-alias-attr.stderr b/tests/ui/rustdoc/check-doc-alias-attr.stderr index 250568be3333..d9e785ee0f1f 100644 --- a/tests/ui/rustdoc/check-doc-alias-attr.stderr +++ b/tests/ui/rustdoc/check-doc-alias-attr.stderr @@ -4,11 +4,13 @@ error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of s LL | #[doc(alias)] | ^^^^^ -error: doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]` - --> $DIR/check-doc-alias-attr.rs:8:7 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:8:1 | LL | #[doc(alias = 0)] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^-^^ + | | + | expected a string literal here error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:9:15 @@ -54,25 +56,27 @@ error: `#[doc(alias = "...")]` attribute cannot have empty value LL | #[doc(alias = "")] | ^^ -error: `#[doc(alias("a"))]` expects string literals - --> $DIR/check-doc-alias-attr.rs:19:13 +error[E0539]: malformed `doc` attribute input + --> $DIR/check-doc-alias-attr.rs:19:1 | LL | #[doc(alias(0))] - | ^ + | ^^^^^^^^^^^^-^^^ + | | + | expected a string literal here -error: '"' character isn't allowed in `#[doc(alias("..."))]` +error: '"' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:20:13 | LL | #[doc(alias("\""))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:21:13 | LL | #[doc(alias("\n"))] | ^^^^ -error: '\n' character isn't allowed in `#[doc(alias("..."))]` +error: '\n' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:22:13 | LL | #[doc(alias(" @@ -80,25 +84,25 @@ LL | #[doc(alias(" LL | | "))] | |_^ -error: '\t' character isn't allowed in `#[doc(alias("..."))]` +error: '\t' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/check-doc-alias-attr.rs:24:13 | LL | #[doc(alias("\t"))] | ^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:25:13 | LL | #[doc(alias(" hello"))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` cannot start or end with ' ' +error: `#[doc(alias = "...")]` cannot start or end with ' ' --> $DIR/check-doc-alias-attr.rs:26:13 | LL | #[doc(alias("hello "))] | ^^^^^^^^ -error: `#[doc(alias("..."))]` attribute cannot have empty value +error: `#[doc(alias = "...")]` attribute cannot have empty value --> $DIR/check-doc-alias-attr.rs:27:13 | LL | #[doc(alias(""))] @@ -106,3 +110,4 @@ LL | #[doc(alias(""))] error: aborting due to 17 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/rustdoc/doc-alias-crate-level.stderr b/tests/ui/rustdoc/doc-alias-crate-level.stderr index bd32609ade29..1d10446a4e7c 100644 --- a/tests/ui/rustdoc/doc-alias-crate-level.stderr +++ b/tests/ui/rustdoc/doc-alias-crate-level.stderr @@ -1,14 +1,14 @@ +error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute + --> $DIR/doc-alias-crate-level.rs:5:16 + | +LL | #![doc(alias = "not working!")] + | ^^^^^^^^^^^^^^ + error: '\'' character isn't allowed in `#[doc(alias = "...")]` --> $DIR/doc-alias-crate-level.rs:7:15 | LL | #[doc(alias = "shouldn't work!")] | ^^^^^^^^^^^^^^^^^ -error: `#![doc(alias = "...")]` isn't allowed as a crate-level attribute - --> $DIR/doc-alias-crate-level.rs:5:8 - | -LL | #![doc(alias = "not working!")] - | ^^^^^^^^^^^^^^^^^^^^^^ - error: aborting due to 2 previous errors diff --git a/tests/ui/rustdoc/doc-alias-same-name.stderr b/tests/ui/rustdoc/doc-alias-same-name.stderr index a9da75c0171c..a76ff5ee0b67 100644 --- a/tests/ui/rustdoc/doc-alias-same-name.stderr +++ b/tests/ui/rustdoc/doc-alias-same-name.stderr @@ -1,8 +1,8 @@ -error: `#[doc(alias = "...")]` is the same as the item's name - --> $DIR/doc-alias-same-name.rs:3:7 +error: `#[doc(alias = "Foo"]` is the same as the item's name + --> $DIR/doc-alias-same-name.rs:3:15 | LL | #[doc(alias = "Foo")] - | ^^^^^^^^^^^^^ + | ^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/rustdoc/doc-primitive.stderr b/tests/ui/rustdoc/doc-primitive.stderr index 8f6f330b3e5d..4ba310ca2410 100644 --- a/tests/ui/rustdoc/doc-primitive.stderr +++ b/tests/ui/rustdoc/doc-primitive.stderr @@ -2,7 +2,7 @@ error: unknown `doc` attribute `primitive` --> $DIR/doc-primitive.rs:3:7 | LL | #[doc(primitive = "foo")] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ | note: the lint level is defined here --> $DIR/doc-primitive.rs:1:9 diff --git a/tests/ui/rustdoc/doc-test-attr.stderr b/tests/ui/rustdoc/doc-test-attr.stderr index 51672314a431..1a4b5e45142a 100644 --- a/tests/ui/rustdoc/doc-test-attr.stderr +++ b/tests/ui/rustdoc/doc-test-attr.stderr @@ -11,10 +11,10 @@ LL | #![deny(invalid_doc_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^ error: `#[doc(test(...)]` takes a list of attributes - --> $DIR/doc-test-attr.rs:6:8 + --> $DIR/doc-test-attr.rs:6:13 | LL | #![doc(test = "hello")] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: unknown `doc(test)` attribute `a` --> $DIR/doc-test-attr.rs:8:13 diff --git a/tests/ui/rustdoc/doc_keyword.rs b/tests/ui/rustdoc/doc_keyword.rs index e0995f336da3..abf06d7a7866 100644 --- a/tests/ui/rustdoc/doc_keyword.rs +++ b/tests/ui/rustdoc/doc_keyword.rs @@ -1,14 +1,14 @@ #![crate_type = "lib"] #![feature(rustdoc_internals)] -#![doc(keyword = "hello")] +#![doc(keyword = "match")] //~^ ERROR `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute -#[doc(keyword = "hell")] //~ ERROR `#[doc(keyword = "...")]` should be used on empty modules +#[doc(keyword = "match")] //~ ERROR `#[doc(keyword = "...")]` should be used on empty modules mod foo { fn hell() {} } -#[doc(keyword = "hall")] //~ ERROR `#[doc(keyword = "...")]` should be used on modules +#[doc(keyword = "match")] //~ ERROR `#[doc(keyword = "...")]` should be used on modules fn foo() {} diff --git a/tests/ui/rustdoc/doc_keyword.stderr b/tests/ui/rustdoc/doc_keyword.stderr index 584daae2f1aa..c8038cbf0196 100644 --- a/tests/ui/rustdoc/doc_keyword.stderr +++ b/tests/ui/rustdoc/doc_keyword.stderr @@ -1,14 +1,8 @@ -error: `#[doc(keyword = "...")]` should be used on empty modules - --> $DIR/doc_keyword.rs:6:7 +error: `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute + --> $DIR/doc_keyword.rs:4:8 | -LL | #[doc(keyword = "hell")] - | ^^^^^^^^^^^^^^^^ - -error: `#[doc(keyword = "...")]` should be used on modules - --> $DIR/doc_keyword.rs:11:7 - | -LL | #[doc(keyword = "hall")] - | ^^^^^^^^^^^^^^^^ +LL | #![doc(keyword = "match")] + | ^^^^^^^ error: nonexistent keyword `tadam` used in `#[doc(keyword = "...")]` --> $DIR/doc_keyword.rs:22:17 @@ -18,17 +12,23 @@ LL | #[doc(keyword = "tadam")] | = help: only existing keywords are allowed in core/std +error: `#[doc(keyword = "...")]` should be used on empty modules + --> $DIR/doc_keyword.rs:6:7 + | +LL | #[doc(keyword = "match")] + | ^^^^^^^ + +error: `#[doc(keyword = "...")]` should be used on modules + --> $DIR/doc_keyword.rs:11:7 + | +LL | #[doc(keyword = "match")] + | ^^^^^^^ + error: `#[doc(keyword = "...")]` should be used on modules --> $DIR/doc_keyword.rs:17:11 | LL | #[doc(keyword = "match")] - | ^^^^^^^^^^^^^^^^^ - -error: `#![doc(keyword = "...")]` isn't allowed as a crate-level attribute - --> $DIR/doc_keyword.rs:4:8 - | -LL | #![doc(keyword = "hello")] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/rustdoc/duplicate_doc_alias.stderr b/tests/ui/rustdoc/duplicate_doc_alias.stderr index 4b2dd1f8eb68..eba48ca599b0 100644 --- a/tests/ui/rustdoc/duplicate_doc_alias.stderr +++ b/tests/ui/rustdoc/duplicate_doc_alias.stderr @@ -1,10 +1,10 @@ error: doc alias is duplicated - --> $DIR/duplicate_doc_alias.rs:4:7 + --> $DIR/duplicate_doc_alias.rs:4:15 | LL | #[doc(alias = "A")] - | ----------- first defined here + | --- first defined here LL | #[doc(alias = "A")] - | ^^^^^^^^^^^ + | ^^^ | note: the lint level is defined here --> $DIR/duplicate_doc_alias.rs:1:9 @@ -16,7 +16,7 @@ error: doc alias is duplicated --> $DIR/duplicate_doc_alias.rs:6:13 | LL | #[doc(alias = "B")] - | ----------- first defined here + | --- first defined here LL | #[doc(alias("B"))] | ^^^ diff --git a/tests/ui/sanitize-attr/invalid-sanitize.stderr b/tests/ui/sanitize-attr/invalid-sanitize.stderr index 9c1a6e5c4528..26ef31603d88 100644 --- a/tests/ui/sanitize-attr/invalid-sanitize.stderr +++ b/tests/ui/sanitize-attr/invalid-sanitize.stderr @@ -5,22 +5,6 @@ LL | #[sanitize(brontosaurus = "off")] | ^^^^^^^^^^^------------^^^^^^^^^^ | | | valid arguments are "address", "cfi", "kcfi", "memory", "memtag", "shadow_call_stack", "thread", "hwaddress" or "realtime" - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize(brontosaurus = "off")] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates error: multiple `sanitize` attributes --> $DIR/invalid-sanitize.rs:7:1 @@ -53,62 +37,20 @@ LL | #[sanitize(address = "bogus")] | ^^^^^^^^^^^^^^^^^^^^^-------^^ | | | valid arguments are "on" or "off" - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize(address = "bogus")] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:18:1 | LL | #[sanitize = "off"] - | ^^^^^^^^^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize = "off"] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize = "off"] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize = "off"] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize = "off"] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates + | ^^^^^^^^^^^-------^ + | | + | expected this to be a list error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:21:1 | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL | #[sanitize(address = "on|off")] - | ++++++++++++++++++++ -LL | #[sanitize(cfi = "on|off")] - | ++++++++++++++++ -LL | #[sanitize(hwaddress = "on|off")] - | ++++++++++++++++++++++ -LL | #[sanitize(kcfi = "on|off")] - | +++++++++++++++++ - = and 6 other candidates error[E0539]: malformed `sanitize` attribute input --> $DIR/invalid-sanitize.rs:24:1 @@ -117,22 +59,6 @@ LL | #[sanitize(realtime = "on")] | ^^^^^^^^^^^^^^^^^^^^^^----^^ | | | valid arguments are "nonblocking", "blocking" or "caller" - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(address = "on|off")] - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(cfi = "on|off")] - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(hwaddress = "on|off")] - | -LL - #[sanitize(realtime = "on")] -LL + #[sanitize(kcfi = "on|off")] - | - = and 6 other candidates warning: the async executor can run blocking code, without realtime sanitizer catching it --> $DIR/invalid-sanitize.rs:27:1 diff --git a/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs b/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs new file mode 100644 index 000000000000..6bd995449fc6 --- /dev/null +++ b/tests/ui/sanitizer/cfi/assoc-const-projection-issue-151878.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -Zsanitizer=cfi -Cunsafe-allow-abi-mismatch=sanitizer -Ccodegen-units=1 -Clto +//@ needs-rustc-debug-assertions +//@ needs-sanitizer-cfi +//@ build-pass +//@ no-prefer-dynamic + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + type const N: usize = 0; + fn process(&self, _: [u8; Self::N]) {} +} + +impl Trait for () {} + +fn main() { + let _x: &dyn Trait = &(); +} diff --git a/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr b/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr index 1aa6bef17b1e..e95006c0ef61 100644 --- a/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr +++ b/tests/ui/sanitizer/cfi/invalid-attr-encoding.stderr @@ -1,8 +1,12 @@ -error: malformed `cfi_encoding` attribute input +error[E0539]: malformed `cfi_encoding` attribute input --> $DIR/invalid-attr-encoding.rs:10:1 | LL | #[cfi_encoding] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` + | ^^^^^^^^^^^^^^^ + | | + | expected this to be of the form `cfi_encoding = "..."` + | help: must be of the form: `#[cfi_encoding = "encoding"]` error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs index 8a724b853e13..c3046708e4eb 100644 --- a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs +++ b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.rs @@ -5,7 +5,7 @@ //@ build-fail //@ max-llvm-major-version: 20 -//~? ERROR `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later. +//~? ERROR `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later #![feature(no_core)] #![no_core] #![no_main] diff --git a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr index ac6bd7411fd8..c5f886e3a390 100644 --- a/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr +++ b/tests/ui/sanitizer/kcfi-arity-requires-llvm-21-0-0.stderr @@ -1,4 +1,4 @@ -error: `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later. +error: `-Zsanitizer-kcfi-arity` requires LLVM 21.0.0 or later error: aborting due to 1 previous error diff --git a/tests/ui/scalable-vectors/async.rs b/tests/ui/scalable-vectors/async.rs new file mode 100644 index 000000000000..916c64ee7435 --- /dev/null +++ b/tests/ui/scalable-vectors/async.rs @@ -0,0 +1,44 @@ +//@ only-aarch64 +//@ edition:2021 + +#![allow(incomplete_features, internal_features)] +#![feature( + core_intrinsics, + simd_ffi, + rustc_attrs, + link_llvm_intrinsics +)] + +use core::intrinsics::transmute_unchecked; + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; + } + unsafe { _svdup_n_s32(op) } +} + +#[target_feature(enable = "sve")] +async fn another() -> i32 { + 42 +} + +#[no_mangle] +#[target_feature(enable = "sve")] +pub async fn test_function() { + unsafe { + let x = svdup_n_s32(1); //~ ERROR: scalable vectors cannot be held over await points + let temp = another().await; + let y: svint32_t = transmute_unchecked(x); + } +} + +fn main() { + let _ = unsafe { test_function() }; +} diff --git a/tests/ui/scalable-vectors/async.stderr b/tests/ui/scalable-vectors/async.stderr new file mode 100644 index 000000000000..fa81c7b8ed4d --- /dev/null +++ b/tests/ui/scalable-vectors/async.stderr @@ -0,0 +1,8 @@ +error: scalable vectors cannot be held over await points + --> $DIR/async.rs:36:13 + | +LL | let x = svdup_n_s32(1); + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/scalable-vectors/closure-capture.rs b/tests/ui/scalable-vectors/closure-capture.rs new file mode 100644 index 000000000000..d6a45f76e214 --- /dev/null +++ b/tests/ui/scalable-vectors/closure-capture.rs @@ -0,0 +1,51 @@ +//@ compile-flags: --crate-type=lib +//@ only-aarch64 + +#![allow(incomplete_features, internal_features)] +#![feature( + link_llvm_intrinsics, + rustc_attrs, + simd_ffi +)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[inline(never)] +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; + } + unsafe { _svdup_n_s32(op) } +} + +#[inline] +#[target_feature(enable = "sve,sve2")] +pub unsafe fn svxar_n_s32(op1: svint32_t, op2: svint32_t) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.xar.nxv4i32")] + fn _svxar_n_s32(op1: svint32_t, op2: svint32_t, imm3: i32) -> svint32_t; + } + unsafe { _svxar_n_s32(op1, op2, IMM3) } +} + +#[inline(never)] +#[target_feature(enable = "sve,sve2")] +fn run(f: impl Fn() -> ()) { + f(); +} + +#[target_feature(enable = "sve,sve2")] +fn foo() { + unsafe { + let a = svdup_n_s32(42); + run(move || { +//~^ ERROR: scalable vectors cannot be tuple fields + svxar_n_s32::<2>(a, a); + }); + } +} diff --git a/tests/ui/scalable-vectors/closure-capture.stderr b/tests/ui/scalable-vectors/closure-capture.stderr new file mode 100644 index 000000000000..ea53066988e5 --- /dev/null +++ b/tests/ui/scalable-vectors/closure-capture.stderr @@ -0,0 +1,8 @@ +error: scalable vectors cannot be tuple fields + --> $DIR/closure-capture.rs:46:9 + | +LL | run(move || { + | ^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/scalable-vectors/copy-clone.rs b/tests/ui/scalable-vectors/copy-clone.rs new file mode 100644 index 000000000000..7576b6ec18dc --- /dev/null +++ b/tests/ui/scalable-vectors/copy-clone.rs @@ -0,0 +1,31 @@ +//@ build-pass +//@ only-aarch64 +#![feature(simd_ffi, rustc_attrs, link_llvm_intrinsics)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; +//~^ WARN: `extern` block uses type `svint32_t`, which is not FFI-safe + } + unsafe { _svdup_n_s32(op) } +} + +#[target_feature(enable = "sve")] +fn require_copy(t: T) {} + +#[target_feature(enable = "sve")] +fn test() { + unsafe { + let a = svdup_n_s32(1); + require_copy(a); + } +} + +fn main() {} diff --git a/tests/ui/scalable-vectors/copy-clone.stderr b/tests/ui/scalable-vectors/copy-clone.stderr new file mode 100644 index 000000000000..8b07aba8e1c0 --- /dev/null +++ b/tests/ui/scalable-vectors/copy-clone.stderr @@ -0,0 +1,17 @@ +warning: `extern` block uses type `svint32_t`, which is not FFI-safe + --> $DIR/copy-clone.rs:14:37 + | +LL | fn _svdup_n_s32(op: i32) -> svint32_t; + | ^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/copy-clone.rs:8:1 + | +LL | pub struct svint32_t(i32); + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/scalable-vectors/debuginfo-does-not-spill.rs b/tests/ui/scalable-vectors/debuginfo-does-not-spill.rs new file mode 100644 index 000000000000..f7cc455dc8ef --- /dev/null +++ b/tests/ui/scalable-vectors/debuginfo-does-not-spill.rs @@ -0,0 +1,39 @@ +// Compiletest for rust-lang/rust#150419: Do not spill operands to the stack when +// creating debuginfo for AArch64 SVE predicates `` where `N != 16` +//@ edition: 2021 +//@ only-aarch64 +//@ build-pass +//@ compile-flags: -C debuginfo=2 -C target-feature=+sve + +#![crate_type = "lib"] +#![allow(internal_features)] +#![feature(rustc_attrs, link_llvm_intrinsics)] + +#[rustc_scalable_vector(16)] +#[allow(non_camel_case_types)] +#[repr(transparent)] +pub struct svbool_t(bool); + +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +#[repr(transparent)] +pub struct svbool4_t(bool); + +impl std::convert::Into for svbool4_t { + #[inline(always)] + fn into(self) -> svbool_t { + unsafe extern "C" { + #[link_name = "llvm.aarch64.sve.convert.to.svbool.nxv4i1"] + fn convert_to_svbool(b: svbool4_t) -> svbool_t; + } + unsafe { convert_to_svbool(self) } + } +} + +pub fn svwhilelt_b32_u64(op1: u64, op2: u64) -> svbool_t { + unsafe extern "C" { + #[link_name = "llvm.aarch64.sve.whilelo.nxv4i1.u64"] + fn _svwhilelt_b32_u64(op1: u64, op2: u64) -> svbool4_t; + } + unsafe { _svwhilelt_b32_u64(op1, op2) }.into() +} diff --git a/tests/ui/scalable-vectors/fn-trait.rs b/tests/ui/scalable-vectors/fn-trait.rs new file mode 100644 index 000000000000..5203b5fa0efd --- /dev/null +++ b/tests/ui/scalable-vectors/fn-trait.rs @@ -0,0 +1,13 @@ +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(4)] +pub struct ScalableSimdFloat(f32); + +unsafe fn test(f: T) +where + T: Fn(ScalableSimdFloat), //~ ERROR: scalable vectors cannot be tuple fields +{ +} + +fn main() {} diff --git a/tests/ui/scalable-vectors/fn-trait.stderr b/tests/ui/scalable-vectors/fn-trait.stderr new file mode 100644 index 000000000000..4d00272dd1b5 --- /dev/null +++ b/tests/ui/scalable-vectors/fn-trait.stderr @@ -0,0 +1,8 @@ +error: scalable vectors cannot be tuple fields + --> $DIR/fn-trait.rs:9:8 + | +LL | T: Fn(ScalableSimdFloat), + | ^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/scalable-vectors/illformed-element-type.rs b/tests/ui/scalable-vectors/illformed-element-type.rs new file mode 100644 index 000000000000..469ca006f5e9 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-element-type.rs @@ -0,0 +1,93 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(extern_types)] +#![feature(never_type)] +#![feature(rustc_attrs)] + +struct Foo; +enum Bar {} +union Baz { x: u16 } +extern "C" { + type Qux; +} + +#[rustc_scalable_vector(4)] +struct TyChar(char); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(2)] +struct TyConstPtr(*const u8); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(2)] +struct TyMutPtr(*mut u8); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyStruct(Foo); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyEnum(Bar); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyUnion(Baz); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyForeign(Qux); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyArray([u32; 4]); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TySlice([u32]); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyRef<'a>(&'a u32); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyFnPtr(fn(u32) -> u32); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyDyn(dyn std::io::Write); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyNever(!); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +#[rustc_scalable_vector(4)] +struct TyTuple((u32, u32)); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +type ValidAlias = u32; +type InvalidAlias = String; + +#[rustc_scalable_vector(4)] +struct TyValidAlias(ValidAlias); + +#[rustc_scalable_vector(4)] +struct TyInvalidAlias(InvalidAlias); +//~^ ERROR: element type of a scalable vector must be a primitive scalar + +trait Tr { + type Valid; + type Invalid; +} + +impl Tr for () { + type Valid = u32; + type Invalid = String; +} + +struct TyValidProjection(<() as Tr>::Valid); + +struct TyInvalidProjection(<() as Tr>::Invalid); +// FIXME: element type of a scalable vector must be a primitive scalar diff --git a/tests/ui/scalable-vectors/illformed-element-type.stderr b/tests/ui/scalable-vectors/illformed-element-type.stderr new file mode 100644 index 000000000000..f8ca8b76215f --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-element-type.stderr @@ -0,0 +1,122 @@ +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:15:1 + | +LL | struct TyChar(char); + | ^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:19:1 + | +LL | struct TyConstPtr(*const u8); + | ^^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:23:1 + | +LL | struct TyMutPtr(*mut u8); + | ^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:27:1 + | +LL | struct TyStruct(Foo); + | ^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:31:1 + | +LL | struct TyEnum(Bar); + | ^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:35:1 + | +LL | struct TyUnion(Baz); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:39:1 + | +LL | struct TyForeign(Qux); + | ^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:43:1 + | +LL | struct TyArray([u32; 4]); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:47:1 + | +LL | struct TySlice([u32]); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:51:1 + | +LL | struct TyRef<'a>(&'a u32); + | ^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:55:1 + | +LL | struct TyFnPtr(fn(u32) -> u32); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:59:1 + | +LL | struct TyDyn(dyn std::io::Write); + | ^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:63:1 + | +LL | struct TyNever(!); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:67:1 + | +LL | struct TyTuple((u32, u32)); + | ^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: element type of a scalable vector must be a primitive scalar + --> $DIR/illformed-element-type.rs:77:1 + | +LL | struct TyInvalidAlias(InvalidAlias); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `u*`, `i*`, `f*` and `bool` types are accepted + +error: aborting due to 15 previous errors + diff --git a/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.rs b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.rs new file mode 100644 index 000000000000..4f89a8f9055e --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.rs @@ -0,0 +1,36 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(2)] +struct ValidI64(i64); + +#[rustc_scalable_vector(4)] +struct ValidI32(i32); + +#[rustc_scalable_vector] +struct ValidTuple(ValidI32, ValidI32, ValidI32); + +#[rustc_scalable_vector] +struct Struct { x: ValidI64, y: ValidI64 } +//~^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector] +struct DifferentVectorTypes(ValidI64, ValidI32); +//~^ ERROR: all fields in a scalable vector struct must be the same type + +#[rustc_scalable_vector] +struct NonVectorTypes(u32, u64); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector] +struct DifferentNonVectorTypes(u32, u64); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector] +struct SomeVectorTypes(ValidI64, u64); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector] +struct NestedTuple(ValidTuple, ValidTuple); +//~^ ERROR: scalable vector structs cannot contain other scalable vector structs diff --git a/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.stderr b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.stderr new file mode 100644 index 000000000000..f5fd963204a2 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-tuples-of-scalable-vectors.stderr @@ -0,0 +1,38 @@ +error: scalable vectors must be tuple structs + --> $DIR/illformed-tuples-of-scalable-vectors.rs:15:1 + | +LL | struct Struct { x: ValidI64, y: ValidI64 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: all fields in a scalable vector struct must be the same type + --> $DIR/illformed-tuples-of-scalable-vectors.rs:19:39 + | +LL | struct DifferentVectorTypes(ValidI64, ValidI32); + | ^^^^^^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed-tuples-of-scalable-vectors.rs:23:23 + | +LL | struct NonVectorTypes(u32, u64); + | ^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed-tuples-of-scalable-vectors.rs:27:32 + | +LL | struct DifferentNonVectorTypes(u32, u64); + | ^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed-tuples-of-scalable-vectors.rs:31:34 + | +LL | struct SomeVectorTypes(ValidI64, u64); + | ^^^ + +error: scalable vector structs cannot contain other scalable vector structs + --> $DIR/illformed-tuples-of-scalable-vectors.rs:35:20 + | +LL | struct NestedTuple(ValidTuple, ValidTuple); + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/scalable-vectors/illformed-within-types.rs b/tests/ui/scalable-vectors/illformed-within-types.rs new file mode 100644 index 000000000000..81d960e4d4e1 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-within-types.rs @@ -0,0 +1,23 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(2)] +struct ValidI64(i64); + +struct Struct { + x: ValidI64, +//~^ ERROR: scalable vectors cannot be fields of a struct + in_tuple: (ValidI64,), +//~^ ERROR: scalable vectors cannot be tuple fields +} + +struct TupleStruct(ValidI64); +//~^ ERROR: scalable vectors cannot be fields of a struct + +enum Enum { + StructVariant { _ty: ValidI64 }, +//~^ ERROR: scalable vectors cannot be fields of a variant + TupleVariant(ValidI64), +//~^ ERROR: scalable vectors cannot be fields of a variant +} diff --git a/tests/ui/scalable-vectors/illformed-within-types.stderr b/tests/ui/scalable-vectors/illformed-within-types.stderr new file mode 100644 index 000000000000..e76ef26f2aa4 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed-within-types.stderr @@ -0,0 +1,32 @@ +error: scalable vectors cannot be fields of a struct + --> $DIR/illformed-within-types.rs:9:8 + | +LL | x: ValidI64, + | ^^^^^^^^ + +error: scalable vectors cannot be tuple fields + --> $DIR/illformed-within-types.rs:11:15 + | +LL | in_tuple: (ValidI64,), + | ^^^^^^^^^^^ + +error: scalable vectors cannot be fields of a struct + --> $DIR/illformed-within-types.rs:15:20 + | +LL | struct TupleStruct(ValidI64); + | ^^^^^^^^ + +error: scalable vectors cannot be fields of a variant + --> $DIR/illformed-within-types.rs:19:26 + | +LL | StructVariant { _ty: ValidI64 }, + | ^^^^^^^^ + +error: scalable vectors cannot be fields of a variant + --> $DIR/illformed-within-types.rs:21:18 + | +LL | TupleVariant(ValidI64), + | ^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/scalable-vectors/illformed.rs b/tests/ui/scalable-vectors/illformed.rs new file mode 100644 index 000000000000..de135413a9f2 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed.rs @@ -0,0 +1,59 @@ +//@ compile-flags: --crate-type=lib +#![allow(internal_features)] +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(4)] +struct NoFieldsStructWithElementCount {} +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector(4)] +struct NoFieldsTupleWithElementCount(); +//~^ ERROR: scalable vectors must have a single field + +#[rustc_scalable_vector(4)] +struct NoFieldsUnitWithElementCount; +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector] +struct NoFieldsStructWithoutElementCount {} +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector] +struct NoFieldsTupleWithoutElementCount(); +//~^ ERROR: scalable vectors must have a single field + +#[rustc_scalable_vector] +struct NoFieldsUnitWithoutElementCount; +//~^ ERROR: scalable vectors must have a single field +//~^^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector(4)] +struct MultipleFieldsStructWithElementCount { +//~^ ERROR: scalable vectors cannot have multiple fields +//~^^ ERROR: scalable vectors must be tuple structs + _ty: f32, + other: u32, +} + +#[rustc_scalable_vector(4)] +struct MultipleFieldsTupleWithElementCount(f32, u32); +//~^ ERROR: scalable vectors cannot have multiple fields + +#[rustc_scalable_vector] +struct MultipleFieldsStructWithoutElementCount { +//~^ ERROR: scalable vectors must be tuple structs + _ty: f32, +//~^ ERROR: scalable vector structs can only have scalable vector fields + other: u32, +} + +#[rustc_scalable_vector] +struct MultipleFieldsTupleWithoutElementCount(f32, u32); +//~^ ERROR: scalable vector structs can only have scalable vector fields + +#[rustc_scalable_vector(2)] +struct SingleFieldStruct { _ty: f64 } +//~^ ERROR: scalable vectors must be tuple structs diff --git a/tests/ui/scalable-vectors/illformed.stderr b/tests/ui/scalable-vectors/illformed.stderr new file mode 100644 index 000000000000..bdf519c91058 --- /dev/null +++ b/tests/ui/scalable-vectors/illformed.stderr @@ -0,0 +1,125 @@ +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:6:1 + | +LL | struct NoFieldsStructWithElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:15:1 + | +LL | struct NoFieldsUnitWithElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:20:1 + | +LL | struct NoFieldsStructWithoutElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:29:1 + | +LL | struct NoFieldsUnitWithoutElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:34:1 + | +LL | / struct MultipleFieldsStructWithElementCount { +LL | | +LL | | +LL | | _ty: f32, +LL | | other: u32, +LL | | } + | |_^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:46:1 + | +LL | / struct MultipleFieldsStructWithoutElementCount { +LL | | +LL | | _ty: f32, +... | +LL | | } + | |_^ + +error: scalable vectors must be tuple structs + --> $DIR/illformed.rs:58:1 + | +LL | struct SingleFieldStruct { _ty: f64 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:6:1 + | +LL | struct NoFieldsStructWithElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: scalable vector types' only field must be a primitive scalar type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:11:1 + | +LL | struct NoFieldsTupleWithElementCount(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: scalable vector types' only field must be a primitive scalar type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:15:1 + | +LL | struct NoFieldsUnitWithElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: scalable vector types' only field must be a primitive scalar type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:20:1 + | +LL | struct NoFieldsStructWithoutElementCount {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: tuples of scalable vectors can only contain multiple of the same scalable vector type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:25:1 + | +LL | struct NoFieldsTupleWithoutElementCount(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: tuples of scalable vectors can only contain multiple of the same scalable vector type + +error: scalable vectors must have a single field + --> $DIR/illformed.rs:29:1 + | +LL | struct NoFieldsUnitWithoutElementCount; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: tuples of scalable vectors can only contain multiple of the same scalable vector type + +error: scalable vectors cannot have multiple fields + --> $DIR/illformed.rs:34:1 + | +LL | struct MultipleFieldsStructWithElementCount { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vectors cannot have multiple fields + --> $DIR/illformed.rs:42:1 + | +LL | struct MultipleFieldsTupleWithElementCount(f32, u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed.rs:48:5 + | +LL | _ty: f32, + | ^^^^^^^^ + +error: scalable vector structs can only have scalable vector fields + --> $DIR/illformed.rs:54:47 + | +LL | struct MultipleFieldsTupleWithoutElementCount(f32, u32); + | ^^^ + +error: aborting due to 17 previous errors + diff --git a/tests/ui/scalable-vectors/invalid.rs b/tests/ui/scalable-vectors/invalid.rs new file mode 100644 index 000000000000..90e9839c9e11 --- /dev/null +++ b/tests/ui/scalable-vectors/invalid.rs @@ -0,0 +1,163 @@ +//@ edition: 2024 +#![allow(internal_features, unused_imports, unused_macros)] +#![feature(extern_types)] +#![feature(gen_blocks)] +#![feature(rustc_attrs)] +#![feature(stmt_expr_attributes)] +#![feature(trait_alias)] + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on extern crates +extern crate std as other_std; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on use statements +use std::vec::Vec; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on statics +static _X: u32 = 0; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on constants +const _Y: u32 = 0; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on modules +mod bar { +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign modules +unsafe extern "C" { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign statics + static X: &'static u32; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign types + type Y; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on foreign functions + fn foo(); +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on type aliases +type Foo = u32; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on enums +enum Bar<#[rustc_scalable_vector(4)] T> { +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on type parameters + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on enum variants + Baz(std::marker::PhantomData), +} + +struct Qux { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on struct fields + field: u32, +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on unions +union FooBar { + x: u32, + y: u32, +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on traits +trait FooBaz { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on associated types + type Foo; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on associated consts + const Bar: i32; + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on provided trait methods + fn foo() {} +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on trait aliases +trait FooQux = FooBaz; + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on inherent impl blocks +impl Bar { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on inherent methods + fn foo() {} +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on trait impl blocks +impl FooBaz for Bar { + type Foo = u32; + const Bar: i32 = 3; +} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on macro defs +macro_rules! barqux { ($foo:tt) => { $foo }; } + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +fn barqux(#[rustc_scalable_vector(4)] _x: u32) {} +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on function params +//~^^ ERROR: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +async fn async_foo() {} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +gen fn gen_foo() {} + +#[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on functions +async gen fn async_gen_foo() {} + +fn main() { + let _x = #[rustc_scalable_vector(4)] || { }; +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on closures + let _y = #[rustc_scalable_vector(4)] 3 + 4; +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on expressions + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on statements + let _z = 3; + + match _z { + #[rustc_scalable_vector(4)] +//~^ ERROR: `#[rustc_scalable_vector]` attribute cannot be used on match arms + 1 => (), + _ => (), + } +} + +#[rustc_scalable_vector("4")] +//~^ ERROR: malformed `rustc_scalable_vector` attribute input +struct ArgNotLit(f32); + +#[rustc_scalable_vector(4, 2)] +//~^ ERROR: malformed `rustc_scalable_vector` attribute input +struct ArgMultipleLits(f32); + +#[rustc_scalable_vector(count = "4")] +//~^ ERROR: malformed `rustc_scalable_vector` attribute input +struct ArgKind(f32); + +#[rustc_scalable_vector(65536)] +//~^ ERROR: element count in `rustc_scalable_vector` is too large: `65536` +struct CountTooLarge(f32); + +#[rustc_scalable_vector(4)] +struct Okay(f32); + +#[rustc_scalable_vector] +struct OkayNoArg(f32); +//~^ ERROR: scalable vector structs can only have scalable vector fields diff --git a/tests/ui/scalable-vectors/invalid.stderr b/tests/ui/scalable-vectors/invalid.stderr new file mode 100644 index 000000000000..d73b5abf7030 --- /dev/null +++ b/tests/ui/scalable-vectors/invalid.stderr @@ -0,0 +1,339 @@ +error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + --> $DIR/invalid.rs:109:11 + | +LL | fn barqux(#[rustc_scalable_vector(4)] _x: u32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[rustc_scalable_vector]` attribute cannot be used on extern crates + --> $DIR/invalid.rs:9:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on use statements + --> $DIR/invalid.rs:13:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on statics + --> $DIR/invalid.rs:17:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on constants + --> $DIR/invalid.rs:21:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on modules + --> $DIR/invalid.rs:25:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign modules + --> $DIR/invalid.rs:30:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign statics + --> $DIR/invalid.rs:33:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign types + --> $DIR/invalid.rs:36:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on foreign functions + --> $DIR/invalid.rs:39:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on type aliases + --> $DIR/invalid.rs:44:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on enums + --> $DIR/invalid.rs:48:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on type parameters + --> $DIR/invalid.rs:50:10 + | +LL | enum Bar<#[rustc_scalable_vector(4)] T> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on enum variants + --> $DIR/invalid.rs:52:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on struct fields + --> $DIR/invalid.rs:58:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on unions + --> $DIR/invalid.rs:63:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on traits + --> $DIR/invalid.rs:70:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on associated types + --> $DIR/invalid.rs:73:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on associated consts + --> $DIR/invalid.rs:76:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on provided trait methods + --> $DIR/invalid.rs:79:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on trait aliases + --> $DIR/invalid.rs:84:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on inherent impl blocks + --> $DIR/invalid.rs:88:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on inherent methods + --> $DIR/invalid.rs:91:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on trait impl blocks + --> $DIR/invalid.rs:96:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on macro defs + --> $DIR/invalid.rs:103:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:107:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on function params + --> $DIR/invalid.rs:109:11 + | +LL | fn barqux(#[rustc_scalable_vector(4)] _x: u32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:113:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:117:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on functions + --> $DIR/invalid.rs:121:1 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on closures + --> $DIR/invalid.rs:126:14 + | +LL | let _x = #[rustc_scalable_vector(4)] || { }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on expressions + --> $DIR/invalid.rs:128:14 + | +LL | let _y = #[rustc_scalable_vector(4)] 3 + 4; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on statements + --> $DIR/invalid.rs:130:5 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error: `#[rustc_scalable_vector]` attribute cannot be used on match arms + --> $DIR/invalid.rs:135:9 + | +LL | #[rustc_scalable_vector(4)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_scalable_vector]` can only be applied to structs + +error[E0539]: malformed `rustc_scalable_vector` attribute input + --> $DIR/invalid.rs:142:1 + | +LL | #[rustc_scalable_vector("4")] + | ^^^^^^^^^^^^^^^^^^^^^^^^---^^ + | | + | expected an integer literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_scalable_vector("4")] +LL + #[rustc_scalable_vector(count)] + | +LL - #[rustc_scalable_vector("4")] +LL + #[rustc_scalable_vector] + | + +error[E0805]: malformed `rustc_scalable_vector` attribute input + --> $DIR/invalid.rs:146:1 + | +LL | #[rustc_scalable_vector(4, 2)] + | ^^^^^^^^^^^^^^^^^^^^^^^------^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_scalable_vector(4, 2)] +LL + #[rustc_scalable_vector(count)] + | +LL - #[rustc_scalable_vector(4, 2)] +LL + #[rustc_scalable_vector] + | + +error[E0539]: malformed `rustc_scalable_vector` attribute input + --> $DIR/invalid.rs:150:1 + | +LL | #[rustc_scalable_vector(count = "4")] + | ^^^^^^^^^^^^^^^^^^^^^^^^-----------^^ + | | + | expected an integer literal here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[rustc_scalable_vector(count = "4")] +LL + #[rustc_scalable_vector(count)] + | +LL - #[rustc_scalable_vector(count = "4")] +LL + #[rustc_scalable_vector] + | + +error: element count in `rustc_scalable_vector` is too large: `65536` + --> $DIR/invalid.rs:154:1 + | +LL | #[rustc_scalable_vector(65536)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the value may not exceed `u16::MAX` + +error: scalable vector structs can only have scalable vector fields + --> $DIR/invalid.rs:162:18 + | +LL | struct OkayNoArg(f32); + | ^^^ + +error: aborting due to 39 previous errors + +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/scalable-vectors/require-target-feature.rs b/tests/ui/scalable-vectors/require-target-feature.rs new file mode 100644 index 000000000000..b3c1d3e51007 --- /dev/null +++ b/tests/ui/scalable-vectors/require-target-feature.rs @@ -0,0 +1,40 @@ +//@ build-fail +//@ compile-flags: --crate-type=lib +//@ only-aarch64 +#![allow(incomplete_features, internal_features)] +#![feature( + simd_ffi, + rustc_attrs, + link_llvm_intrinsics +)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[inline(never)] +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; +//~^ WARN: `extern` block uses type `svint32_t`, which is not FFI-safe + } + unsafe { _svdup_n_s32(op) } +} + +pub fn non_annotated_callee(x: svint32_t) {} +//~^ ERROR: this function definition uses scalable vector type `svint32_t` + +#[target_feature(enable = "sve")] +pub fn annotated_callee(x: svint32_t) {} // okay! + +#[target_feature(enable = "sve")] +pub fn caller() { + unsafe { + let a = svdup_n_s32(42); + non_annotated_callee(a); + annotated_callee(a); + } +} diff --git a/tests/ui/scalable-vectors/require-target-feature.stderr b/tests/ui/scalable-vectors/require-target-feature.stderr new file mode 100644 index 000000000000..85b9e5b6579c --- /dev/null +++ b/tests/ui/scalable-vectors/require-target-feature.stderr @@ -0,0 +1,25 @@ +warning: `extern` block uses type `svint32_t`, which is not FFI-safe + --> $DIR/require-target-feature.rs:21:37 + | +LL | fn _svdup_n_s32(op: i32) -> svint32_t; + | ^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/require-target-feature.rs:14:1 + | +LL | pub struct svint32_t(i32); + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default + +error: this function definition uses scalable vector type `svint32_t` which (with the chosen ABI) requires the `sve` target feature, which is not enabled + --> $DIR/require-target-feature.rs:27:1 + | +LL | pub fn non_annotated_callee(x: svint32_t) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here + | + = help: consider enabling it globally (`-C target-feature=+sve`) or locally (`#[target_feature(enable="sve")]`) + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/scalable-vectors/value-type.rs b/tests/ui/scalable-vectors/value-type.rs new file mode 100644 index 000000000000..31a9ee8344eb --- /dev/null +++ b/tests/ui/scalable-vectors/value-type.rs @@ -0,0 +1,37 @@ +//@ build-pass +//@ compile-flags: --crate-type=lib +//@ only-aarch64 +#![allow(internal_features)] +#![feature( + link_llvm_intrinsics, + rustc_attrs, + simd_ffi, +)] + +#[derive(Copy, Clone)] +#[rustc_scalable_vector(4)] +#[allow(non_camel_case_types)] +pub struct svint32_t(i32); + +#[target_feature(enable = "sve")] +pub unsafe fn svdup_n_s32(op: i32) -> svint32_t { + extern "C" { + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.sve.dup.x.nxv4i32")] + fn _svdup_n_s32(op: i32) -> svint32_t; +//~^ WARN: `extern` block uses type `svint32_t`, which is not FFI-safe + } + unsafe { _svdup_n_s32(op) } +} + +// Tests that scalable vectors can be locals, arguments and return types. + +#[target_feature(enable = "sve")] +fn id(v: svint32_t) -> svint32_t { v } + +#[target_feature(enable = "sve")] +fn foo() { + unsafe { + let v = svdup_n_s32(1); + let v = id(v); + } +} diff --git a/tests/ui/scalable-vectors/value-type.stderr b/tests/ui/scalable-vectors/value-type.stderr new file mode 100644 index 000000000000..3fc90ebd874e --- /dev/null +++ b/tests/ui/scalable-vectors/value-type.stderr @@ -0,0 +1,17 @@ +warning: `extern` block uses type `svint32_t`, which is not FFI-safe + --> $DIR/value-type.rs:20:37 + | +LL | fn _svdup_n_s32(op: i32) -> svint32_t; + | ^^^^^^^^^ not FFI-safe + | + = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct + = note: this struct has unspecified layout +note: the type is defined here + --> $DIR/value-type.rs:14:1 + | +LL | pub struct svint32_t(i32); + | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/scalable-vectors/wellformed-arrays.rs b/tests/ui/scalable-vectors/wellformed-arrays.rs new file mode 100644 index 000000000000..b8f0bf291eea --- /dev/null +++ b/tests/ui/scalable-vectors/wellformed-arrays.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(16)] +struct ScalableU8(u8); + +fn main() { + let x: [ScalableU8; 4] = todo!(); +} diff --git a/tests/ui/scalable-vectors/wellformed.rs b/tests/ui/scalable-vectors/wellformed.rs new file mode 100644 index 000000000000..cb6a22d6c433 --- /dev/null +++ b/tests/ui/scalable-vectors/wellformed.rs @@ -0,0 +1,48 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(rustc_attrs)] + +#[rustc_scalable_vector(16)] +struct ScalableU8(u8); + +#[rustc_scalable_vector(8)] +struct ScalableU16(u16); + +#[rustc_scalable_vector(4)] +struct ScalableU32(u32); + +#[rustc_scalable_vector(2)] +struct ScalableU64(u64); + +#[rustc_scalable_vector(1)] +struct ScalableU128(u128); + +#[rustc_scalable_vector(16)] +struct ScalableI8(i8); + +#[rustc_scalable_vector(8)] +struct ScalableI16(i16); + +#[rustc_scalable_vector(4)] +struct ScalableI32(i32); + +#[rustc_scalable_vector(2)] +struct ScalableI64(i64); + +#[rustc_scalable_vector(1)] +struct ScalableI128(i128); + +#[rustc_scalable_vector(8)] +struct ScalableF16(f32); + +#[rustc_scalable_vector(4)] +struct ScalableF32(f32); + +#[rustc_scalable_vector(2)] +struct ScalableF64(f64); + +#[rustc_scalable_vector(16)] +struct ScalableBool(bool); + +#[rustc_scalable_vector] +struct ScalableTuple(ScalableU8, ScalableU8, ScalableU8); diff --git a/tests/ui/self/self-in-method-body-resolves.rs b/tests/ui/self/self-in-method-body-resolves.rs new file mode 100644 index 000000000000..636922cd87ce --- /dev/null +++ b/tests/ui/self/self-in-method-body-resolves.rs @@ -0,0 +1,16 @@ +//! regression test for +//@ check-pass +#![allow(dead_code)] + +struct Foo; + +impl Foo { + fn new() -> Self { + Foo + } + fn bar() { + Self::new(); + } +} + +fn main() {} diff --git a/tests/ui/shadowed/match-binding-shadows-const.rs b/tests/ui/shadowed/match-binding-shadows-const.rs new file mode 100644 index 000000000000..95f2e087b5e7 --- /dev/null +++ b/tests/ui/shadowed/match-binding-shadows-const.rs @@ -0,0 +1,9 @@ +//! regression test for https://github.com/rust-lang/rust/issues/34047 +const C: u8 = 0; + +fn main() { + match 1u8 { + mut C => {} //~ ERROR match bindings cannot shadow constants + _ => {} + } +} diff --git a/tests/ui/shadowed/match-binding-shadows-const.stderr b/tests/ui/shadowed/match-binding-shadows-const.stderr new file mode 100644 index 000000000000..345c67700e62 --- /dev/null +++ b/tests/ui/shadowed/match-binding-shadows-const.stderr @@ -0,0 +1,12 @@ +error[E0530]: match bindings cannot shadow constants + --> $DIR/match-binding-shadows-const.rs:6:13 + | +LL | const C: u8 = 0; + | ---------------- the constant `C` is defined here +... +LL | mut C => {} + | ^ cannot be named the same as a constant + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0530`. diff --git a/tests/ui/simd/dont-invalid-bitcast-masks.rs b/tests/ui/simd/dont-invalid-bitcast-masks.rs index 3d8376207cd0..1e2d097198d0 100644 --- a/tests/ui/simd/dont-invalid-bitcast-masks.rs +++ b/tests/ui/simd/dont-invalid-bitcast-masks.rs @@ -12,6 +12,6 @@ use std::simd::num::*; pub unsafe fn mask_to_array(mask: u8) -> [i32; 8] { let mut output = [0; 8]; let m = masksizex8::from_bitmask(mask as _); - output.copy_from_slice(&m.to_int().cast::().to_array()); + output.copy_from_slice(&m.to_simd().cast::().to_array()); output } diff --git a/tests/ui/simd/extern-static-zero-length.rs b/tests/ui/simd/extern-static-zero-length.rs new file mode 100644 index 000000000000..5ca7b63fc523 --- /dev/null +++ b/tests/ui/simd/extern-static-zero-length.rs @@ -0,0 +1,13 @@ +#![feature(repr_simd)] + +#[repr(simd)] +struct Simd([T; N]); + +unsafe extern "C" { + static VAR: Simd; + //~^ ERROR the SIMD type `Simd` has zero elements + static VAR2: Simd; + //~^ ERROR the SIMD type `Simd` has more elements than the limit 32768 +} + +fn main() {} diff --git a/tests/ui/simd/extern-static-zero-length.stderr b/tests/ui/simd/extern-static-zero-length.stderr new file mode 100644 index 000000000000..49c05f27d8c5 --- /dev/null +++ b/tests/ui/simd/extern-static-zero-length.stderr @@ -0,0 +1,14 @@ +error: the SIMD type `Simd` has zero elements + --> $DIR/extern-static-zero-length.rs:7:17 + | +LL | static VAR: Simd; + | ^^^^^^^^^^^ + +error: the SIMD type `Simd` has more elements than the limit 32768 + --> $DIR/extern-static-zero-length.rs:9:18 + | +LL | static VAR2: Simd; + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs index 680e0dcfd7d6..ee46f4c48502 100644 --- a/tests/ui/simd/intrinsic/generic-elements-pass.rs +++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs @@ -25,7 +25,7 @@ macro_rules! all_eq { }}; } -fn extract_insert_dyn() { +const fn extract_insert_dyn() { let x2 = i32x2::from_array([20, 21]); let x4 = i32x4::from_array([40, 41, 42, 43]); let x8 = i32x8::from_array([80, 81, 82, 83, 84, 85, 86, 87]); @@ -141,6 +141,7 @@ const fn swizzle() { } fn main() { + const { extract_insert_dyn() }; extract_insert_dyn(); const { swizzle() }; swizzle(); diff --git a/tests/ui/simd/intrinsic/splat.rs b/tests/ui/simd/intrinsic/splat.rs new file mode 100644 index 000000000000..38260a124d44 --- /dev/null +++ b/tests/ui/simd/intrinsic/splat.rs @@ -0,0 +1,48 @@ +//@ run-pass +#![feature(repr_simd, core_intrinsics)] + +#[path = "../../../auxiliary/minisimd.rs"] +mod minisimd; +use minisimd::*; + +use std::intrinsics::simd::simd_splat; + +fn main() { + unsafe { + let x: Simd = simd_splat(123u32); + let y: Simd = const { simd_splat(123u32) }; + assert_eq!(x.into_array(), [123; 1]); + assert_eq!(x.into_array(), y.into_array()); + + let x: u16x2 = simd_splat(42u16); + let y: u16x2 = const { simd_splat(42u16) }; + assert_eq!(x.into_array(), [42; 2]); + assert_eq!(x.into_array(), y.into_array()); + + let x: u128x4 = simd_splat(42u128); + let y: u128x4 = const { simd_splat(42u128) }; + assert_eq!(x.into_array(), [42; 4]); + assert_eq!(x.into_array(), y.into_array()); + + let x: i32x4 = simd_splat(-7i32); + let y: i32x4 = const { simd_splat(-7i32) }; + assert_eq!(x.into_array(), [-7; 4]); + assert_eq!(x.into_array(), y.into_array()); + + let x: f32x4 = simd_splat(42.0f32); + let y: f32x4 = const { simd_splat(42.0f32) }; + assert_eq!(x.into_array(), [42.0; 4]); + assert_eq!(x.into_array(), y.into_array()); + + let x: f64x2 = simd_splat(42.0f64); + let y: f64x2 = const { simd_splat(42.0f64) }; + assert_eq!(x.into_array(), [42.0; 2]); + assert_eq!(x.into_array(), y.into_array()); + + static ZERO: u8 = 0u8; + let x: Simd<*const u8, 2> = simd_splat(&raw const ZERO); + let y: Simd<*const u8, 2> = const { simd_splat(&raw const ZERO) }; + assert_eq!(x.into_array(), [&raw const ZERO; 2]); + assert_eq!(x.into_array(), y.into_array()); + } +} diff --git a/tests/ui/simd/portable-intrinsics-arent-exposed.stderr b/tests/ui/simd/portable-intrinsics-arent-exposed.stderr index 043a4ca37618..c7c36c841091 100644 --- a/tests/ui/simd/portable-intrinsics-arent-exposed.stderr +++ b/tests/ui/simd/portable-intrinsics-arent-exposed.stderr @@ -1,11 +1,14 @@ -error[E0433]: failed to resolve: you might be missing crate `core` +error[E0433]: cannot find `core` in the crate root --> $DIR/portable-intrinsics-arent-exposed.rs:5:5 | LL | use core::simd::intrinsics; - | ^^^^ - | | - | you might be missing crate `core` - | help: try using `std` instead of `core`: `std` + | ^^^^ you might be missing crate `core` + | +help: try using `std` instead of `core` + | +LL - use core::simd::intrinsics; +LL + use std::simd::intrinsics; + | error[E0432]: unresolved import `std::simd::intrinsics` --> $DIR/portable-intrinsics-arent-exposed.rs:6:5 diff --git a/tests/ui/simd/target-feature-mixup.rs b/tests/ui/simd/target-feature-mixup.rs index 014a9966f5cb..5f599f38fb92 100644 --- a/tests/ui/simd/target-feature-mixup.rs +++ b/tests/ui/simd/target-feature-mixup.rs @@ -1,13 +1,12 @@ //@ run-pass #![allow(unused_variables)] -#![allow(stable_features)] #![allow(overflowing_literals)] //@ needs-subprocess //@ ignore-fuchsia must translate zircon signal to SIGILL, FIXME (#58590) //@ ignore-backends: gcc -#![feature(repr_simd, target_feature, cfg_target_feature)] +#![feature(repr_simd)] #[path = "../../auxiliary/minisimd.rs"] mod minisimd; diff --git a/tests/ui/single-use-lifetime/issue-104440.rs b/tests/ui/single-use-lifetime/issue-104440.rs index 0795e95303a1..cecd17fb930b 100644 --- a/tests/ui/single-use-lifetime/issue-104440.rs +++ b/tests/ui/single-use-lifetime/issue-104440.rs @@ -8,7 +8,7 @@ mod type_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($T:ident) { fn g<$T: Clone>(t1: $T, t2: T) -> (T, $T) { (t1.clone(), t2.clone()) @@ -40,7 +40,7 @@ mod lifetime_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($a:lifetime) { fn g<$a>(t1: &$a(), t2: &'a ()) -> (&'a (), &$a ()) { (t1, t2) @@ -72,7 +72,7 @@ mod const_params { } } - #[rustc_macro_transparency = "semitransparent"] + #[rustc_macro_transparency = "semiopaque"] macro n($C:ident) { fn g(t1: [(); $C], t2: [(); C]) -> ([(); C], [(); $C]) { (t1, t2) diff --git a/tests/ui/sized-hierarchy/default-bound.stderr b/tests/ui/sized-hierarchy/default-bound.stderr index 0a4ea6f44d8e..9929e2dba524 100644 --- a/tests/ui/sized-hierarchy/default-bound.stderr +++ b/tests/ui/sized-hierarchy/default-bound.stderr @@ -76,7 +76,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known LL | metasized::(); | ^^^ doesn't have a known size | - = help: the trait `MetaSized` is not implemented for `main::Foo` + = help: the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo` note: required by a bound in `metasized` --> $DIR/default-bound.rs:14:17 | diff --git a/tests/ui/sized-hierarchy/impls.stderr b/tests/ui/sized-hierarchy/impls.stderr index ca70822aad28..25c6c933149f 100644 --- a/tests/ui/sized-hierarchy/impls.stderr +++ b/tests/ui/sized-hierarchy/impls.stderr @@ -164,7 +164,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known LL | needs_metasized::(); | ^^^ doesn't have a known size | - = help: the trait `MetaSized` is not implemented for `main::Foo` + = help: the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo` note: required by a bound in `needs_metasized` --> $DIR/impls.rs:16:23 | @@ -222,7 +222,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known LL | needs_metasized::<(Foo, Foo)>(); | ^^^^^^^^^^ doesn't have a known size | - = help: within `(main::Foo, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo` + = help: within `(main::Foo, main::Foo)`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo` = note: required because it appears within the type `(main::Foo, main::Foo)` note: required by a bound in `needs_metasized` --> $DIR/impls.rs:16:23 @@ -273,7 +273,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known LL | needs_metasized::<(u32, Foo)>(); | ^^^^^^^^^^ doesn't have a known size | - = help: within `(u32, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo` + = help: within `(u32, main::Foo)`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo` = note: required because it appears within the type `(u32, main::Foo)` note: required by a bound in `needs_metasized` --> $DIR/impls.rs:16:23 @@ -323,7 +323,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known LL | needs_metasized::(); | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size | - = help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo` + = help: within `StructAllFieldsUnsized`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo` note: required because it appears within the type `StructAllFieldsUnsized` --> $DIR/impls.rs:243:12 | @@ -377,7 +377,7 @@ error[E0277]: the size for values of type `main::Foo` cannot be known LL | needs_metasized::(); | ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size | - = help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo` + = help: within `StructLastFieldUnsized`, the nightly-only, unstable trait `MetaSized` is not implemented for `main::Foo` note: required because it appears within the type `StructLastFieldUnsized` --> $DIR/impls.rs:259:12 | diff --git a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr index ecf4d912be8f..9f9289d0f391 100644 --- a/tests/ui/sized-hierarchy/pretty-print-opaque.stderr +++ b/tests/ui/sized-hierarchy/pretty-print-opaque.stderr @@ -4,7 +4,7 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be kno LL | pub fn pointeesized() -> Box { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size | - = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` + = help: the nightly-only, unstable trait `MetaSized` is not implemented for `impl Tr + PointeeSized` note: required by a bound in `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -32,7 +32,7 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be kno LL | let x = pointeesized(); | ^^^^^^^^^^^^^^ doesn't have a known size | - = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` + = help: the nightly-only, unstable trait `MetaSized` is not implemented for `impl Tr + PointeeSized` note: required by a bound in `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -51,7 +51,7 @@ error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be kno LL | let y: Box = x; | ^ doesn't have a known size | - = help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized` + = help: the nightly-only, unstable trait `MetaSized` is not implemented for `impl Tr + PointeeSized` = note: required for the cast from `Box` to `Box` error: aborting due to 6 previous errors diff --git a/tests/ui/span/E0204.rs b/tests/ui/span/E0204.rs index 8793a05c8a85..841bd5e32b8a 100644 --- a/tests/ui/span/E0204.rs +++ b/tests/ui/span/E0204.rs @@ -4,8 +4,8 @@ struct Foo { impl Copy for Foo { } //~ ERROR cannot be implemented for this type -#[derive(Copy)] //~ ERROR cannot be implemented for this type -struct Foo2<'a> { +#[derive(Copy)] +struct Foo2<'a> { //~ ERROR cannot be implemented for this type ty: &'a mut bool, } @@ -16,8 +16,8 @@ enum EFoo { impl Copy for EFoo { } //~ ERROR cannot be implemented for this type -#[derive(Copy)] //~ ERROR cannot be implemented for this type -enum EFoo2<'a> { +#[derive(Copy)] +enum EFoo2<'a> { //~ ERROR cannot be implemented for this type Bar(&'a mut bool), Baz, } diff --git a/tests/ui/span/E0204.stderr b/tests/ui/span/E0204.stderr index fe375b94781b..a0b51be17863 100644 --- a/tests/ui/span/E0204.stderr +++ b/tests/ui/span/E0204.stderr @@ -8,11 +8,12 @@ LL | impl Copy for Foo { } | ^^^ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/E0204.rs:7:10 + --> $DIR/E0204.rs:8:8 | LL | #[derive(Copy)] - | ^^^^ + | ---- in this derive macro expansion LL | struct Foo2<'a> { + | ^^^^ LL | ty: &'a mut bool, | ---------------- this field does not implement `Copy` @@ -26,11 +27,12 @@ LL | impl Copy for EFoo { } | ^^^^ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/E0204.rs:19:10 + --> $DIR/E0204.rs:20:6 | LL | #[derive(Copy)] - | ^^^^ + | ---- in this derive macro expansion LL | enum EFoo2<'a> { + | ^^^^^ LL | Bar(&'a mut bool), | ------------ this field does not implement `Copy` diff --git a/tests/ui/span/coerce-suggestions.stderr b/tests/ui/span/coerce-suggestions.stderr index 77b01ee08b79..d0f76a23edc4 100644 --- a/tests/ui/span/coerce-suggestions.stderr +++ b/tests/ui/span/coerce-suggestions.stderr @@ -56,8 +56,6 @@ error[E0308]: mismatched types | LL | s = format!("foo"); | ^^^^^^^^^^^^^^ expected `&mut String`, found `String` - | - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/tests/ui/span/issue-15480.stderr b/tests/ui/span/issue-15480.stderr deleted file mode 100644 index 45a5d7dfbecb..000000000000 --- a/tests/ui/span/issue-15480.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/issue-15480.rs:6:10 - | -LL | &id(3) - | ^^^^^ creates a temporary value which is freed while still in use -LL | ]; - | - temporary value is freed at the end of this statement -... -LL | for &&x in &v { - | -- borrow later used here - | -help: consider using a `let` binding to create a longer lived value - | -LL ~ let binding = id(3); -LL ~ let v = vec![ -LL ~ &binding - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/span/issue-33884.stderr b/tests/ui/span/issue-33884.stderr index 29490d86fffe..a5c3e9fa7c45 100644 --- a/tests/ui/span/issue-33884.stderr +++ b/tests/ui/span/issue-33884.stderr @@ -3,8 +3,6 @@ error[E0308]: mismatched types | LL | stream.write_fmt(format!("message received")) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Arguments<'_>`, found `String` - | - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr index eb18969c3c0d..dd57fa061866 100644 --- a/tests/ui/span/issue-39698.stderr +++ b/tests/ui/span/issue-39698.stderr @@ -71,8 +71,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | binding initialized here in some conditions | binding initialized here in some conditions | binding declared here but left uninitialized - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 5 previous errors diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.stderr index 10308ec07da5..f16006a8e085 100644 --- a/tests/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/tests/ui/span/issue-42234-unknown-receiver-type.stderr @@ -16,7 +16,6 @@ error[E0282]: type annotations needed | LL | .sum::<_>() | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` - | error: aborting due to 2 previous errors diff --git a/tests/ui/span/issue-71363.rs b/tests/ui/span/issue-71363.rs index f186e0526a42..4ce8a942c7b1 100644 --- a/tests/ui/span/issue-71363.rs +++ b/tests/ui/span/issue-71363.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z ui-testing=no +//@ compile-flags: -Z ui-testing=no --diagnostic-width=80 struct MyError; impl std::error::Error for MyError {} diff --git a/tests/ui/span/let-offset-of.rs b/tests/ui/span/let-offset-of.rs new file mode 100644 index 000000000000..99b34a192847 --- /dev/null +++ b/tests/ui/span/let-offset-of.rs @@ -0,0 +1,19 @@ +#![crate_type = "rlib"] +//@ edition: 2024 +//@ check-pass + +// Using `offset_of` in the RHS of a let-else statement should not produce +// malformed spans or a blank diagnostic snippet. +// +// Regression test for . + +fn init_to_offset_of() { + use std::mem::offset_of; + struct Foo { field: u32 } + + if let x = offset_of!(Foo, field) {} + //~^ WARN irrefutable `if let` pattern + + let x = offset_of!(Foo, field) else { return; }; + //~^ WARN irrefutable `let...else` pattern +} diff --git a/tests/ui/span/let-offset-of.stderr b/tests/ui/span/let-offset-of.stderr new file mode 100644 index 000000000000..6ea9b2194a36 --- /dev/null +++ b/tests/ui/span/let-offset-of.stderr @@ -0,0 +1,21 @@ +warning: irrefutable `if let` pattern + --> $DIR/let-offset-of.rs:14:8 + | +LL | if let x = offset_of!(Foo, field) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + = note: `#[warn(irrefutable_let_patterns)]` on by default + +warning: irrefutable `let...else` pattern + --> $DIR/let-offset-of.rs:17:5 + | +LL | let x = offset_of!(Foo, field) else { return; }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this pattern will always match, so the `else` clause is useless + = help: consider removing the `else` clause + +warning: 2 warnings emitted + diff --git a/tests/ui/span/macro-span-caller-replacement.rs b/tests/ui/span/macro-span-caller-replacement.rs new file mode 100644 index 000000000000..8e7239699cd1 --- /dev/null +++ b/tests/ui/span/macro-span-caller-replacement.rs @@ -0,0 +1,16 @@ +macro_rules! macro_with_format { () => { + fn check_5(arg : usize) -> String { + let s : &str; + if arg < 5 { + s = format!("{arg}"); //~ ERROR mismatched types + } else { + s = String::new(); //~ ERROR mismatched types + } + String::from(s) + } +}} + +fn main() { + macro_with_format!(); + println!( "{}", check_5(6) ); +} diff --git a/tests/ui/span/macro-span-caller-replacement.stderr b/tests/ui/span/macro-span-caller-replacement.stderr new file mode 100644 index 000000000000..43be48a9e362 --- /dev/null +++ b/tests/ui/span/macro-span-caller-replacement.stderr @@ -0,0 +1,32 @@ +error[E0308]: mismatched types + --> $DIR/macro-span-caller-replacement.rs:5:17 + | +LL | s = format!("{arg}"); + | ^^^^^^^^^^^^^^^^ expected `&str`, found `String` +... +LL | macro_with_format!(); + | -------------------- in this macro invocation + | + = note: this error originates in the macro `format` which comes from the expansion of the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/macro-span-caller-replacement.rs:7:17 + | +LL | let s : &str; + | ---- expected due to this type +... +LL | s = String::new(); + | ^^^^^^^^^^^^^ expected `&str`, found `String` +... +LL | macro_with_format!(); + | -------------------- in this macro invocation + | + = note: this error originates in the macro `macro_with_format` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider borrowing here + | +LL | s = &String::new(); + | + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/span/multiline-span-simple.stderr b/tests/ui/span/multiline-span-simple.stderr index af04ceaf8097..e013b3c06bc1 100644 --- a/tests/ui/span/multiline-span-simple.stderr +++ b/tests/ui/span/multiline-span-simple.stderr @@ -8,13 +8,19 @@ LL | foo(1 as u32 + help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: `u32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&u32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&u32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `u32` implements `Add<&u32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `u32` implements `Add` + = note: `&u32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/span/slice-borrow.stderr b/tests/ui/span/slice-borrow.stderr index 48ac20feea72..6d37019e91b4 100644 --- a/tests/ui/span/slice-borrow.stderr +++ b/tests/ui/span/slice-borrow.stderr @@ -10,7 +10,6 @@ LL | y.use_ref(); | - borrow later used here | = note: consider using a `let` binding to create a longer lived value - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/span/suggestion-raw-68962.stderr b/tests/ui/span/suggestion-raw-68962.stderr index 2e25f5cbdf58..2271acf15a80 100644 --- a/tests/ui/span/suggestion-raw-68962.stderr +++ b/tests/ui/span/suggestion-raw-68962.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find value `fina` in this scope --> $DIR/suggestion-raw-68962.rs:7:5 | LL | fina; - | ^^^^ help: a local variable with a similar name exists: `r#final` + | ^^^^ + | +help: a local variable with a similar name exists + | +LL - fina; +LL + r#final; + | error[E0425]: cannot find function `f` in this scope --> $DIR/suggestion-raw-68962.rs:10:5 @@ -11,7 +17,13 @@ LL | fn r#fn() {} | --------- similarly named function `r#fn` defined here ... LL | f(); - | ^ help: a function with a similar name exists: `r#fn` + | ^ + | +help: a function with a similar name exists + | +LL - f(); +LL + r#fn(); + | error: aborting due to 2 previous errors diff --git a/tests/ui/span/typo-suggestion.stderr b/tests/ui/span/typo-suggestion.stderr index 61d4e06119c4..1f679221c002 100644 --- a/tests/ui/span/typo-suggestion.stderr +++ b/tests/ui/span/typo-suggestion.stderr @@ -8,7 +8,13 @@ error[E0425]: cannot find value `fob` in this scope --> $DIR/typo-suggestion.rs:8:26 | LL | println!("Hello {}", fob); - | ^^^ help: a local variable with a similar name exists: `foo` + | ^^^ + | +help: a local variable with a similar name exists + | +LL - println!("Hello {}", fob); +LL + println!("Hello {}", foo); + | error: aborting due to 2 previous errors diff --git a/tests/ui/span/issue-15480.fixed b/tests/ui/span/vec-macro-outlives-issue-15480.fixed similarity index 100% rename from tests/ui/span/issue-15480.fixed rename to tests/ui/span/vec-macro-outlives-issue-15480.fixed diff --git a/tests/ui/span/issue-15480.rs b/tests/ui/span/vec-macro-outlives-issue-15480.rs similarity index 100% rename from tests/ui/span/issue-15480.rs rename to tests/ui/span/vec-macro-outlives-issue-15480.rs diff --git a/tests/ui/span/vec-macro-outlives-issue-15480.stderr b/tests/ui/span/vec-macro-outlives-issue-15480.stderr new file mode 100644 index 000000000000..7fa9b374ad88 --- /dev/null +++ b/tests/ui/span/vec-macro-outlives-issue-15480.stderr @@ -0,0 +1,21 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/vec-macro-outlives-issue-15480.rs:6:10 + | +LL | &id(3) + | ^^^^^ creates a temporary value which is freed while still in use +LL | ]; + | - temporary value is freed at the end of this statement +... +LL | for &&x in &v { + | -- borrow later used here + | +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = id(3); +LL ~ let v = vec![ +LL ~ &binding + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/span/visibility-ty-params.rs b/tests/ui/span/visibility-ty-params.rs index 05d93e546360..7817d134c77b 100644 --- a/tests/ui/span/visibility-ty-params.rs +++ b/tests/ui/span/visibility-ty-params.rs @@ -4,7 +4,7 @@ macro_rules! m { struct S(T); m!{ crate::S } //~ ERROR unexpected generic arguments in path - //~| ERROR failed to resolve: `S` is a struct, not a module [E0433] + //~| ERROR cannot find mod m { m!{ crate::m<> } //~ ERROR unexpected generic arguments in path diff --git a/tests/ui/span/visibility-ty-params.stderr b/tests/ui/span/visibility-ty-params.stderr index 7b02d79a1bc2..2fda6c70de0d 100644 --- a/tests/ui/span/visibility-ty-params.stderr +++ b/tests/ui/span/visibility-ty-params.stderr @@ -4,7 +4,7 @@ error: unexpected generic arguments in path LL | m!{ crate::S } | ^^^^ -error[E0433]: failed to resolve: `S` is a struct, not a module +error[E0433]: cannot find module `S` in `crate` --> $DIR/visibility-ty-params.rs:6:12 | LL | m!{ crate::S } diff --git a/tests/ui/specialization/const_trait_impl.rs b/tests/ui/specialization/const_trait_impl.rs deleted file mode 100644 index adfef77a15ca..000000000000 --- a/tests/ui/specialization/const_trait_impl.rs +++ /dev/null @@ -1,55 +0,0 @@ -//@ known-bug: #110395 - -#![feature(const_trait_impl, min_specialization, rustc_attrs)] - -use std::fmt::Debug; - -#[rustc_specialization_trait] -pub const unsafe trait Sup { - fn foo() -> u32; -} - -#[rustc_specialization_trait] -pub const unsafe trait Sub: [const] Sup {} - -unsafe impl const Sup for u8 { - default fn foo() -> u32 { - 1 - } -} - -unsafe impl const Sup for () { - fn foo() -> u32 { - 42 - } -} - -unsafe impl const Sub for () {} - -pub const trait A { - fn a() -> u32; -} - -impl const A for T { - default fn a() -> u32 { - 2 - } -} - -impl const A for T { - default fn a() -> u32 { - 3 - } -} - -impl const A for T { - fn a() -> u32 { - T::foo() - } -} - -const _: () = assert!(<()>::a() == 42); -const _: () = assert!(::a() == 3); -const _: () = assert!(::a() == 2); - -fn main() {} diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr deleted file mode 100644 index 93ed7234e563..000000000000 --- a/tests/ui/specialization/const_trait_impl.stderr +++ /dev/null @@ -1,59 +0,0 @@ -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:33:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:39:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:45:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:39:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:33:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: `[const]` can only be applied to `const` traits - --> $DIR/const_trait_impl.rs:45:9 - | -LL | impl const A for T { - | ^^^^^^^ can't be applied to `Debug` - | -note: `Debug` can't be used with `[const]` because it isn't `const` - --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 6 previous errors - diff --git a/tests/ui/specialization/issue-44861.stderr b/tests/ui/specialization/issue-44861.stderr index d184c4468b68..e480f65333fd 100644 --- a/tests/ui/specialization/issue-44861.stderr +++ b/tests/ui/specialization/issue-44861.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `(): CoerceUnsized<*const [u8]>` is not satisfied --> $DIR/issue-44861.rs:21:26 | LL | default type Data2 = (); - | ^^ the trait `CoerceUnsized<*const [u8]>` is not implemented for `()` + | ^^ the nightly-only, unstable trait `CoerceUnsized<*const [u8]>` is not implemented for `()` | note: required by a bound in `Smartass::Data2` --> $DIR/issue-44861.rs:12:17 diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs index edea6f75444f..578a46c67400 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.rs @@ -1,16 +1,15 @@ // Regression test for #140571. The compiler used to ICE -#![feature(associated_const_equality, min_generic_const_args, specialization)] +#![feature(min_generic_const_args, specialization)] //~^ WARN the feature `specialization` is incomplete //~| WARN the feature `min_generic_const_args` is incomplete pub trait IsVoid { - #[type_const] - const IS_VOID: bool; + + type const IS_VOID: bool; } impl IsVoid for T { - #[type_const] - default const IS_VOID: bool = false; + default type const IS_VOID: bool = false; } pub trait NotVoid {} diff --git a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr index bf15d0fae4e5..9361f7d6222f 100644 --- a/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr +++ b/tests/ui/specialization/overlap-due-to-unsatisfied-const-bound.stderr @@ -1,23 +1,23 @@ warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:39 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:12 | -LL | #![feature(associated_const_equality, min_generic_const_args, specialization)] - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #![feature(min_generic_const_args, specialization)] + | ^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #132980 for more information = note: `#[warn(incomplete_features)]` on by default warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:63 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:3:36 | -LL | #![feature(associated_const_equality, min_generic_const_args, specialization)] - | ^^^^^^^^^^^^^^ +LL | #![feature(min_generic_const_args, specialization)] + | ^^^^^^^^^^^^^^ | = note: see issue #31844 for more information = help: consider using `min_specialization` instead, which is more stable and complete error[E0119]: conflicting implementations of trait `Maybe<()>` for type `()` - --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:21:1 + --> $DIR/overlap-due-to-unsatisfied-const-bound.rs:20:1 | LL | impl Maybe for T {} | ---------------------- first implementation here diff --git a/tests/ui/specialization/specialization-default-projection.current.stderr b/tests/ui/specialization/specialization-default-projection.current.stderr index 038c379c43e1..b88c1a94baf9 100644 --- a/tests/ui/specialization/specialization-default-projection.current.stderr +++ b/tests/ui/specialization/specialization-default-projection.current.stderr @@ -21,6 +21,8 @@ LL | () found unit type `()` = help: consider constraining the associated type `::Assoc` to `()` or calling a method that returns `::Assoc` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Assoc` is defined as `()` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:32:5 @@ -37,6 +39,8 @@ LL | generic::<()>() found associated type `<() as Foo>::Assoc` = help: consider constraining the associated type `<() as Foo>::Assoc` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the where-bound `()` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-projection.next.stderr b/tests/ui/specialization/specialization-default-projection.next.stderr index 9111f173a9c8..a385b16a2d8b 100644 --- a/tests/ui/specialization/specialization-default-projection.next.stderr +++ b/tests/ui/specialization/specialization-default-projection.next.stderr @@ -21,6 +21,8 @@ LL | () found unit type `()` = help: consider constraining the associated type `::Assoc` to `()` or calling a method that returns `::Assoc` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Assoc` is defined as `()` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:32:5 @@ -37,6 +39,8 @@ LL | generic::<()>() found associated type `<() as Foo>::Assoc` = help: consider constraining the associated type `<() as Foo>::Assoc` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the where-bound `()` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-types.current.stderr b/tests/ui/specialization/specialization-default-types.current.stderr index 09689681740f..8df170cbb767 100644 --- a/tests/ui/specialization/specialization-default-types.current.stderr +++ b/tests/ui/specialization/specialization-default-types.current.stderr @@ -20,6 +20,8 @@ LL | Box::new(self) | = note: expected associated type `::Output` found struct `Box` + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:29:5 @@ -33,6 +35,8 @@ LL | Example::generate(t) found associated type `::Output` = help: consider constraining the associated type `::Output` to `Box` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-types.next.stderr b/tests/ui/specialization/specialization-default-types.next.stderr index 1535c6473bdd..4ea9b996c86a 100644 --- a/tests/ui/specialization/specialization-default-types.next.stderr +++ b/tests/ui/specialization/specialization-default-types.next.stderr @@ -20,6 +20,8 @@ LL | Box::new(self) | = note: expected associated type `::Output` found struct `Box` + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:29:5 @@ -33,6 +35,8 @@ LL | Example::generate(t) found associated type `::Output` = help: consider constraining the associated type `::Output` to `Box` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/stability-attribute/issue-109177.stderr b/tests/ui/stability-attribute/issue-109177.stderr index 9c2ac591ace0..6f89bde7f894 100644 --- a/tests/ui/stability-attribute/issue-109177.stderr +++ b/tests/ui/stability-attribute/issue-109177.stderr @@ -2,12 +2,18 @@ error[E0425]: cannot find function `foo1` in crate `similar_unstable_method` --> $DIR/issue-109177.rs:7:30 | LL | similar_unstable_method::foo1(); - | ^^^^ help: a function with a similar name exists: `foo` + | ^^^^ | ::: $DIR/auxiliary/similar-unstable-method.rs:5:1 | LL | pub fn foo() {} | ------------ similarly named function `foo` defined here + | +help: a function with a similar name exists + | +LL - similar_unstable_method::foo1(); +LL + similar_unstable_method::foo(); + | error[E0599]: no method named `foo1` found for struct `Foo` in the current scope --> $DIR/issue-109177.rs:11:9 diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-2.rs b/tests/ui/stability-attribute/stability-attribute-sanity-2.rs index 92e300d33d6e..dabff97ad52d 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity-2.rs +++ b/tests/ui/stability-attribute/stability-attribute-sanity-2.rs @@ -7,7 +7,7 @@ #[stable(feature = "a", feature = "b", since = "1.0.0")] //~ ERROR malformed `stable` attribute input [E0538] fn f1() { } -#[stable(feature = "a", sinse = "1.0.0")] //~ ERROR unknown meta item 'sinse' +#[stable(feature = "a", sinse = "1.0.0")] //~ ERROR malformed `stable` attribute input [E0539] fn f2() { } #[unstable(feature = "a", issue = "no")] diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr b/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr index 5b35a51cad72..7beb9fd979ce 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr +++ b/tests/ui/stability-attribute/stability-attribute-sanity-2.stderr @@ -7,11 +7,14 @@ LL | #[stable(feature = "a", feature = "b", since = "1.0.0")] | | found `feature` used as a key more than once | help: must be of the form: `#[stable(feature = "name", since = "version")]` -error[E0541]: unknown meta item 'sinse' - --> $DIR/stability-attribute-sanity-2.rs:10:25 +error[E0539]: malformed `stable` attribute input + --> $DIR/stability-attribute-sanity-2.rs:10:1 | LL | #[stable(feature = "a", sinse = "1.0.0")] - | ^^^^^^^^^^^^^^^ expected one of `feature`, `since` + | ^^^^^^^^^^^^^^^^^^^^^^^^---------------^^ + | | | + | | valid arguments are `feature` or `since` + | help: must be of the form: `#[stable(feature = "name", since = "version")]` error[E0545]: `issue` must be a non-zero numeric string or "none" --> $DIR/stability-attribute-sanity-2.rs:13:27 @@ -23,5 +26,5 @@ LL | #[unstable(feature = "a", issue = "no")] error: aborting due to 3 previous errors -Some errors have detailed explanations: E0538, E0541, E0545. +Some errors have detailed explanations: E0538, E0539, E0545. For more information about an error, try `rustc --explain E0538`. diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr index f656aeaa16c7..9b3f540198ce 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr +++ b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr @@ -11,9 +11,9 @@ error[E0539]: malformed `unstable` attribute input --> $DIR/stability-attribute-sanity-4.rs:11:5 | LL | #[unstable = "b"] - | ^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^-----^ + | | | + | | expected this to be a list | help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]` error[E0539]: malformed `stable` attribute input @@ -29,9 +29,9 @@ error[E0539]: malformed `stable` attribute input --> $DIR/stability-attribute-sanity-4.rs:17:5 | LL | #[stable = "a"] - | ^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^-----^ + | | | + | | expected this to be a list | help: must be of the form: `#[stable(feature = "name", since = "version")]` error[E0542]: missing 'since' diff --git a/tests/ui/stability-attribute/stability-attribute-sanity.rs b/tests/ui/stability-attribute/stability-attribute-sanity.rs index c4c86e12d267..cee8d5fae1d2 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity.rs +++ b/tests/ui/stability-attribute/stability-attribute-sanity.rs @@ -5,7 +5,7 @@ #![stable(feature = "rust1", since = "1.0.0")] mod bogus_attribute_types_1 { - #[stable(feature = "a", since = "4.4.4", reason)] //~ ERROR unknown meta item 'reason' [E0541] + #[stable(feature = "a", since = "4.4.4", reason)] //~ ERROR malformed `stable` attribute input [E0539] fn f1() { } #[stable(feature = "a", since)] //~ ERROR malformed `stable` attribute input [E0539] diff --git a/tests/ui/stability-attribute/stability-attribute-sanity.stderr b/tests/ui/stability-attribute/stability-attribute-sanity.stderr index ae948237d7ed..05c34484b9f8 100644 --- a/tests/ui/stability-attribute/stability-attribute-sanity.stderr +++ b/tests/ui/stability-attribute/stability-attribute-sanity.stderr @@ -1,8 +1,11 @@ -error[E0541]: unknown meta item 'reason' - --> $DIR/stability-attribute-sanity.rs:8:46 +error[E0539]: malformed `stable` attribute input + --> $DIR/stability-attribute-sanity.rs:8:5 | LL | #[stable(feature = "a", since = "4.4.4", reason)] - | ^^^^^^ expected one of `feature`, `since` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ + | | | + | | valid arguments are `feature` or `since` + | help: must be of the form: `#[stable(feature = "name", since = "version")]` error[E0539]: malformed `stable` attribute input --> $DIR/stability-attribute-sanity.rs:11:5 @@ -138,5 +141,5 @@ LL | #[stable(feature = "a", since = "1.0.0")] error: aborting due to 20 previous errors -Some errors have detailed explanations: E0539, E0541, E0542, E0543, E0544, E0546, E0547, E0549, E0711. +Some errors have detailed explanations: E0539, E0542, E0543, E0544, E0546, E0547, E0549, E0711. For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/stability-attribute/stability-in-private-module.rs b/tests/ui/stability-attribute/stability-in-private-module.rs index df94931690b7..000de46ab45e 100644 --- a/tests/ui/stability-attribute/stability-in-private-module.rs +++ b/tests/ui/stability-attribute/stability-in-private-module.rs @@ -1,4 +1,4 @@ fn main() { - let _ = std::sys::os::errno(); + let _ = std::sys::io::errno(); //~^ERROR module `sys` is private } diff --git a/tests/ui/stability-attribute/stability-in-private-module.stderr b/tests/ui/stability-attribute/stability-in-private-module.stderr index e65f8aa9b1fc..ab27f703ab6b 100644 --- a/tests/ui/stability-attribute/stability-in-private-module.stderr +++ b/tests/ui/stability-attribute/stability-in-private-module.stderr @@ -1,7 +1,7 @@ error[E0603]: module `sys` is private --> $DIR/stability-in-private-module.rs:2:18 | -LL | let _ = std::sys::os::errno(); +LL | let _ = std::sys::io::errno(); | ^^^ ----- function `errno` is not publicly re-exported | | | private module diff --git a/tests/ui/static/global-variable-promotion-error-7364.stderr b/tests/ui/static/global-variable-promotion-error-7364.stderr index b9d75676bef8..9f0026621c13 100644 --- a/tests/ui/static/global-variable-promotion-error-7364.stderr +++ b/tests/ui/static/global-variable-promotion-error-7364.stderr @@ -6,7 +6,7 @@ LL | static boxed: Box> = Box::new(RefCell::new(0)); | = help: the trait `Sync` is not implemented for `RefCell` = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead - = note: required for `Unique>` to implement `Sync` + = note: required for `std::ptr::Unique>` to implement `Sync` note: required because it appears within the type `Box>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL = note: shared static variables must have a type that implements `Sync` diff --git a/tests/ui/static/static-align.rs b/tests/ui/static/static-align.rs index e2db7c01adf2..c1c9f79996ed 100644 --- a/tests/ui/static/static-align.rs +++ b/tests/ui/static/static-align.rs @@ -53,7 +53,7 @@ thread_local! { #[allow(unused_mut, reason = "test attribute handling")] #[cfg_attr(TRUE, cfg_attr(FOURTY_TWO = "42", - cfg_attr(all(), + cfg_attr(true, cfg_attr(any(true), cfg_attr(true, rustc_align_static(4096))))))] #[allow(unused_mut, reason = "test attribute handling")] diff --git a/tests/ui/static/static-array-shared-slice-references.rs b/tests/ui/static/static-array-shared-slice-references.rs new file mode 100644 index 000000000000..a2ef169e2a29 --- /dev/null +++ b/tests/ui/static/static-array-shared-slice-references.rs @@ -0,0 +1,10 @@ +//! regression test for +//@ build-pass +#![allow(dead_code)] + +static FOO: [usize; 3] = [1, 2, 3]; + +static SLICE_1: &'static [usize] = &FOO; +static SLICE_2: &'static [usize] = &FOO; + +fn main() {} diff --git a/tests/ui/static/static-initializer-acyclic-issue-146787.rs b/tests/ui/static/static-initializer-acyclic-issue-146787.rs new file mode 100644 index 000000000000..715133bd5d3c --- /dev/null +++ b/tests/ui/static/static-initializer-acyclic-issue-146787.rs @@ -0,0 +1,29 @@ +//@ add-minicore +//@ needs-llvm-components: nvptx +//@ compile-flags: --target nvptx64-nvidia-cuda --emit link +//@ ignore-backends: gcc +#![crate_type = "rlib"] +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct Foo(&'static Foo); +impl Sync for Foo {} + +static A: Foo = Foo(&A); //~ ERROR static initializer forms a cycle involving `A` + +static B0: Foo = Foo(&B1); //~ ERROR static initializer forms a cycle involving `B0` +static B1: Foo = Foo(&B0); + +static C0: Foo = Foo(&C1); //~ ERROR static initializer forms a cycle involving `C0` +static C1: Foo = Foo(&C2); +static C2: Foo = Foo(&C0); + +struct Bar(&'static u32); +impl Sync for Bar {} + +static BAR: Bar = Bar(&INT); +static INT: u32 = 42u32; diff --git a/tests/ui/static/static-initializer-acyclic-issue-146787.stderr b/tests/ui/static/static-initializer-acyclic-issue-146787.stderr new file mode 100644 index 000000000000..af2e4e0f5df8 --- /dev/null +++ b/tests/ui/static/static-initializer-acyclic-issue-146787.stderr @@ -0,0 +1,32 @@ +error: static initializer forms a cycle involving `C0` + --> $DIR/static-initializer-acyclic-issue-146787.rs:21:1 + | +LL | static C0: Foo = Foo(&C1); + | ^^^^^^^^^^^^^^ part of this cycle +LL | static C1: Foo = Foo(&C2); + | -------------- part of this cycle +LL | static C2: Foo = Foo(&C0); + | -------------- part of this cycle + | + = note: cyclic static initializers are not supported for target `nvptx64-nvidia-cuda` + +error: static initializer forms a cycle involving `B0` + --> $DIR/static-initializer-acyclic-issue-146787.rs:18:1 + | +LL | static B0: Foo = Foo(&B1); + | ^^^^^^^^^^^^^^ part of this cycle +LL | static B1: Foo = Foo(&B0); + | -------------- part of this cycle + | + = note: cyclic static initializers are not supported for target `nvptx64-nvidia-cuda` + +error: static initializer forms a cycle involving `A` + --> $DIR/static-initializer-acyclic-issue-146787.rs:16:1 + | +LL | static A: Foo = Foo(&A); + | ^^^^^^^^^^^^^ part of this cycle + | + = note: cyclic static initializers are not supported for target `nvptx64-nvidia-cuda` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/static/static-str-deref-ref.rs b/tests/ui/static/static-str-deref-ref.rs new file mode 100644 index 000000000000..86c37e527657 --- /dev/null +++ b/tests/ui/static/static-str-deref-ref.rs @@ -0,0 +1,5 @@ +//! regression test for +//@ build-pass +#[allow(dead_code)] +static X: &'static str = &*""; +fn main() {} diff --git a/tests/ui/statics/check-immutable-mut-slices.stderr b/tests/ui/statics/check-immutable-mut-slices.stderr index a9486fc9d781..1e6dfb78c93d 100644 --- a/tests/ui/statics/check-immutable-mut-slices.stderr +++ b/tests/ui/statics/check-immutable-mut-slices.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static TEST: &'static mut [isize] = &mut []; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/statics/check-values-constraints.rs b/tests/ui/statics/check-values-constraints.rs index 9df76b5c1497..c62abd75a304 100644 --- a/tests/ui/statics/check-values-constraints.rs +++ b/tests/ui/statics/check-values-constraints.rs @@ -79,8 +79,8 @@ static STATIC10: UnsafeStruct = UnsafeStruct; struct MyOwned; static STATIC11: Vec = vec![MyOwned]; -//~^ ERROR allocations are not allowed in statics -//~^^ ERROR cannot call non-const +//~^ ERROR cannot call non-const function +//~| ERROR cannot call non-const static mut STATIC12: UnsafeStruct = UnsafeStruct; @@ -93,29 +93,29 @@ static mut STATIC14: SafeStruct = SafeStruct { }; static STATIC15: &'static [Vec] = &[ - vec![MyOwned], //~ ERROR allocations are not allowed in statics - //~^ ERROR cannot call non-const - vec![MyOwned], //~ ERROR allocations are not allowed in statics - //~^ ERROR cannot call non-const + vec![MyOwned], //~ ERROR cannot call non-const function + //~| ERROR cannot call non-const + vec![MyOwned], //~ ERROR cannot call non-const function + //~| ERROR cannot call non-const ]; static STATIC16: (&'static Vec, &'static Vec) = ( - &vec![MyOwned], //~ ERROR allocations are not allowed in statics - //~^ ERROR cannot call non-const - &vec![MyOwned], //~ ERROR allocations are not allowed in statics - //~^ ERROR cannot call non-const + &vec![MyOwned], //~ ERROR cannot call non-const function + //~| ERROR cannot call non-const + &vec![MyOwned], //~ ERROR cannot call non-const function + //~| ERROR cannot call non-const ); static mut STATIC17: SafeEnum = SafeEnum::Variant1; static STATIC19: Vec = vec![3]; -//~^ ERROR allocations are not allowed in statics -//~^^ ERROR cannot call non-const +//~^ ERROR cannot call non-const function +//~| ERROR cannot call non-const pub fn main() { let y = { - static x: Vec = vec![3]; //~ ERROR allocations are not allowed in statics - //~^ ERROR cannot call non-const + static x: Vec = vec![3]; //~ ERROR cannot call non-const function + //~| ERROR cannot call non-const x //~^ ERROR cannot move out of static }; diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr index c54f4830533a..94d2b8ce8064 100644 --- a/tests/ui/statics/check-values-constraints.stderr +++ b/tests/ui/statics/check-values-constraints.stderr @@ -11,15 +11,7 @@ LL | | } LL | }; | - value is dropped here -error[E0010]: allocations are not allowed in statics - --> $DIR/check-values-constraints.rs:81:33 - | -LL | static STATIC11: Vec = vec![MyOwned]; - | ^^^^^^^^^^^^^ allocation not allowed in statics - | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0015]: cannot call non-const method `slice::::into_vec::` in statics +error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics --> $DIR/check-values-constraints.rs:81:33 | LL | static STATIC11: Vec = vec![MyOwned]; @@ -27,7 +19,17 @@ LL | static STATIC11: Vec = vec![MyOwned]; | = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics + --> $DIR/check-values-constraints.rs:81:33 + | +LL | static STATIC11: Vec = vec![MyOwned]; + | ^^^^^^^^^^^^^ + | +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0015]: cannot call non-const method `::to_string` in statics --> $DIR/check-values-constraints.rs:92:38 @@ -45,15 +47,7 @@ note: method `to_string` is not const because trait `ToString` is not const = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0010]: allocations are not allowed in statics - --> $DIR/check-values-constraints.rs:96:5 - | -LL | vec![MyOwned], - | ^^^^^^^^^^^^^ allocation not allowed in statics - | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0015]: cannot call non-const method `slice::::into_vec::` in statics +error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics --> $DIR/check-values-constraints.rs:96:5 | LL | vec![MyOwned], @@ -61,17 +55,19 @@ LL | vec![MyOwned], | = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0010]: allocations are not allowed in statics - --> $DIR/check-values-constraints.rs:98:5 +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics + --> $DIR/check-values-constraints.rs:96:5 | LL | vec![MyOwned], - | ^^^^^^^^^^^^^ allocation not allowed in statics + | ^^^^^^^^^^^^^ | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0015]: cannot call non-const method `slice::::into_vec::` in statics +error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics --> $DIR/check-values-constraints.rs:98:5 | LL | vec![MyOwned], @@ -79,17 +75,19 @@ LL | vec![MyOwned], | = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0010]: allocations are not allowed in statics - --> $DIR/check-values-constraints.rs:103:6 +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics + --> $DIR/check-values-constraints.rs:98:5 | -LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ allocation not allowed in statics +LL | vec![MyOwned], + | ^^^^^^^^^^^^^ | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0015]: cannot call non-const method `slice::::into_vec::` in statics +error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics --> $DIR/check-values-constraints.rs:103:6 | LL | &vec![MyOwned], @@ -97,17 +95,19 @@ LL | &vec![MyOwned], | = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0010]: allocations are not allowed in statics - --> $DIR/check-values-constraints.rs:105:6 +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics + --> $DIR/check-values-constraints.rs:103:6 | LL | &vec![MyOwned], - | ^^^^^^^^^^^^^ allocation not allowed in statics + | ^^^^^^^^^^^^^ | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0015]: cannot call non-const method `slice::::into_vec::` in statics +error[E0015]: cannot call non-const associated function `Box::<[MyOwned; 1]>::new_uninit` in statics --> $DIR/check-values-constraints.rs:105:6 | LL | &vec![MyOwned], @@ -115,17 +115,19 @@ LL | &vec![MyOwned], | = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0010]: allocations are not allowed in statics - --> $DIR/check-values-constraints.rs:111:31 +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics + --> $DIR/check-values-constraints.rs:105:6 | -LL | static STATIC19: Vec = vec![3]; - | ^^^^^^^ allocation not allowed in statics +LL | &vec![MyOwned], + | ^^^^^^^^^^^^^ | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0015]: cannot call non-const method `slice::::into_vec::` in statics +error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics --> $DIR/check-values-constraints.rs:111:31 | LL | static STATIC19: Vec = vec![3]; @@ -133,17 +135,19 @@ LL | static STATIC19: Vec = vec![3]; | = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0010]: allocations are not allowed in statics - --> $DIR/check-values-constraints.rs:117:32 +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics + --> $DIR/check-values-constraints.rs:111:31 | -LL | static x: Vec = vec![3]; - | ^^^^^^^ allocation not allowed in statics +LL | static STATIC19: Vec = vec![3]; + | ^^^^^^^ | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` -error[E0015]: cannot call non-const method `slice::::into_vec::` in statics +error[E0015]: cannot call non-const associated function `Box::<[isize; 1]>::new_uninit` in statics --> $DIR/check-values-constraints.rs:117:32 | LL | static x: Vec = vec![3]; @@ -151,7 +155,17 @@ LL | static x: Vec = vec![3]; | = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in statics + --> $DIR/check-values-constraints.rs:117:32 + | +LL | static x: Vec = vec![3]; + | ^^^^^^^ + | +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` error[E0507]: cannot move out of static item `x` --> $DIR/check-values-constraints.rs:119:9 @@ -170,5 +184,5 @@ LL | x.clone() error: aborting due to 17 previous errors -Some errors have detailed explanations: E0010, E0015, E0493, E0507. -For more information about an error, try `rustc --explain E0010`. +Some errors have detailed explanations: E0015, E0493, E0507. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/statics/static-mut-unsafe-init.rs b/tests/ui/statics/static-mut-unsafe-init.rs new file mode 100644 index 000000000000..ee8472100a08 --- /dev/null +++ b/tests/ui/statics/static-mut-unsafe-init.rs @@ -0,0 +1,8 @@ +//! regression test for https://github.com/rust-lang/rust/issues/17450 +//@ build-pass +#![allow(dead_code)] + +static mut X: isize = 3; +static mut Y: isize = unsafe { X }; + +fn main() {} diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr index f2fcb98cb6a9..a91a15bc63df 100644 --- a/tests/ui/stats/input-stats.stderr +++ b/tests/ui/stats/input-stats.stderr @@ -15,7 +15,7 @@ ast-stats - Ptr 64 (NN.N%) 1 ast-stats - Ref 64 (NN.N%) 1 ast-stats - ImplicitSelf 128 (NN.N%) 2 ast-stats - Path 640 (NN.N%) 10 -ast-stats PathSegment 888 (NN.N%) 37 24 +ast-stats PathSegment 864 (NN.N%) 36 24 ast-stats Expr 648 (NN.N%) 9 72 ast-stats - InlineAsm 72 (NN.N%) 1 ast-stats - Match 72 (NN.N%) 1 @@ -41,9 +41,9 @@ ast-stats - Let 32 (NN.N%) 1 ast-stats - Semi 32 (NN.N%) 1 ast-stats - Expr 96 (NN.N%) 3 ast-stats Param 160 (NN.N%) 4 40 -ast-stats Attribute 160 (NN.N%) 5 32 +ast-stats Attribute 128 (NN.N%) 4 32 ast-stats - DocComment 32 (NN.N%) 1 -ast-stats - Normal 128 (NN.N%) 4 +ast-stats - Normal 96 (NN.N%) 3 ast-stats InlineAsm 120 (NN.N%) 1 120 ast-stats FnDecl 120 (NN.N%) 5 24 ast-stats Local 96 (NN.N%) 1 96 @@ -57,7 +57,7 @@ ast-stats GenericArgs 40 (NN.N%) 1 40 ast-stats - AngleBracketed 40 (NN.N%) 1 ast-stats Crate 40 (NN.N%) 1 40 ast-stats ---------------------------------------------------------------- -ast-stats Total 7_616 129 +ast-stats Total 7_560 127 ast-stats ================================================================ hir-stats ================================================================ hir-stats HIR STATS: input_stats @@ -93,7 +93,7 @@ hir-stats GenericParam 400 (NN.N%) 5 80 hir-stats Block 288 (NN.N%) 6 48 hir-stats GenericBound 256 (NN.N%) 4 64 hir-stats - Trait 256 (NN.N%) 4 -hir-stats Attribute 200 (NN.N%) 5 40 +hir-stats Attribute 160 (NN.N%) 4 40 hir-stats Variant 144 (NN.N%) 2 72 hir-stats GenericArgs 144 (NN.N%) 3 48 hir-stats FieldDef 128 (NN.N%) 2 64 @@ -119,5 +119,5 @@ hir-stats TraitItemId 8 (NN.N%) 2 4 hir-stats ImplItemId 8 (NN.N%) 2 4 hir-stats ForeignItemId 4 (NN.N%) 1 4 hir-stats ---------------------------------------------------------------- -hir-stats Total 8_616 173 +hir-stats Total 8_576 172 hir-stats ================================================================ diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index 11a6bfdfcd29..a48940460f91 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -4,11 +4,11 @@ macro-stats Macro Name Uses Lines Avg Lines B macro-stats ----------------------------------------------------------------------------------- macro-stats #[derive(Clone)] 8 67 8.4 1_879 234.9 macro-stats #[derive(PartialOrd)] 1 17 17.0 675 675.0 -macro-stats #[derive(Hash)] 2 17 8.5 577 288.5 +macro-stats #[derive(Hash)] 2 17 8.5 565 282.5 macro-stats q! 1 26 26.0 519 519.0 macro-stats #[derive(Ord)] 1 15 15.0 503 503.0 macro-stats #[derive(Default)] 2 16 8.0 403 201.5 -macro-stats #[derive(Eq)] 1 11 11.0 325 325.0 +macro-stats #[derive(Eq)] 1 11 11.0 319 319.0 macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 macro-stats #[derive(PartialEq)] 1 9 9.0 267 267.0 macro-stats #[derive(Copy)] 1 2 2.0 61 61.0 diff --git a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr index 6a8a7b152c54..93e189ffa0d3 100644 --- a/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr +++ b/tests/ui/stdlib-unit-tests/atomic-from-mut-not-available.alignment_mismatch.stderr @@ -6,6 +6,9 @@ LL | core::sync::atomic::AtomicU64::from_mut(&mut 0u64); | note: if you're trying to build a new `AtomicU64`, consider using `AtomicU64::new` which returns `AtomicU64` --> $SRC_DIR/core/src/sync/atomic.rs:LL:COL + ::: $SRC_DIR/core/src/sync/atomic.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `atomic_int` (in Nightly builds, run with -Z macro-backtrace for more info) help: there is an associated function `from` with a similar name | diff --git a/tests/ui/stdlib-unit-tests/matches2021.rs b/tests/ui/stdlib-unit-tests/matches2021.rs index 78c8be732136..0958e82f43e4 100644 --- a/tests/ui/stdlib-unit-tests/matches2021.rs +++ b/tests/ui/stdlib-unit-tests/matches2021.rs @@ -3,9 +3,7 @@ // regression test for https://github.com/rust-lang/rust/pull/85678 -#![feature(assert_matches)] - -use std::assert_matches::assert_matches; +use std::assert_matches; fn main() { assert!(matches!((), ())); diff --git a/tests/ui/str/raw-string-literal-unescaped-unicode.rs b/tests/ui/str/raw-string-literal-unescaped-unicode.rs new file mode 100644 index 000000000000..c0dc0743a28f --- /dev/null +++ b/tests/ui/str/raw-string-literal-unescaped-unicode.rs @@ -0,0 +1,10 @@ +//! regression test for +//@ check-pass + +fn main() { + assert!({ false }); + + assert!(r"\u{41}" == "A"); + + assert!(r"\u{".is_empty()); +} diff --git a/tests/ui/str/str-add-operator.rs b/tests/ui/str/str-add-operator.rs new file mode 100644 index 000000000000..9c489f2091f8 --- /dev/null +++ b/tests/ui/str/str-add-operator.rs @@ -0,0 +1,7 @@ +//! regression test for issue #47377, #47380 +// ignore-tidy-tab +fn main() { + let b = "hello"; + let _a = b + ", World!"; + //~^ ERROR E0369 +} diff --git a/tests/ui/str/str-add-operator.stderr b/tests/ui/str/str-add-operator.stderr new file mode 100644 index 000000000000..2354819d7fa1 --- /dev/null +++ b/tests/ui/str/str-add-operator.stderr @@ -0,0 +1,18 @@ +error[E0369]: cannot add `&str` to `&str` + --> $DIR/str-add-operator.rs:5:14 + | +LL | let _a = b + ", World!"; + | - ^ ---------- &str + | | | + | | `+` cannot be used to concatenate two `&str` strings + | &str + | + = note: string concatenation requires an owned `String` on the left +help: create an owned `String` from a string reference + | +LL | let _a = b.to_owned() + ", World!"; + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/structs/ice-line-bounds-issue-148684.stderr b/tests/ui/structs/ice-line-bounds-issue-148684.stderr index f26d96cd1172..71ed393bf056 100644 --- a/tests/ui/structs/ice-line-bounds-issue-148684.stderr +++ b/tests/ui/structs/ice-line-bounds-issue-148684.stderr @@ -9,7 +9,6 @@ LL | | } ... LL | A(2, vec![]) | ^^^^^^^^^^^^ - | error: aborting due to 1 previous error diff --git a/tests/ui/structs/parse-error-with-type-param.fixed b/tests/ui/structs/parse-error-with-type-param.fixed new file mode 100644 index 000000000000..46d1c2722843 --- /dev/null +++ b/tests/ui/structs/parse-error-with-type-param.fixed @@ -0,0 +1,14 @@ +//@ run-rustfix +// #141403 +#![allow(dead_code)] + +#[derive(Clone)] +struct B { + a: A<(T, u32)>, // <- note, comma is missing here + /// asdf + //~^ ERROR found a documentation comment that doesn't document anything + b: u32, +} +#[derive(Clone)] +struct A(T); +fn main() {} diff --git a/tests/ui/structs/parse-error-with-type-param.rs b/tests/ui/structs/parse-error-with-type-param.rs new file mode 100644 index 000000000000..27a9fc854f57 --- /dev/null +++ b/tests/ui/structs/parse-error-with-type-param.rs @@ -0,0 +1,14 @@ +//@ run-rustfix +// #141403 +#![allow(dead_code)] + +#[derive(Clone)] +struct B { + a: A<(T, u32)> // <- note, comma is missing here + /// asdf + //~^ ERROR found a documentation comment that doesn't document anything + b: u32, +} +#[derive(Clone)] +struct A(T); +fn main() {} diff --git a/tests/ui/structs/parse-error-with-type-param.stderr b/tests/ui/structs/parse-error-with-type-param.stderr new file mode 100644 index 000000000000..d01eae193b14 --- /dev/null +++ b/tests/ui/structs/parse-error-with-type-param.stderr @@ -0,0 +1,18 @@ +error[E0585]: found a documentation comment that doesn't document anything + --> $DIR/parse-error-with-type-param.rs:8:5 + | +LL | struct B { + | - while parsing this struct +LL | a: A<(T, u32)> // <- note, comma is missing here +LL | /// asdf + | ^^^^^^^^ + | + = help: doc comments must come before what they document, if a comment was intended use `//` +help: missing comma here + | +LL | a: A<(T, u32)>, // <- note, comma is missing here + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0585`. diff --git a/tests/ui/structs/struct-field-cfg.rs b/tests/ui/structs/struct-field-cfg.rs index 42cab8ab916b..84f913927dab 100644 --- a/tests/ui/structs/struct-field-cfg.rs +++ b/tests/ui/structs/struct-field-cfg.rs @@ -3,16 +3,16 @@ struct Foo { } fn main() { - let foo = Foo { #[cfg(all())] present: () }; - let _ = Foo { #[cfg(any())] present: () }; + let foo = Foo { #[cfg(true)] present: () }; + let _ = Foo { #[cfg(false)] present: () }; //~^ ERROR missing field `present` in initializer of `Foo` - let _ = Foo { present: (), #[cfg(any())] absent: () }; - let _ = Foo { present: (), #[cfg(all())] absent: () }; + let _ = Foo { present: (), #[cfg(false)] absent: () }; + let _ = Foo { present: (), #[cfg(true)] absent: () }; //~^ ERROR struct `Foo` has no field named `absent` - let Foo { #[cfg(all())] present: () } = foo; - let Foo { #[cfg(any())] present: () } = foo; + let Foo { #[cfg(true)] present: () } = foo; + let Foo { #[cfg(false)] present: () } = foo; //~^ ERROR pattern does not mention field `present` - let Foo { present: (), #[cfg(any())] absent: () } = foo; - let Foo { present: (), #[cfg(all())] absent: () } = foo; + let Foo { present: (), #[cfg(false)] absent: () } = foo; + let Foo { present: (), #[cfg(true)] absent: () } = foo; //~^ ERROR struct `Foo` does not have a field named `absent` } diff --git a/tests/ui/structs/struct-field-cfg.stderr b/tests/ui/structs/struct-field-cfg.stderr index 2bca6f302db7..db280a632d63 100644 --- a/tests/ui/structs/struct-field-cfg.stderr +++ b/tests/ui/structs/struct-field-cfg.stderr @@ -1,44 +1,44 @@ error[E0063]: missing field `present` in initializer of `Foo` --> $DIR/struct-field-cfg.rs:7:13 | -LL | let _ = Foo { #[cfg(any())] present: () }; +LL | let _ = Foo { #[cfg(false)] present: () }; | ^^^ missing `present` error[E0560]: struct `Foo` has no field named `absent` - --> $DIR/struct-field-cfg.rs:10:46 + --> $DIR/struct-field-cfg.rs:10:45 | -LL | let _ = Foo { present: (), #[cfg(all())] absent: () }; - | ^^^^^^ `Foo` does not have this field +LL | let _ = Foo { present: (), #[cfg(true)] absent: () }; + | ^^^^^^ `Foo` does not have this field | = note: all struct fields are already assigned error[E0027]: pattern does not mention field `present` --> $DIR/struct-field-cfg.rs:13:9 | -LL | let Foo { #[cfg(any())] present: () } = foo; +LL | let Foo { #[cfg(false)] present: () } = foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `present` | help: include the missing field in the pattern | -LL - let Foo { #[cfg(any())] present: () } = foo; +LL - let Foo { #[cfg(false)] present: () } = foo; LL + let Foo { present } = foo; | help: if you don't care about this missing field, you can explicitly ignore it | -LL - let Foo { #[cfg(any())] present: () } = foo; +LL - let Foo { #[cfg(false)] present: () } = foo; LL + let Foo { present: _ } = foo; | help: or always ignore missing fields here | -LL - let Foo { #[cfg(any())] present: () } = foo; +LL - let Foo { #[cfg(false)] present: () } = foo; LL + let Foo { .. } = foo; | error[E0026]: struct `Foo` does not have a field named `absent` - --> $DIR/struct-field-cfg.rs:16:42 + --> $DIR/struct-field-cfg.rs:16:41 | -LL | let Foo { present: (), #[cfg(all())] absent: () } = foo; - | ^^^^^^ struct `Foo` does not have this field +LL | let Foo { present: (), #[cfg(true)] absent: () } = foo; + | ^^^^^^ struct `Foo` does not have this field error: aborting due to 4 previous errors diff --git a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr index b485c17c1b27..5d8321130958 100644 --- a/tests/ui/structs/struct-fields-shorthand-unresolved.stderr +++ b/tests/ui/structs/struct-fields-shorthand-unresolved.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find value `y` in this scope --> $DIR/struct-fields-shorthand-unresolved.rs:10:9 | LL | y - | ^ help: a local variable with a similar name exists: `x` + | ^ + | +help: a local variable with a similar name exists + | +LL - y +LL + x + | error: aborting due to 1 previous error diff --git a/tests/ui/structs/struct-size-with-drop-2895.rs b/tests/ui/structs/struct-size-with-drop-2895.rs new file mode 100644 index 000000000000..9540d340ff68 --- /dev/null +++ b/tests/ui/structs/struct-size-with-drop-2895.rs @@ -0,0 +1,30 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2895 + +//@ run-pass +#![allow(dead_code)] + +use std::mem; + +struct Cat { + x: isize, +} + +struct Kitty { + x: isize, +} + +impl Drop for Kitty { + fn drop(&mut self) {} +} + +#[cfg(target_pointer_width = "64")] +pub fn main() { + assert_eq!(mem::size_of::(), 8 as usize); + assert_eq!(mem::size_of::(), 8 as usize); +} + +#[cfg(target_pointer_width = "32")] +pub fn main() { + assert_eq!(mem::size_of::(), 4 as usize); + assert_eq!(mem::size_of::(), 4 as usize); +} diff --git a/tests/ui/structs/struct-update-syntax-2463.rs b/tests/ui/structs/struct-update-syntax-2463.rs new file mode 100644 index 000000000000..5b2a90a5adf9 --- /dev/null +++ b/tests/ui/structs/struct-update-syntax-2463.rs @@ -0,0 +1,17 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2463 + +//@ run-pass +#![allow(dead_code)] + +struct Pair { + f: isize, + g: isize, +} + +pub fn main() { + let x = Pair { f: 0, g: 0 }; + + let _y = Pair { f: 1, g: 1, ..x }; + + let _z = Pair { f: 1, ..x }; +} diff --git a/tests/ui/suggestions/attribute-typos.stderr b/tests/ui/suggestions/attribute-typos.stderr index 1816a27dcdc8..960e0b0f620f 100644 --- a/tests/ui/suggestions/attribute-typos.stderr +++ b/tests/ui/suggestions/attribute-typos.stderr @@ -8,23 +8,38 @@ error: cannot find attribute `rustc_dumm` in this scope --> $DIR/attribute-typos.rs:7:3 | LL | #[rustc_dumm] - | ^^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_dummy` + | ^^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL | #[rustc_dummy] + | + error: cannot find attribute `tests` in this scope --> $DIR/attribute-typos.rs:4:3 | LL | #[tests] - | ^^^^^ help: an attribute macro with a similar name exists: `test` + | ^^^^^ | --> $SRC_DIR/core/src/macros/mod.rs:LL:COL | = note: similarly named attribute macro `test` defined here +help: an attribute macro with a similar name exists + | +LL - #[tests] +LL + #[test] + | error: cannot find attribute `deprcated` in this scope --> $DIR/attribute-typos.rs:1:3 | LL | #[deprcated] - | ^^^^^^^^^ help: a built-in attribute with a similar name exists: `deprecated` + | ^^^^^^^^^ + | +help: a built-in attribute with a similar name exists + | +LL | #[deprecated] + | + error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/bound-suggestions.stderr b/tests/ui/suggestions/bound-suggestions.stderr index ec1d23fac458..ba792578a202 100644 --- a/tests/ui/suggestions/bound-suggestions.stderr +++ b/tests/ui/suggestions/bound-suggestions.stderr @@ -6,7 +6,6 @@ LL | println!("{:?}", t); | | | required by this formatting parameter | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting opaque type `impl Sized` with trait `Debug` | LL | fn test_impl(t: impl Sized + std::fmt::Debug) { @@ -20,7 +19,6 @@ LL | println!("{:?}", t); | | | required by this formatting parameter | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` with trait `Debug` | LL | fn test_no_bounds(t: T) { @@ -34,7 +32,6 @@ LL | println!("{:?}", t); | | | required by this formatting parameter | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `T` with trait `Debug` | LL | fn test_one_bound(t: T) { @@ -48,7 +45,6 @@ LL | println!("{:?} {:?}", x, y); | | | required by this formatting parameter | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `Y` with trait `Debug` | LL | fn test_no_bounds_where(x: X, y: Y) where X: std::fmt::Debug, Y: std::fmt::Debug { @@ -62,7 +58,6 @@ LL | println!("{:?}", x); | | | required by this formatting parameter | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `X` with trait `Debug` | LL | fn test_one_bound_where(x: X) where X: Sized + std::fmt::Debug { @@ -76,7 +71,6 @@ LL | println!("{:?}", x); | | | required by this formatting parameter | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `X` with trait `Debug` | LL | fn test_many_bounds_where(x: X) where X: Sized + std::fmt::Debug, X: Sized { diff --git a/tests/ui/suggestions/case-difference-suggestions.stderr b/tests/ui/suggestions/case-difference-suggestions.stderr index c3d2410a6eb2..198c3c7a38c9 100644 --- a/tests/ui/suggestions/case-difference-suggestions.stderr +++ b/tests/ui/suggestions/case-difference-suggestions.stderr @@ -2,97 +2,193 @@ error[E0425]: cannot find value `Hello` in this scope --> $DIR/case-difference-suggestions.rs:5:20 | LL | println!("{}", Hello); - | ^^^^^ help: a local variable with a similar name exists: `hello` + | ^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", Hello); +LL + println!("{}", hello); + | error[E0425]: cannot find value `myvariable` in this scope --> $DIR/case-difference-suggestions.rs:9:20 | LL | println!("{}", myvariable); - | ^^^^^^^^^^ help: a local variable with a similar name exists (notice the capitalization): `myVariable` + | ^^^^^^^^^^ + | +help: a local variable with a similar name exists (notice the capitalization) + | +LL - println!("{}", myvariable); +LL + println!("{}", myVariable); + | error[E0425]: cannot find value `User_Name` in this scope --> $DIR/case-difference-suggestions.rs:13:20 | LL | println!("{}", User_Name); - | ^^^^^^^^^ help: a local variable with a similar name exists: `user_name` + | ^^^^^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", User_Name); +LL + println!("{}", user_name); + | error[E0425]: cannot find value `foo` in this scope --> $DIR/case-difference-suggestions.rs:17:20 | LL | println!("{}", foo); - | ^^^ help: a local variable with a similar name exists (notice the capitalization): `FOO` + | ^^^ + | +help: a local variable with a similar name exists (notice the capitalization) + | +LL - println!("{}", foo); +LL + println!("{}", FOO); + | error[E0425]: cannot find value `FFOO` in this scope --> $DIR/case-difference-suggestions.rs:22:20 | LL | println!("{}", FFOO); - | ^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `FFO0` + | ^^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", FFOO); +LL + println!("{}", FFO0); + | error[E0425]: cannot find value `list` in this scope --> $DIR/case-difference-suggestions.rs:25:20 | LL | println!("{}", list); - | ^^^^ help: a local variable with a similar name exists: `l1st` + | ^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", list); +LL + println!("{}", l1st); + | error[E0425]: cannot find value `SS` in this scope --> $DIR/case-difference-suggestions.rs:28:20 | LL | println!("{}", SS); - | ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `S5` + | ^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", SS); +LL + println!("{}", S5); + | error[E0425]: cannot find value `a55` in this scope --> $DIR/case-difference-suggestions.rs:31:20 | LL | println!("{}", a55); - | ^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `aS5` + | ^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", a55); +LL + println!("{}", aS5); + | error[E0425]: cannot find value `BB` in this scope --> $DIR/case-difference-suggestions.rs:34:20 | LL | println!("{}", BB); - | ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `B8` + | ^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", BB); +LL + println!("{}", B8); + | error[E0425]: cannot find value `gg` in this scope --> $DIR/case-difference-suggestions.rs:37:20 | LL | println!("{}", gg); - | ^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `g9` + | ^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", gg); +LL + println!("{}", g9); + | error[E0425]: cannot find value `old` in this scope --> $DIR/case-difference-suggestions.rs:40:20 | LL | println!("{}", old); - | ^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `o1d` + | ^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", old); +LL + println!("{}", o1d); + | error[E0425]: cannot find value `newl` in this scope --> $DIR/case-difference-suggestions.rs:43:20 | LL | println!("{}", newl); - | ^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `new1` + | ^^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", newl); +LL + println!("{}", new1); + | error[E0425]: cannot find value `app1e` in this scope --> $DIR/case-difference-suggestions.rs:46:20 | LL | println!("{}", app1e); - | ^^^^^ help: a local variable with a similar name exists (notice the digit/letter confusion): `apple` + | ^^^^^ + | +help: a local variable with a similar name exists (notice the digit/letter confusion) + | +LL - println!("{}", app1e); +LL + println!("{}", apple); + | error[E0425]: cannot find value `A` in this scope --> $DIR/case-difference-suggestions.rs:49:20 | LL | println!("{}", A); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", A); +LL + println!("{}", a); + | error[E0425]: cannot find value `world1U` in this scope --> $DIR/case-difference-suggestions.rs:52:20 | LL | println!("{}", world1U); - | ^^^^^^^ help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion): `worldlu` + | ^^^^^^^ + | +help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion) + | +LL - println!("{}", world1U); +LL + println!("{}", worldlu); + | error[E0425]: cannot find value `myv4r1able` in this scope --> $DIR/case-difference-suggestions.rs:55:20 | LL | println!("{}", myv4r1able); - | ^^^^^^^^^^ help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion): `myV4rlable` + | ^^^^^^^^^^ + | +help: a local variable with a similar name exists (notice the capitalization and digit/letter confusion) + | +LL - println!("{}", myv4r1able); +LL + println!("{}", myV4rlable); + | error: aborting due to 16 previous errors diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed index b7b94a051212..3ab6ad8b85f5 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.fixed @@ -12,7 +12,7 @@ use core::num::NonZero; fn main() { //~^ HELP consider importing this struct let _x = NonZero::new(5u32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type `NonZero` + //~^ ERROR cannot find type `NonZero` } #[allow(dead_code)] diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr index d73f613bf9c8..37bfb07b2295 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.no_std.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `NonZero` +error[E0433]: cannot find type `NonZero` in this scope --> $DIR/core-std-import-order-issue-83564.rs:12:14 | LL | let _x = NonZero::new(5u32).unwrap(); diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.rs b/tests/ui/suggestions/core-std-import-order-issue-83564.rs index 4cfc9a6bf742..e7a56a44d921 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.rs +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.rs @@ -10,7 +10,7 @@ fn main() { //~^ HELP consider importing this struct let _x = NonZero::new(5u32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type `NonZero` + //~^ ERROR cannot find type `NonZero` } #[allow(dead_code)] diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed b/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed index 84c7c19d19e2..802177578846 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.std.fixed @@ -12,7 +12,7 @@ use std::num::NonZero; fn main() { //~^ HELP consider importing this struct let _x = NonZero::new(5u32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type `NonZero` + //~^ ERROR cannot find type `NonZero` } #[allow(dead_code)] diff --git a/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr b/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr index ebfe197b45d6..ad0ac7859a8d 100644 --- a/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr +++ b/tests/ui/suggestions/core-std-import-order-issue-83564.std.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `NonZero` +error[E0433]: cannot find type `NonZero` in this scope --> $DIR/core-std-import-order-issue-83564.rs:12:14 | LL | let _x = NonZero::new(5u32).unwrap(); diff --git a/tests/ui/suggestions/crate-or-module-typo.rs b/tests/ui/suggestions/crate-or-module-typo.rs index 393fc7a1f72e..8a6df258b452 100644 --- a/tests/ui/suggestions/crate-or-module-typo.rs +++ b/tests/ui/suggestions/crate-or-module-typo.rs @@ -1,9 +1,9 @@ //@ edition:2018 -use st::cell::Cell; //~ ERROR failed to resolve: use of unresolved module or unlinked crate `st` +use st::cell::Cell; //~ ERROR cannot find module or crate `st` mod bar { - pub fn bar() { bar::baz(); } //~ ERROR failed to resolve: function `bar` is not a crate or module + pub fn bar() { bar::baz(); } //~ ERROR cannot find module or crate `bar` fn baz() {} } @@ -11,7 +11,7 @@ mod bar { use bas::bar; //~ ERROR unresolved import `bas` struct Foo { - bar: st::cell::Cell //~ ERROR failed to resolve: use of unresolved module or unlinked crate `st` + bar: st::cell::Cell //~ ERROR cannot find module or crate `st` } fn main() {} diff --git a/tests/ui/suggestions/crate-or-module-typo.stderr b/tests/ui/suggestions/crate-or-module-typo.stderr index 2ec4fc7ed6cc..49ac1c89ab52 100644 --- a/tests/ui/suggestions/crate-or-module-typo.stderr +++ b/tests/ui/suggestions/crate-or-module-typo.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `st` +error[E0433]: cannot find module or crate `st` in this scope --> $DIR/crate-or-module-typo.rs:3:5 | LL | use st::cell::Cell; @@ -21,7 +21,7 @@ LL - use bas::bar; LL + use bar::bar; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `st` +error[E0433]: cannot find module or crate `st` in this scope --> $DIR/crate-or-module-typo.rs:14:10 | LL | bar: st::cell::Cell @@ -41,7 +41,7 @@ LL - bar: st::cell::Cell LL + bar: cell::Cell | -error[E0433]: failed to resolve: function `bar` is not a crate or module +error[E0433]: cannot find module or crate `bar` in this scope --> $DIR/crate-or-module-typo.rs:6:20 | LL | pub fn bar() { bar::baz(); } diff --git a/tests/ui/suggestions/deref-path-method.stderr b/tests/ui/suggestions/deref-path-method.stderr index dc2f6f66437e..0dec424555ed 100644 --- a/tests/ui/suggestions/deref-path-method.stderr +++ b/tests/ui/suggestions/deref-path-method.stderr @@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec<_, _>` consider using one of the foll Vec::::with_capacity Vec::::try_with_capacity Vec::::from_raw_parts - and 6 others + and 7 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: the function `contains` is implemented on `[_]` | diff --git a/tests/ui/suggestions/derive-clone-already-present-issue-146515.rs b/tests/ui/suggestions/derive-clone-already-present-issue-146515.rs new file mode 100644 index 000000000000..78b4c017251e --- /dev/null +++ b/tests/ui/suggestions/derive-clone-already-present-issue-146515.rs @@ -0,0 +1,19 @@ +// issue: https://github.com/rust-lang/rust/issues/146515 + +use std::rc::Rc; + +#[derive(Clone)] //~ NOTE in this expansion +struct ContainsRc { //~ NOTE derive introduces an implicit `T: Clone` bound + value: Rc, +} + +fn clone_me(x: &ContainsRc) -> ContainsRc { + //~^ NOTE expected `ContainsRc` because of return type + x.clone() + //~^ ERROR mismatched types + //~| NOTE expected `ContainsRc`, found `&ContainsRc` + //~| NOTE expected struct `ContainsRc<_>` + //~| NOTE `ContainsRc` does not implement `Clone`, so `&ContainsRc` was cloned instead +} + +fn main() {} diff --git a/tests/ui/suggestions/derive-clone-already-present-issue-146515.stderr b/tests/ui/suggestions/derive-clone-already-present-issue-146515.stderr new file mode 100644 index 000000000000..6ecf4e7ca943 --- /dev/null +++ b/tests/ui/suggestions/derive-clone-already-present-issue-146515.stderr @@ -0,0 +1,28 @@ +error[E0308]: mismatched types + --> $DIR/derive-clone-already-present-issue-146515.rs:12:5 + | +LL | fn clone_me(x: &ContainsRc) -> ContainsRc { + | ------------- expected `ContainsRc` because of return type +LL | +LL | x.clone() + | ^^^^^^^^^ expected `ContainsRc`, found `&ContainsRc` + | + = note: expected struct `ContainsRc<_>` + found reference `&ContainsRc<_>` +note: `ContainsRc` does not implement `Clone`, so `&ContainsRc` was cloned instead + --> $DIR/derive-clone-already-present-issue-146515.rs:12:5 + | +LL | x.clone() + | ^ +help: `Clone` is not implemented because a trait bound is not satisfied + --> $DIR/derive-clone-already-present-issue-146515.rs:6:19 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct ContainsRc { + | ^ derive introduces an implicit `T: Clone` bound + = help: consider manually implementing `Clone` to avoid the implicit type parameter bounds + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/suggestions/derive-clone-for-eq.fixed b/tests/ui/suggestions/derive-clone-for-eq.fixed index 4dc362f94787..17259dd687c6 100644 --- a/tests/ui/suggestions/derive-clone-for-eq.fixed +++ b/tests/ui/suggestions/derive-clone-for-eq.fixed @@ -1,8 +1,8 @@ //@ run-rustfix // https://github.com/rust-lang/rust/issues/79076 -#[derive(Clone, Eq)] //~ ERROR [E0277] -pub struct Struct(T); +#[derive(Clone, Eq)] +pub struct Struct(T); //~ ERROR [E0277] impl PartialEq for Struct where diff --git a/tests/ui/suggestions/derive-clone-for-eq.rs b/tests/ui/suggestions/derive-clone-for-eq.rs index b3635000f165..3e4331745be8 100644 --- a/tests/ui/suggestions/derive-clone-for-eq.rs +++ b/tests/ui/suggestions/derive-clone-for-eq.rs @@ -1,8 +1,8 @@ //@ run-rustfix // https://github.com/rust-lang/rust/issues/79076 -#[derive(Clone, Eq)] //~ ERROR [E0277] -pub struct Struct(T); +#[derive(Clone, Eq)] +pub struct Struct(T); //~ ERROR [E0277] impl PartialEq for Struct where diff --git a/tests/ui/suggestions/derive-clone-for-eq.stderr b/tests/ui/suggestions/derive-clone-for-eq.stderr index eb0355853daa..bed5ff90c194 100644 --- a/tests/ui/suggestions/derive-clone-for-eq.stderr +++ b/tests/ui/suggestions/derive-clone-for-eq.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/derive-clone-for-eq.rs:4:17 + --> $DIR/derive-clone-for-eq.rs:5:12 | LL | #[derive(Clone, Eq)] - | ^^ the trait `Clone` is not implemented for `T` + | -- in this derive macro expansion +LL | pub struct Struct(T); + | ^^^^^^ the trait `Clone` is not implemented for `T` | note: required for `Struct` to implement `PartialEq` --> $DIR/derive-clone-for-eq.rs:7:19 diff --git a/tests/ui/suggestions/derive-trait-for-method-call.stderr b/tests/ui/suggestions/derive-trait-for-method-call.stderr index ae3a0391eea2..0e25b09fedb3 100644 --- a/tests/ui/suggestions/derive-trait-for-method-call.stderr +++ b/tests/ui/suggestions/derive-trait-for-method-call.stderr @@ -25,11 +25,14 @@ LL | impl Foo { | | | unsatisfied trait bound introduced here | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced here -note: the trait `Default` must be implemented - --> $SRC_DIR/core/src/default.rs:LL:COL -help: consider annotating `Enum` with `#[derive(Clone)]` +help: consider annotating `CloneEnum` with `#[derive(Default)]` | -LL + #[derive(Clone)] +LL + #[derive(Default)] +LL | enum CloneEnum { + | +help: consider annotating `Enum` with `#[derive(Clone, Default)]` + | +LL + #[derive(Clone, Default)] LL | enum Enum { | diff --git a/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr b/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr index 112ed6fffd50..e54e5acffe8f 100644 --- a/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr +++ b/tests/ui/suggestions/do-not-attempt-to-add-suggestions-with-no-changes.stderr @@ -2,11 +2,16 @@ error[E0573]: expected type, found module `result` --> $DIR/do-not-attempt-to-add-suggestions-with-no-changes.rs:3:6 | LL | impl result { - | ^^^^^^ help: an enum with a similar name exists: `Result` + | ^^^^^^ | --> $SRC_DIR/core/src/result.rs:LL:COL | = note: similarly named enum `Result` defined here +help: an enum with a similar name exists + | +LL - impl result { +LL + impl Result { + | error[E0573]: expected type, found variant `Err` --> $DIR/do-not-attempt-to-add-suggestions-with-no-changes.rs:4:25 diff --git a/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr b/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr index 46613e8e1b48..0ed657c7fa99 100644 --- a/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr +++ b/tests/ui/suggestions/dont-suggest-deref-inside-macro-issue-58298.stderr @@ -1,10 +1,13 @@ error[E0308]: mismatched types - --> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:11:5 + --> $DIR/dont-suggest-deref-inside-macro-issue-58298.rs:5:14 | +LL | warn(format!("unsupported intrinsic {}", $intrinsic)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `String` +... LL | / intrinsic_match! { LL | | "abc" LL | | }; - | |_____^ expected `&str`, found `String` + | |_____- in this macro invocation | = note: this error originates in the macro `format` which comes from the expansion of the macro `intrinsic_match` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/suggestions/fn-trait-notation.stderr b/tests/ui/suggestions/fn-trait-notation.stderr index 9b47c8c02a78..ef7d5fe36282 100644 --- a/tests/ui/suggestions/fn-trait-notation.stderr +++ b/tests/ui/suggestions/fn-trait-notation.stderr @@ -32,7 +32,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple --> $DIR/fn-trait-notation.rs:4:8 | LL | F: Fn, - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -47,7 +47,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/fn-trait-notation.rs:9:5 | LL | f(3); - | ^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` error[E0308]: mismatched types --> $DIR/fn-trait-notation.rs:17:5 diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr index 8bb2bb290d3d..2521341723a2 100644 --- a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr @@ -11,7 +11,7 @@ LL | std::ptr::from_ref(num).cast_mut().as_deref(); | ^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see = note: `#[warn(tyvar_behind_raw_pointer)]` (part of `#[warn(rust_2018_compatibility)]`) on by default warning: type annotations needed @@ -21,7 +21,7 @@ LL | std::ptr::from_ref(num).cast_mut().as_deref(); | ^^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see error[E0599]: no method named `as_deref` found for raw pointer `*mut _` in the current scope --> $DIR/ice-unwrap-probe-many-result-125876.rs:5:40 diff --git a/tests/ui/suggestions/issue-102354.stderr b/tests/ui/suggestions/issue-102354.stderr index 8340d9340f9b..9354ce3efe57 100644 --- a/tests/ui/suggestions/issue-102354.stderr +++ b/tests/ui/suggestions/issue-102354.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `func` found for type `i32` in the current scope --> $DIR/issue-102354.rs:9:7 | LL | x.func(); - | --^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `i32::func()` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `Trait` @@ -13,6 +10,11 @@ note: the candidate is defined in the trait `Trait` | LL | fn func() {} | ^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.func(); +LL + i32::func(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-103112.rs b/tests/ui/suggestions/issue-103112.rs index 111ae7c73080..795fe60fd693 100644 --- a/tests/ui/suggestions/issue-103112.rs +++ b/tests/ui/suggestions/issue-103112.rs @@ -1,4 +1,4 @@ fn main() { std::process::abort!(); - //~^ ERROR: failed to resolve + //~^ ERROR: cannot find } diff --git a/tests/ui/suggestions/issue-103112.stderr b/tests/ui/suggestions/issue-103112.stderr index b7de57bfd90e..b644eff920d6 100644 --- a/tests/ui/suggestions/issue-103112.stderr +++ b/tests/ui/suggestions/issue-103112.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `abort` in `process` +error[E0433]: cannot find `abort` in `process` --> $DIR/issue-103112.rs:2:19 | LL | std::process::abort!(); diff --git a/tests/ui/suggestions/issue-103646.stderr b/tests/ui/suggestions/issue-103646.stderr index 8d0e8652392d..42505e13e7e6 100644 --- a/tests/ui/suggestions/issue-103646.stderr +++ b/tests/ui/suggestions/issue-103646.stderr @@ -4,10 +4,7 @@ error[E0599]: no method named `nya` found for type parameter `T` in the current LL | fn uwu(c: T) { | - method `nya` not found for this type parameter LL | c.nya(); - | --^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `T::nya()` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `Cat` @@ -15,6 +12,11 @@ note: the candidate is defined in the trait `Cat` | LL | fn nya() {} | ^^^^^^^^ +help: use associated function syntax instead + | +LL - c.nya(); +LL + T::nya(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-112590-suggest-import.rs b/tests/ui/suggestions/issue-112590-suggest-import.rs index a7868b719190..ec7a3cbac1de 100644 --- a/tests/ui/suggestions/issue-112590-suggest-import.rs +++ b/tests/ui/suggestions/issue-112590-suggest-import.rs @@ -1,8 +1,9 @@ pub struct S; -impl fmt::Debug for S { //~ ERROR failed to resolve: use of unresolved module or unlinked crate `fmt` - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { //~ ERROR failed to resolve: use of unresolved module or unlinked crate `fmt` - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `fmt` +impl fmt::Debug for S { //~ ERROR: cannot find module or crate `fmt` + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + //~^ ERROR: cannot find module or crate `fmt` + //~| ERROR: cannot find module or crate `fmt` Ok(()) } } diff --git a/tests/ui/suggestions/issue-112590-suggest-import.stderr b/tests/ui/suggestions/issue-112590-suggest-import.stderr index bbbd2c481c1c..b44b59bea181 100644 --- a/tests/ui/suggestions/issue-112590-suggest-import.stderr +++ b/tests/ui/suggestions/issue-112590-suggest-import.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `fmt` +error[E0433]: cannot find module or crate `fmt` in this scope --> $DIR/issue-112590-suggest-import.rs:3:6 | LL | impl fmt::Debug for S { @@ -10,7 +10,7 @@ help: consider importing this module LL + use std::fmt; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `fmt` +error[E0433]: cannot find module or crate `fmt` in this scope --> $DIR/issue-112590-suggest-import.rs:4:28 | LL | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -22,7 +22,7 @@ help: consider importing this module LL + use std::fmt; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `fmt` +error[E0433]: cannot find module or crate `fmt` in this scope --> $DIR/issue-112590-suggest-import.rs:4:51 | LL | fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr index ce0087fbfcba..b55353c9e6e4 100644 --- a/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr +++ b/tests/ui/suggestions/issue-66968-suggest-sorted-words.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find value `a_variable_longer_name` in this scope --> $DIR/issue-66968-suggest-sorted-words.rs:3:20 | LL | println!("{}", a_variable_longer_name); - | ^^^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `a_longer_variable_name` + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: a local variable with a similar name exists + | +LL - println!("{}", a_variable_longer_name); +LL + println!("{}", a_longer_variable_name); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr index 9e068c311ae0..b8a240f7f07c 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr @@ -13,7 +13,7 @@ LL | let _: &[i8] = data.into(); `[T; 6]` implements `From<(T, T, T, T, T, T)>` `[T; 7]` implements `From<(T, T, T, T, T, T, T)>` `[T; 8]` implements `From<(T, T, T, T, T, T, T, T)>` - and 6 others + and 7 others = note: required for `&[u8]` to implement `Into<&[i8]>` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-72766.stderr b/tests/ui/suggestions/issue-72766.stderr index f0680dfe19f7..03aad995b966 100644 --- a/tests/ui/suggestions/issue-72766.stderr +++ b/tests/ui/suggestions/issue-72766.stderr @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | SadGirl {}.call()?; | ^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl Future>` | - = help: the trait `Try` is not implemented for `impl Future>` + = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>` help: consider `await`ing on the `Future` | LL | SadGirl {}.call().await?; diff --git a/tests/ui/suggestions/issue-97704.stderr b/tests/ui/suggestions/issue-97704.stderr index a7284db1d956..e20c68057eb7 100644 --- a/tests/ui/suggestions/issue-97704.stderr +++ b/tests/ui/suggestions/issue-97704.stderr @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | func(async { Ok::<_, i32>(()) })?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl Future>` | - = help: the trait `Try` is not implemented for `impl Future>` + = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>` help: consider `await`ing on the `Future` | LL | func(async { Ok::<_, i32>(()) }).await?; diff --git a/tests/ui/suggestions/issue-97760.stderr b/tests/ui/suggestions/issue-97760.stderr index c3cf7e13987b..f3dc3f74efe8 100644 --- a/tests/ui/suggestions/issue-97760.stderr +++ b/tests/ui/suggestions/issue-97760.stderr @@ -6,7 +6,6 @@ LL | println!("{x}"); | = help: the trait `std::fmt::Display` is not implemented for `::Item` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: introduce a type parameter with a trait bound instead of using `impl Trait` | LL ~ pub fn print_values(values: &I) diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index a48dd30d008a..791e2d19f2f9 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -24,12 +24,13 @@ LL | pub loc: Vector2, | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Debug` - --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:10 + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ^^^^^^^ ---- unsatisfied trait bound + = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider further restricting type parameter `K` with trait `Copy` | @@ -65,12 +66,13 @@ LL | pub size: Vector2, | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Clone` - --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23 + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ^^^^^^^ ---- unsatisfied trait bound + = help: consider manually implementing `Clone` to avoid undesired bounds help: consider further restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed index 74df1d7c7cfd..bd1785e35112 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed @@ -7,8 +7,8 @@ pub struct Vector2{ pub y: T } -#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB{ +#[derive(Debug, Copy, Clone)] +pub struct AABB { //~ ERROR the trait `Copy` cannot be implemented for this type pub loc: Vector2, //~ ERROR `K` doesn't implement `Debug` //~^ ERROR `K` doesn't implement `Debug` pub size: Vector2 //~ ERROR `K` doesn't implement `Debug` diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs index 8550a4d72476..36502044bd46 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs @@ -7,8 +7,8 @@ pub struct Vector2{ pub y: T } -#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB{ +#[derive(Debug, Copy, Clone)] +pub struct AABB { //~ ERROR the trait `Copy` cannot be implemented for this type pub loc: Vector2, //~ ERROR `K` doesn't implement `Debug` //~^ ERROR `K` doesn't implement `Debug` pub size: Vector2 //~ ERROR `K` doesn't implement `Debug` diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr index e3375b67c86d..cc80e7297e48 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr @@ -1,9 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/missing-bound-in-derive-copy-impl-3.rs:10:17 + --> $DIR/missing-bound-in-derive-copy-impl-3.rs:11:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ -LL | pub struct AABB{ + | ---- in this derive macro expansion +LL | pub struct AABB { + | ^^^^ LL | pub loc: Vector2, | ------------------- this field does not implement `Copy` | @@ -14,7 +15,7 @@ LL | pub loc: Vector2, | ^^^^^^^^^^ help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++ error[E0277]: `K` doesn't implement `Debug` @@ -30,7 +31,7 @@ LL | pub struct Vector2{ | ^^^^^ required by this bound in `Vector2` help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++++++++++++ error[E0277]: `K` doesn't implement `Debug` @@ -38,13 +39,13 @@ error[E0277]: `K` doesn't implement `Debug` | LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion -LL | pub struct AABB{ +LL | pub struct AABB { LL | pub loc: Vector2, | ^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `K` | help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++++++++++++ error[E0277]: `K` doesn't implement `Debug` @@ -58,7 +59,7 @@ LL | pub size: Vector2 | help: consider further restricting type parameter `K` with trait `Debug` | -LL | pub struct AABB{ +LL | pub struct AABB { | +++++++++++++++++ error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs index 0ffc1b8f7a25..60a9074e5c0d 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs @@ -6,8 +6,8 @@ pub struct Vector2 { pub y: T, } -#[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type -pub struct AABB { +#[derive(Debug, Copy, Clone)] +pub struct AABB { //~ ERROR the trait `Copy` cannot be implemented for this type pub loc: Vector2, //~^ ERROR doesn't implement `Debug` //~| ERROR `K: Copy` is not satisfied diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index 645d6ebb3961..55d6391f975e 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -1,9 +1,10 @@ error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/missing-bound-in-derive-copy-impl.rs:9:17 + --> $DIR/missing-bound-in-derive-copy-impl.rs:10:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^ + | ---- in this derive macro expansion LL | pub struct AABB { + | ^^^^ LL | pub loc: Vector2, | ------------------- this field does not implement `Copy` | @@ -59,12 +60,13 @@ LL | pub loc: Vector2, | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Debug` - --> $DIR/missing-bound-in-derive-copy-impl.rs:3:10 + --> $DIR/missing-bound-in-derive-copy-impl.rs:4:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ^^^^^^^ ---- unsatisfied trait bound + = help: consider manually implementing `Debug` to avoid undesired bounds = note: required for the cast from `&Vector2` to `&dyn Debug` help: consider restricting type parameter `K` with trait `Copy` | @@ -128,12 +130,13 @@ LL | pub size: Vector2, | ^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | note: required for `Vector2` to implement `Clone` - --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23 + --> $DIR/missing-bound-in-derive-copy-impl.rs:4:12 | LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ + | ----- in this derive macro expansion LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ^^^^^^^ ---- unsatisfied trait bound + = help: consider manually implementing `Clone` to avoid undesired bounds help: consider restricting type parameter `K` with trait `Copy` | LL | pub struct AABB { diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr index c2ae19b1ae9a..2da0f9bd12c2 100644 --- a/tests/ui/suggestions/multi-suggestion.ascii.stderr +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -5,6 +5,7 @@ LL | let _ = std::collections::HashMap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + ::: $SRC_DIR/std/src/collections/hash/map.rs:LL:COL | = note: `std::collections::HashMap` defined here help: you might have meant to use an associated function to build this type @@ -12,14 +13,15 @@ help: you might have meant to use an associated function to build this type LL | let _ = std::collections::HashMap::new(); | +++++ LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap(); LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL | let _ = ::default(); @@ -73,7 +75,7 @@ LL - })), LL + wtf: Some(::default()), | -error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields +error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields --> $DIR/multi-suggestion.rs:19:13 | LL | let _ = std::collections::HashMap {}; @@ -86,14 +88,15 @@ LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::new(); | LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new_in(_); + | +LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::with_capacity(_); | LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_hasher(_); - | -LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); | + = and 4 other candidates help: consider using the `Default` trait | LL - let _ = std::collections::HashMap {}; diff --git a/tests/ui/suggestions/multi-suggestion.rs b/tests/ui/suggestions/multi-suggestion.rs index 99d2407aa212..6d822a8e5aff 100644 --- a/tests/ui/suggestions/multi-suggestion.rs +++ b/tests/ui/suggestions/multi-suggestion.rs @@ -17,6 +17,6 @@ fn main() { let _ = std::collections::HashMap(); //[ascii]~^ ERROR expected function, tuple struct or tuple variant, found struct `std::collections::HashMap` let _ = std::collections::HashMap {}; - //[ascii]~^ ERROR cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields + //[ascii]~^ ERROR cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields let _ = Box {}; //[ascii]~ ERROR cannot construct `Box<_, _>` with struct literal syntax due to private fields } diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr index fc187cac91d1..69529b67b775 100644 --- a/tests/ui/suggestions/multi-suggestion.unicode.stderr +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -5,6 +5,7 @@ LL │ let _ = std::collections::HashMap(); │ â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â”â” â•°â•´ â•­â–¸ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL + ⸬ $SRC_DIR/std/src/collections/hash/map.rs:LL:COL │ â•° note: `std::collections::HashMap` defined here help: you might have meant to use an associated function to build this type @@ -12,14 +13,15 @@ help: you might have meant to use an associated function to build this type LL │ let _ = std::collections::HashMap::new(); ├╴ +++++ LL - let _ = std::collections::HashMap(); +LL + let _ = std::collections::HashMap::new_in(_); + ├╴ +LL - let _ = std::collections::HashMap(); LL + let _ = std::collections::HashMap::with_capacity(_); ├╴ LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_hasher(_); - ├╴ -LL - let _ = std::collections::HashMap(); -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); - â•°â•´ +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); + │ + â•° and 4 other candidates help: consider using the `Default` trait â•­â•´ LL │ let _ = ::default(); @@ -73,7 +75,7 @@ LL - })), LL + wtf: Some(::default()), â•°â•´ -error: cannot construct `HashMap<_, _, _>` with struct literal syntax due to private fields +error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to private fields â•­â–¸ $DIR/multi-suggestion.rs:19:13 │ LL │ let _ = std::collections::HashMap {}; @@ -86,14 +88,15 @@ LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::new(); ├╴ LL - let _ = std::collections::HashMap {}; +LL + let _ = std::collections::HashMap::new_in(_); + ├╴ +LL - let _ = std::collections::HashMap {}; LL + let _ = std::collections::HashMap::with_capacity(_); ├╴ LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_hasher(_); - ├╴ -LL - let _ = std::collections::HashMap {}; -LL + let _ = std::collections::HashMap::with_capacity_and_hasher(_, _); - â•°â•´ +LL + let _ = std::collections::HashMap::with_capacity_in(_, _); + │ + â•° and 4 other candidates help: consider using the `Default` trait â•­â•´ LL - let _ = std::collections::HashMap {}; diff --git a/tests/ui/suggestions/path-display.stderr b/tests/ui/suggestions/path-display.stderr index 0c7271b3c1c3..df9e855bb714 100644 --- a/tests/ui/suggestions/path-display.stderr +++ b/tests/ui/suggestions/path-display.stderr @@ -10,7 +10,6 @@ LL | println!("{}", path); = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: call `.display()` or `.to_string_lossy()` to safely print paths, as they may contain non-Unicode data = note: required for `&Path` to implement `std::fmt::Display` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `PathBuf` doesn't implement `std::fmt::Display` --> $DIR/path-display.rs:9:20 @@ -23,7 +22,6 @@ LL | println!("{}", path); = help: the trait `std::fmt::Display` is not implemented for `PathBuf` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: call `.display()` or `.to_string_lossy()` to safely print paths, as they may contain non-Unicode data - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr index aa96159aacf5..9f34d2747881 100644 --- a/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr +++ b/tests/ui/suggestions/semi-suggestion-when-stmt-and-expr-span-equal.stderr @@ -21,14 +21,14 @@ LL | .collect::(); | = help: the trait `FromIterator<()>` is not implemented for `String` = help: the following other types implement trait `FromIterator`: - `String` implements `FromIterator<&Char>` `String` implements `FromIterator<&char>` + `String` implements `FromIterator<&std::ascii::Char>` `String` implements `FromIterator<&str>` `String` implements `FromIterator>` - `String` implements `FromIterator` `String` implements `FromIterator>` `String` implements `FromIterator` `String` implements `FromIterator` + `String` implements `FromIterator` note: the method call chain might not have had the expected associated types --> $DIR/semi-suggestion-when-stmt-and-expr-span-equal.rs:20:10 | diff --git a/tests/ui/suggestions/slice-issue-87994.stderr b/tests/ui/suggestions/slice-issue-87994.stderr index 22ad5d352120..dd5c00af90b2 100644 --- a/tests/ui/suggestions/slice-issue-87994.stderr +++ b/tests/ui/suggestions/slice-issue-87994.stderr @@ -17,11 +17,10 @@ error[E0277]: `[i32]` is not an iterator --> $DIR/slice-issue-87994.rs:3:12 | LL | for _ in v[1..] { - | ^^^^^^ the trait `IntoIterator` is not implemented for `[i32]` + | ^^^^^^ the trait `Sized` is not implemented for `[i32]` | - = note: the trait bound `[i32]: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `[i32]` to implement `IntoIterator` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for _ in &v[1..] { @@ -48,11 +47,10 @@ error[E0277]: `[K]` is not an iterator --> $DIR/slice-issue-87994.rs:11:13 | LL | for i2 in v2[1..] { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `[K]` + | ^^^^^^^ the trait `Sized` is not implemented for `[K]` | - = note: the trait bound `[K]: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `[K]` to implement `IntoIterator` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider borrowing here | LL | for i2 in &v2[1..] { diff --git a/tests/ui/suggestions/struct-lit-placeholder-path.rs b/tests/ui/suggestions/struct-lit-placeholder-path.rs new file mode 100644 index 000000000000..190440dd1569 --- /dev/null +++ b/tests/ui/suggestions/struct-lit-placeholder-path.rs @@ -0,0 +1,21 @@ +// Regression test for issue #98282. + +mod blah { + pub struct Stuff { x: i32 } + pub fn do_stuff(_: Stuff) {} +} + +fn main() { + blah::do_stuff(_ { x: 10 }); + //~^ ERROR placeholder `_` is not allowed for the path in struct literals + //~| NOTE not allowed in struct literals + //~| HELP replace it with the correct type +} + +#[cfg(FALSE)] +fn disabled() { + blah::do_stuff(_ { x: 10 }); + //~^ ERROR placeholder `_` is not allowed for the path in struct literals + //~| NOTE not allowed in struct literals + //~| HELP replace it with the correct type +} diff --git a/tests/ui/suggestions/struct-lit-placeholder-path.stderr b/tests/ui/suggestions/struct-lit-placeholder-path.stderr new file mode 100644 index 000000000000..8cd24b6f268d --- /dev/null +++ b/tests/ui/suggestions/struct-lit-placeholder-path.stderr @@ -0,0 +1,26 @@ +error: placeholder `_` is not allowed for the path in struct literals + --> $DIR/struct-lit-placeholder-path.rs:9:20 + | +LL | blah::do_stuff(_ { x: 10 }); + | ^ not allowed in struct literals + | +help: replace it with the correct type + | +LL - blah::do_stuff(_ { x: 10 }); +LL + blah::do_stuff(/* Type */ { x: 10 }); + | + +error: placeholder `_` is not allowed for the path in struct literals + --> $DIR/struct-lit-placeholder-path.rs:17:20 + | +LL | blah::do_stuff(_ { x: 10 }); + | ^ not allowed in struct literals + | +help: replace it with the correct type + | +LL - blah::do_stuff(_ { x: 10 }); +LL + blah::do_stuff(/* Type */ { x: 10 }); + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr index a30b78692146..2314ff378f64 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-deref.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `test` found for struct `Box>` in the cur --> $DIR/suggest-assoc-fn-call-deref.rs:13:7 | LL | x.test(); - | --^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `Foo::::test()` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `Foo` @@ -13,6 +10,11 @@ note: the candidate is defined in an impl for the type `Foo` | LL | fn test() -> i32 { 1 } | ^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.test(); +LL + Foo::::test(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr index 0df2b08d3be8..4ff4c50f1790 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.stderr @@ -5,10 +5,7 @@ LL | struct A { | -------- method `foo` not found for this struct ... LL | _a.foo(); - | ---^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::foo(_a)` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `M` @@ -16,6 +13,11 @@ note: the candidate is defined in the trait `M` | LL | fn foo(_a: Self); | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.foo(); +LL + A::foo(_a); + | error[E0599]: no method named `baz` found for struct `A` in the current scope --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:23:8 @@ -24,10 +26,7 @@ LL | struct A { | -------- method `baz` not found for this struct ... LL | _a.baz(0); - | ---^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::baz(0)` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `M` @@ -35,6 +34,11 @@ note: the candidate is defined in the trait `M` | LL | fn baz(_a: i32); | ^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.baz(0); +LL + A::baz(0); + | error[E0599]: no method named `bar` found for struct `A` in the current scope --> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:27:8 @@ -43,10 +47,7 @@ LL | struct A { | -------- method `bar` not found for this struct ... LL | _b.bar(); - | ---^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::bar(_b)` + | ^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `M` @@ -54,6 +55,11 @@ note: the candidate is defined in the trait `M` | LL | fn bar(_a: Self); | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _b.bar(); +LL + A::bar(_b); + | error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr index 6e4c77deac50..df8d80c4babf 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-placeholder.stderr @@ -5,10 +5,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct ... LL | x.default_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::default_hello()` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -16,6 +13,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.default_hello(); +LL + GenericAssocMethod::<_>::default_hello(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr index 1bc259294469..99d206764a17 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish-through-deref.stderr @@ -2,10 +2,7 @@ error[E0599]: no method named `hello` found for struct `RefMut<'_, HasAssocMetho --> $DIR/suggest-assoc-fn-call-with-turbofish-through-deref.rs:11:11 | LL | state.hello(); - | ------^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `HasAssocMethod::hello()` + | ^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `HasAssocMethod` @@ -13,6 +10,11 @@ note: the candidate is defined in an impl for the type `HasAssocMethod` | LL | fn hello() {} | ^^^^^^^^^^ +help: use associated function syntax instead + | +LL - state.hello(); +LL + HasAssocMethod::hello(); + | error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index 92b03fc77142..56d6b9fcd143 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -5,10 +5,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | x.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_ref_hello(&x)` + | ^^^^^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -16,6 +13,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.self_ty_ref_hello(); +LL + GenericAssocMethod::<_>::self_ty_ref_hello(&x); + | error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod<{integer}>` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:16:7 @@ -24,10 +26,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | x.self_ty_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::<_>::self_ty_hello(x)` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -35,6 +34,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_hello(_: Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - x.self_ty_hello(); +LL + GenericAssocMethod::<_>::self_ty_hello(x); + | error[E0599]: no method named `default_hello` found for struct `GenericAssocMethod` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:20:7 @@ -43,10 +47,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `default_hello` not found for this struct ... LL | y.default_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::default_hello()` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -54,6 +55,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn default_hello() {} | ^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - y.default_hello(); +LL + GenericAssocMethod::::default_hello(); + | error[E0599]: no method named `self_ty_ref_hello` found for struct `GenericAssocMethod` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:22:7 @@ -62,10 +68,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_ref_hello` not found for this struct ... LL | y.self_ty_ref_hello(); - | --^^^^^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_ref_hello(&y)` + | ^^^^^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -73,6 +76,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_ref_hello(_: &Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - y.self_ty_ref_hello(); +LL + GenericAssocMethod::::self_ty_ref_hello(&y); + | error[E0599]: no method named `self_ty_hello` found for struct `GenericAssocMethod` in the current scope --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:24:7 @@ -81,10 +89,7 @@ LL | struct GenericAssocMethod(T); | ---------------------------- method `self_ty_hello` not found for this struct ... LL | y.self_ty_hello(); - | --^^^^^^^^^^^^^-- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `GenericAssocMethod::::self_ty_hello(y)` + | ^^^^^^^^^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `GenericAssocMethod` @@ -92,6 +97,11 @@ note: the candidate is defined in an impl for the type `GenericAssocMethod` | LL | fn self_ty_hello(_: Self) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - y.self_ty_hello(); +LL + GenericAssocMethod::::self_ty_hello(y); + | error: aborting due to 5 previous errors diff --git a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr index 793595784d93..a09cf41488df 100644 --- a/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr +++ b/tests/ui/suggestions/suggest-assoc-fn-call-without-receiver.stderr @@ -5,10 +5,7 @@ LL | struct A {} | -------- method `hello` not found for this struct ... LL | _a.hello(1); - | ---^^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::hello(1)` + | ^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `A` @@ -16,6 +13,11 @@ note: the candidate is defined in an impl for the type `A` | LL | fn hello(_a: i32) {} | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.hello(1); +LL + A::hello(1); + | error[E0599]: no method named `test` found for struct `A` in the current scope --> $DIR/suggest-assoc-fn-call-without-receiver.rs:22:8 @@ -24,10 +26,7 @@ LL | struct A {} | -------- method `test` not found for this struct ... LL | _a.test(1); - | ---^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `A::test(_a, 1)` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `A` @@ -35,6 +34,11 @@ note: the candidate is defined in an impl for the type `A` | LL | fn test(_a: Self, _b: i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _a.test(1); +LL + A::test(_a, 1); + | error[E0599]: no method named `hello` found for struct `B<&str>` in the current scope --> $DIR/suggest-assoc-fn-call-without-receiver.rs:26:8 @@ -43,10 +47,7 @@ LL | struct B { | ----------- method `hello` not found for this struct ... LL | _b.hello(1); - | ---^^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `B::<&str>::hello(1)` + | ^^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `B` @@ -54,6 +55,11 @@ note: the candidate is defined in an impl for the type `B` | LL | fn hello(_a: i32) {} | ^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _b.hello(1); +LL + B::<&str>::hello(1); + | error[E0599]: no method named `test` found for struct `B<&str>` in the current scope --> $DIR/suggest-assoc-fn-call-without-receiver.rs:28:8 @@ -62,10 +68,7 @@ LL | struct B { | ----------- method `test` not found for this struct ... LL | _b.test(1); - | ---^^^^--- - | | | - | | this is an associated function, not a method - | help: use associated function syntax instead: `B::<&str>::test(_b, 1)` + | ^^^^ this is an associated function, not a method | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in an impl for the type `B` @@ -73,6 +76,11 @@ note: the candidate is defined in an impl for the type `B` | LL | fn test(_a: Self, _b: i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use associated function syntax instead + | +LL - _b.test(1); +LL + B::<&str>::test(_b, 1); + | error: aborting due to 4 previous errors diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index 1e8beaa3711e..541c625ebb10 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -13,8 +13,6 @@ help: the following other types implement trait `SliceIndex` | = note: `usize` implements `SliceIndex` = note: required for `[{integer}]` to implement `Index<&usize>` - = note: 1 redundant requirement hidden - = note: required for `[{integer}; 3]` to implement `Index<&usize>` help: dereference this index | LL | let one_item_please: i32 = [1, 2, 3][*i]; diff --git a/tests/ui/suggestions/suggest-derive-default-for-enums.rs b/tests/ui/suggestions/suggest-derive-default-for-enums.rs new file mode 100644 index 000000000000..a75123c27d18 --- /dev/null +++ b/tests/ui/suggestions/suggest-derive-default-for-enums.rs @@ -0,0 +1,15 @@ +// A test showing that we suggest deriving `Default` for enums. +enum MyEnum { + A, +} + +trait Foo { + fn bar(&self) {} +} +impl Foo for T {} + +fn main() { + let x = MyEnum::A; + x.bar(); + //~^ ERROR the method `bar` exists for enum `MyEnum`, but its trait bounds were not satisfied +} diff --git a/tests/ui/suggestions/suggest-derive-default-for-enums.stderr b/tests/ui/suggestions/suggest-derive-default-for-enums.stderr new file mode 100644 index 000000000000..977535c83dae --- /dev/null +++ b/tests/ui/suggestions/suggest-derive-default-for-enums.stderr @@ -0,0 +1,25 @@ +error[E0599]: the method `bar` exists for enum `MyEnum`, but its trait bounds were not satisfied + --> $DIR/suggest-derive-default-for-enums.rs:13:7 + | +LL | enum MyEnum { + | ----------- method `bar` not found for this enum because it doesn't satisfy `MyEnum: Default` or `MyEnum: Foo` +... +LL | x.bar(); + | ^^^ method cannot be called on `MyEnum` due to unsatisfied trait bounds + | +note: trait bound `MyEnum: Default` was not satisfied + --> $DIR/suggest-derive-default-for-enums.rs:9:9 + | +LL | impl Foo for T {} + | ^^^^^^^ --- - + | | + | unsatisfied trait bound introduced here +help: consider annotating `MyEnum` with `#[derive(Default)]` + | +LL + #[derive(Default)] +LL | enum MyEnum { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.rs b/tests/ui/suggestions/suggest-tryinto-edition-change.rs index f45670ae7c1e..06675a8e530b 100644 --- a/tests/ui/suggestions/suggest-tryinto-edition-change.rs +++ b/tests/ui/suggestions/suggest-tryinto-edition-change.rs @@ -8,17 +8,17 @@ fn test() { //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021 let _i: i16 = TryFrom::try_from(0_i32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type + //~^ ERROR cannot find //~| NOTE use of undeclared type //~| NOTE 'std::convert::TryFrom' is included in the prelude starting in Edition 2021 let _i: i16 = TryInto::try_into(0_i32).unwrap(); - //~^ ERROR failed to resolve: use of undeclared type + //~^ ERROR cannot find //~| NOTE use of undeclared type //~| NOTE 'std::convert::TryInto' is included in the prelude starting in Edition 2021 let _v: Vec<_> = FromIterator::from_iter(&[1]); - //~^ ERROR failed to resolve: use of undeclared type + //~^ ERROR cannot find //~| NOTE use of undeclared type //~| NOTE 'std::iter::FromIterator' is included in the prelude starting in Edition 2021 } diff --git a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr index 8ab8a1716b14..b0d150f49c73 100644 --- a/tests/ui/suggestions/suggest-tryinto-edition-change.stderr +++ b/tests/ui/suggestions/suggest-tryinto-edition-change.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `TryFrom` +error[E0433]: cannot find type `TryFrom` in this scope --> $DIR/suggest-tryinto-edition-change.rs:10:19 | LL | let _i: i16 = TryFrom::try_from(0_i32).unwrap(); @@ -10,7 +10,7 @@ help: consider importing this trait LL + use std::convert::TryFrom; | -error[E0433]: failed to resolve: use of undeclared type `TryInto` +error[E0433]: cannot find type `TryInto` in this scope --> $DIR/suggest-tryinto-edition-change.rs:15:19 | LL | let _i: i16 = TryInto::try_into(0_i32).unwrap(); @@ -22,7 +22,7 @@ help: consider importing this trait LL + use std::convert::TryInto; | -error[E0433]: failed to resolve: use of undeclared type `FromIterator` +error[E0433]: cannot find type `FromIterator` in this scope --> $DIR/suggest-tryinto-edition-change.rs:20:22 | LL | let _v: Vec<_> = FromIterator::from_iter(&[1]); diff --git a/tests/ui/suggestions/suggest-variants.rs b/tests/ui/suggestions/suggest-variants.rs index dd05d0f04abe..d3bd3c2c8e87 100644 --- a/tests/ui/suggestions/suggest-variants.rs +++ b/tests/ui/suggestions/suggest-variants.rs @@ -16,3 +16,26 @@ fn main() { Shape::Circl; //~ ERROR no variant Shape::Rombus; //~ ERROR no variant } + +enum Color { + Red, + Green(()), + Blue, + Alpha{ a: u8 }, +} + +fn red() -> Result { + Ok(Color::Redd) //~ ERROR no variant +} + +fn green() -> Result { + Ok(Color::Greenn(())) //~ ERROR no variant +} + +fn blue() -> Result { + Ok(Color::Blu) //~ ERROR no variant +} + +fn alpha() -> Result { + Ok(Color::Alph{ a: 255 }) //~ ERROR no variant +} diff --git a/tests/ui/suggestions/suggest-variants.stderr b/tests/ui/suggestions/suggest-variants.stderr index 50286a968759..13518a9d5842 100644 --- a/tests/ui/suggestions/suggest-variants.stderr +++ b/tests/ui/suggestions/suggest-variants.stderr @@ -74,6 +74,64 @@ LL | enum Shape { LL | Shape::Rombus; | ^^^^^^ variant or associated item not found in `Shape` -error: aborting due to 6 previous errors +error[E0599]: no variant or associated item named `Redd` found for enum `Color` in the current scope + --> $DIR/suggest-variants.rs:28:13 + | +LL | enum Color { + | ---------- variant or associated item `Redd` not found for this enum +... +LL | Ok(Color::Redd) + | ^^^^ variant or associated item not found in `Color` + | +help: there is a variant with a similar name + | +LL - Ok(Color::Redd) +LL + Ok(Color::Red) + | + +error[E0599]: no variant or associated item named `Greenn` found for enum `Color` in the current scope + --> $DIR/suggest-variants.rs:32:13 + | +LL | enum Color { + | ---------- variant or associated item `Greenn` not found for this enum +... +LL | Ok(Color::Greenn(())) + | ^^^^^^ variant or associated item not found in `Color` + | +help: there is a variant with a similar name + | +LL - Ok(Color::Greenn(())) +LL + Ok(Color::Green(())) + | + +error[E0599]: no variant or associated item named `Blu` found for enum `Color` in the current scope + --> $DIR/suggest-variants.rs:36:13 + | +LL | enum Color { + | ---------- variant or associated item `Blu` not found for this enum +... +LL | Ok(Color::Blu) + | ^^^ variant or associated item not found in `Color` + | +help: there is a variant with a similar name + | +LL | Ok(Color::Blue) + | + + +error[E0599]: no variant named `Alph` found for enum `Color` + --> $DIR/suggest-variants.rs:40:13 + | +LL | enum Color { + | ---------- variant `Alph` not found here +... +LL | Ok(Color::Alph{ a: 255 }) + | ^^^^ + | +help: there is a variant with a similar name + | +LL | Ok(Color::Alpha{ a: 255 }) + | + + +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/suggestions/trait-hidden-method.stderr b/tests/ui/suggestions/trait-hidden-method.stderr index 87753e578462..c764034d8466 100644 --- a/tests/ui/suggestions/trait-hidden-method.stderr +++ b/tests/ui/suggestions/trait-hidden-method.stderr @@ -2,7 +2,7 @@ error[E0191]: the value of the associated type `Item` in `Iterator` must be spec --> $DIR/trait-hidden-method.rs:4:33 | LL | Box::new(1..=10) as Box - | ^^^^^^^^ help: specify the associated type: `Iterator` + | ^^^^^^^^ help: specify the associated type: `Iterator` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs index f882a159f983..fdd5dfc8307a 100644 --- a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs +++ b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.rs @@ -12,7 +12,7 @@ fn main() -> Result<(), ()> { // Here, we do want to suggest a semicolon: let x = Ok(42); if true { - //~^ NOTE: expected this to be `()` + //~^ NOTE: `if` expressions without `else` arms expect their inner expression to be `()` x? //~^ ERROR: mismatched types [E0308] //~| NOTE: expected `()`, found integer diff --git a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr index a275f0c2fa89..25cd27488c8c 100644 --- a/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr +++ b/tests/ui/suggestions/try-operator-dont-suggest-semicolon.stderr @@ -15,7 +15,7 @@ LL | | x? | | ^^ expected `()`, found integer ... | LL | | } - | |_____- expected this to be `()` + | |_____- `if` expressions without `else` arms expect their inner expression to be `()` | help: consider using a semicolon here | diff --git a/tests/ui/suggestions/undeclared-module-alloc.rs b/tests/ui/suggestions/undeclared-module-alloc.rs index a0bddc94471c..a19e828f2a9b 100644 --- a/tests/ui/suggestions/undeclared-module-alloc.rs +++ b/tests/ui/suggestions/undeclared-module-alloc.rs @@ -1,5 +1,5 @@ //@ edition:2018 -use alloc::rc::Rc; //~ ERROR failed to resolve: use of unresolved module or unlinked crate `alloc` +use alloc::rc::Rc; //~ ERROR cannot find module or crate `alloc` fn main() {} diff --git a/tests/ui/suggestions/undeclared-module-alloc.stderr b/tests/ui/suggestions/undeclared-module-alloc.stderr index 00e498aa9ba9..c73efa8a3614 100644 --- a/tests/ui/suggestions/undeclared-module-alloc.stderr +++ b/tests/ui/suggestions/undeclared-module-alloc.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `alloc` +error[E0433]: cannot find module or crate `alloc` in this scope --> $DIR/undeclared-module-alloc.rs:3:5 | LL | use alloc::rc::Rc; diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs index 8449b8ce0928..dba9e2366d9e 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target=aarch64-unknown-none-softfloat //@ needs-llvm-components: aarch64 //@ add-minicore +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] #![deny(aarch64_softfloat_neon)] diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr index e3bb8bef9a00..9595d1aba477 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute-fcw.stderr @@ -1,5 +1,5 @@ error: enabling the `neon` target feature on the current target is unsound due to ABI issues - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:12:18 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:13:18 | LL | #[target_feature(enable = "neon")] | ^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #[target_feature(enable = "neon")] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #134375 note: the lint level is defined here - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:7:9 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:8:9 | LL | #![deny(aarch64_softfloat_neon)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ error: aborting due to 1 previous error Future incompatibility report: Future breakage diagnostic: error: enabling the `neon` target feature on the current target is unsound due to ABI issues - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:12:18 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:13:18 | LL | #[target_feature(enable = "neon")] | ^^^^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | #[target_feature(enable = "neon")] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #134375 note: the lint level is defined here - --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:7:9 + --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:8:9 | LL | #![deny(aarch64_softfloat_neon)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr index fd9d693525cc..0fab0f003375 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-attribute.x86.stderr @@ -1,4 +1,4 @@ -error: target feature `soft-float` cannot be enabled with `#[target_feature]`: this feature is incompatible with the target ABI +error: target feature `soft-float` cannot be enabled with `#[target_feature]`: use a soft-float target instead --> $DIR/abi-incompatible-target-feature-attribute.rs:17:32 | LL | #[cfg_attr(x86, target_feature(enable = "soft-float"))] #[cfg_attr(riscv, target_feature(enable = "d"))] diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs index 0cdaf3358d25..c6370f01c47d 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.rs @@ -19,4 +19,5 @@ extern crate minicore; use minicore::*; //~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly -//~? WARN unstable feature specified for `-Ctarget-feature` +//[riscv]~? WARN unstable feature specified for `-Ctarget-feature` +//[x86]~? WARN use a soft-float target instead diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr index 90a9665fb41b..a8395f2d4690 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.x86.stderr @@ -1,6 +1,7 @@ -warning: unstable feature specified for `-Ctarget-feature`: `soft-float` +warning: target feature `soft-float` cannot be enabled with `-Ctarget-feature`: use a soft-float target instead | - = note: this feature is not stably supported; its behavior can change in the future + = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #116344 warning: target feature `soft-float` must be disabled to ensure that the ABI of the current target can be implemented correctly | diff --git a/tests/ui/target-feature/feature-hierarchy.rs b/tests/ui/target-feature/feature-hierarchy.rs index 2e10c0e6e690..a14af97d7234 100644 --- a/tests/ui/target-feature/feature-hierarchy.rs +++ b/tests/ui/target-feature/feature-hierarchy.rs @@ -5,6 +5,7 @@ //@ [aarch64-sve2] needs-llvm-components: aarch64 //@ build-pass //@ add-minicore +//@ ignore-backends: gcc #![no_core] #![crate_type = "rlib"] #![feature(intrinsics, rustc_attrs, no_core, staged_api)] diff --git a/tests/ui/target-feature/gate.rs b/tests/ui/target-feature/gate.rs index fc3763820cbe..ea3bbbed273c 100644 --- a/tests/ui/target-feature/gate.rs +++ b/tests/ui/target-feature/gate.rs @@ -20,6 +20,7 @@ // gate-test-sparc_target_feature // gate-test-x87_target_feature // gate-test-m68k_target_feature +// gate-test-avr_target_feature #[target_feature(enable = "x87")] //~^ ERROR: currently unstable diff --git a/tests/ui/target-feature/gate.stderr b/tests/ui/target-feature/gate.stderr index 345dc2006d0b..f0de5a958e86 100644 --- a/tests/ui/target-feature/gate.stderr +++ b/tests/ui/target-feature/gate.stderr @@ -1,10 +1,10 @@ error[E0658]: the target feature `x87` is currently unstable - --> $DIR/gate.rs:24:18 + --> $DIR/gate.rs:25:18 | LL | #[target_feature(enable = "x87")] | ^^^^^^^^^^^^^^ | - = note: see issue #44839 for more information + = note: see issue #150261 for more information = help: add `#![feature(x87_target_feature)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr index eaa26aa3ecaf..05a836b01af5 100644 --- a/tests/ui/target-feature/invalid-attribute.stderr +++ b/tests/ui/target-feature/invalid-attribute.stderr @@ -26,9 +26,9 @@ error[E0539]: malformed `target_feature` attribute input --> $DIR/invalid-attribute.rs:17:1 | LL | #[target_feature = "+sse2"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^---------^ + | | | + | | expected this to be a list | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` error[E0539]: malformed `target_feature` attribute input diff --git a/tests/ui/target-feature/no-llvm-leaks.rs b/tests/ui/target-feature/no-llvm-leaks.rs index fa72c88ead02..e4d964497ef3 100644 --- a/tests/ui/target-feature/no-llvm-leaks.rs +++ b/tests/ui/target-feature/no-llvm-leaks.rs @@ -2,6 +2,7 @@ //@ revisions: aarch64 x86-64 //@ [aarch64] compile-flags: -Ctarget-feature=+neon,+fp16,+fhm --target=aarch64-unknown-linux-gnu //@ [aarch64] needs-llvm-components: aarch64 +//@ [aarch64] ignore-backends: gcc //@ [x86-64] compile-flags: -Ctarget-feature=+sse4.2,+rdrand --target=x86_64-unknown-linux-gnu //@ [x86-64] needs-llvm-components: x86 //@ build-pass diff --git a/tests/ui/target-feature/target-feature-detection.rs b/tests/ui/target-feature/target-feature-detection.rs index 41fc24691312..9a9102bf7d54 100644 --- a/tests/ui/target-feature/target-feature-detection.rs +++ b/tests/ui/target-feature/target-feature-detection.rs @@ -4,9 +4,6 @@ //@ run-pass //@ ignore-i586 (no SSE2) -#![allow(stable_features)] -#![feature(cfg_target_feature)] - fn main() { if cfg!(any(target_arch = "x86", target_arch = "x86_64")) { assert!( diff --git a/tests/ui/target-feature/x86-soft-float-cfg.rs b/tests/ui/target-feature/x86-soft-float-cfg.rs new file mode 100644 index 000000000000..8718338ca105 --- /dev/null +++ b/tests/ui/target-feature/x86-soft-float-cfg.rs @@ -0,0 +1,17 @@ +//! The soft-float target feature is *not* exposed as `cfg` on x86. +//@ revisions: soft hard +//@[hard] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=lib +//@[hard] needs-llvm-components: x86 +//@[soft] compile-flags: --target=x86_64-unknown-none --crate-type=lib +//@[soft] needs-llvm-components: x86 +//@ check-pass +//@ ignore-backends: gcc +//@ add-minicore +#![feature(no_core)] +#![no_core] +#![allow(unexpected_cfgs)] + +// The compile_error macro does not exist, so if the `cfg` evaluates to `true` this +// complains about the missing macro rather than showing the error... but that's good enough. +#[cfg(target_feature = "soft-float")] +compile_error!("the soft-float feature should NOT be exposed in `cfg`"); diff --git a/tests/ui/target_modifiers/auxiliary/disabled_softfloat.rs b/tests/ui/target_modifiers/auxiliary/disabled_softfloat.rs new file mode 100644 index 000000000000..0063d925deca --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/disabled_softfloat.rs @@ -0,0 +1,8 @@ +//@ add-minicore +//@ no-prefer-dynamic +//@ compile-flags: --target=s390x-unknown-linux-gnu +//@ needs-llvm-components: systemz + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/auxiliary/enabled_softfloat.rs b/tests/ui/target_modifiers/auxiliary/enabled_softfloat.rs new file mode 100644 index 000000000000..7439a1eb69b5 --- /dev/null +++ b/tests/ui/target_modifiers/auxiliary/enabled_softfloat.rs @@ -0,0 +1,8 @@ +//@ add-minicore +//@ no-prefer-dynamic +//@ compile-flags: --target=s390x-unknown-none-softfloat +//@ needs-llvm-components: systemz + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] diff --git a/tests/ui/target_modifiers/incompatible_softfloat_targets.disable-softfloat.stderr b/tests/ui/target_modifiers/incompatible_softfloat_targets.disable-softfloat.stderr new file mode 100644 index 000000000000..090ebe6ca14c --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_softfloat_targets.disable-softfloat.stderr @@ -0,0 +1,12 @@ +error[E0461]: couldn't find crate `enabled_softfloat` with expected target triple s390x-unknown-linux-gnu + --> $DIR/incompatible_softfloat_targets.rs:17:1 + | +LL | extern crate enabled_softfloat; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the following crate versions were found: + crate `enabled_softfloat`, target triple s390x-unknown-none-softfloat: $TEST_BUILD_DIR/auxiliary/libenabled_softfloat.rlib + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0461`. diff --git a/tests/ui/target_modifiers/incompatible_softfloat_targets.enable-softfloat.stderr b/tests/ui/target_modifiers/incompatible_softfloat_targets.enable-softfloat.stderr new file mode 100644 index 000000000000..9adb6d265651 --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_softfloat_targets.enable-softfloat.stderr @@ -0,0 +1,12 @@ +error[E0461]: couldn't find crate `disabled_softfloat` with expected target triple s390x-unknown-none-softfloat + --> $DIR/incompatible_softfloat_targets.rs:19:1 + | +LL | extern crate disabled_softfloat; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the following crate versions were found: + crate `disabled_softfloat`, target triple s390x-unknown-linux-gnu: $TEST_BUILD_DIR/auxiliary/libdisabled_softfloat.rlib + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0461`. diff --git a/tests/ui/target_modifiers/incompatible_softfloat_targets.rs b/tests/ui/target_modifiers/incompatible_softfloat_targets.rs new file mode 100644 index 000000000000..3d253c5f0c78 --- /dev/null +++ b/tests/ui/target_modifiers/incompatible_softfloat_targets.rs @@ -0,0 +1,20 @@ +//@ add-minicore +//@ aux-build: disabled_softfloat.rs +//@ aux-build: enabled_softfloat.rs +//@ revisions: disable-softfloat enable-softfloat +//@ check-fail +//@ [enable-softfloat] compile-flags: --target=s390x-unknown-none-softfloat +//@ [enable-softfloat] needs-llvm-components: systemz +//@ [disable-softfloat] compile-flags: --target=s390x-unknown-linux-gnu +//@ [disable-softfloat] needs-llvm-components: systemz +//@ ignore-backends: gcc + + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_core] + +extern crate enabled_softfloat; +//[disable-softfloat]~^ ERROR couldn't find crate `enabled_softfloat` with expected target triple s390x-unknown-linux-gnu +extern crate disabled_softfloat; +//[enable-softfloat]~^ ERROR couldn't find crate `disabled_softfloat` with expected target triple s390x-unknown-none-softfloat diff --git a/tests/ui/test-attrs/issue-109816.rs b/tests/ui/test-attrs/issue-109816.rs index c7caae67fefa..f40f99946da1 100644 --- a/tests/ui/test-attrs/issue-109816.rs +++ b/tests/ui/test-attrs/issue-109816.rs @@ -1,4 +1,5 @@ //@ compile-flags: --test +//@ reference: attributes.testing.test.allowed-positions fn align_offset_weird_strides() { #[test] diff --git a/tests/ui/test-attrs/issue-109816.stderr b/tests/ui/test-attrs/issue-109816.stderr index 270f4e0a6668..118c8d878290 100644 --- a/tests/ui/test-attrs/issue-109816.stderr +++ b/tests/ui/test-attrs/issue-109816.stderr @@ -1,5 +1,5 @@ error: the `#[test]` attribute may only be used on a free function - --> $DIR/issue-109816.rs:4:5 + --> $DIR/issue-109816.rs:5:5 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions diff --git a/tests/ui/test-attrs/issue-34932.rs b/tests/ui/test-attrs/issue-34932.rs index feb6556b60a1..f0cbdd07df84 100644 --- a/tests/ui/test-attrs/issue-34932.rs +++ b/tests/ui/test-attrs/issue-34932.rs @@ -1,6 +1,6 @@ //@ run-pass //@ compile-flags:--test -#![cfg(any())] // This test should be configured away +#![cfg(false)] // This test should be configured away #![feature(rustc_attrs)] // Test that this is allowed on stable/beta #![feature(iter_arith_traits)] // Test that this is not unused #![deny(unused_features)] diff --git a/tests/ui/test-attrs/test-attr-non-associated-functions.rs b/tests/ui/test-attrs/test-attr-non-associated-functions.rs index 4bf337d0f1b3..9d28f59888a0 100644 --- a/tests/ui/test-attrs/test-attr-non-associated-functions.rs +++ b/tests/ui/test-attrs/test-attr-non-associated-functions.rs @@ -1,4 +1,5 @@ //@ compile-flags:--test +//@ reference: attributes.testing.test.allowed-positions struct A {} diff --git a/tests/ui/test-attrs/test-attr-non-associated-functions.stderr b/tests/ui/test-attrs/test-attr-non-associated-functions.stderr index 13914971b558..fda28ee28a07 100644 --- a/tests/ui/test-attrs/test-attr-non-associated-functions.stderr +++ b/tests/ui/test-attrs/test-attr-non-associated-functions.stderr @@ -1,5 +1,5 @@ error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-attr-non-associated-functions.rs:6:5 + --> $DIR/test-attr-non-associated-functions.rs:7:5 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -11,7 +11,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-attr-non-associated-functions.rs:11:5 + --> $DIR/test-attr-non-associated-functions.rs:12:5 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions diff --git a/tests/ui/test-attrs/test-function-signature.rs b/tests/ui/test-attrs/test-function-signature.rs index 0f43245be6f6..4a6c0e8450ce 100644 --- a/tests/ui/test-attrs/test-function-signature.rs +++ b/tests/ui/test-attrs/test-function-signature.rs @@ -1,4 +1,5 @@ //@ compile-flags: --test +//@ reference: attributes.testing.test.allowed-positions #[test] fn foo() -> Result<(), ()> { diff --git a/tests/ui/test-attrs/test-function-signature.stderr b/tests/ui/test-attrs/test-function-signature.stderr index 55d09970b320..7fdaaed1aebc 100644 --- a/tests/ui/test-attrs/test-function-signature.stderr +++ b/tests/ui/test-attrs/test-function-signature.stderr @@ -1,29 +1,29 @@ error: functions used as tests can not have any arguments - --> $DIR/test-function-signature.rs:14:1 + --> $DIR/test-function-signature.rs:15:1 | LL | fn baz(val: i32) {} | ^^^^^^^^^^^^^^^^^^^ error: functions used as tests can not have any non-lifetime generic parameters - --> $DIR/test-function-signature.rs:22:1 + --> $DIR/test-function-signature.rs:23:1 | LL | fn type_generic() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions used as tests can not have any non-lifetime generic parameters - --> $DIR/test-function-signature.rs:25:1 + --> $DIR/test-function-signature.rs:26:1 | LL | fn const_generic() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions used as tests can not have any arguments - --> $DIR/test-function-signature.rs:30:5 + --> $DIR/test-function-signature.rs:31:5 | LL | fn foo(arg: ()) {} | ^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `i32: Termination` is not satisfied - --> $DIR/test-function-signature.rs:9:13 + --> $DIR/test-function-signature.rs:10:13 | LL | #[test] | ------- in this attribute macro expansion diff --git a/tests/ui/test-attrs/test-on-not-fn.rs b/tests/ui/test-attrs/test-on-not-fn.rs index 16e9cd8d5b8d..57ae2b19cf5f 100644 --- a/tests/ui/test-attrs/test-on-not-fn.rs +++ b/tests/ui/test-attrs/test-on-not-fn.rs @@ -1,4 +1,5 @@ //@ compile-flags: --test +//@ reference: attributes.testing.test.allowed-positions #[test] //~ ERROR: the `#[test]` attribute may only be used on a free function mod test {} diff --git a/tests/ui/test-attrs/test-on-not-fn.stderr b/tests/ui/test-attrs/test-on-not-fn.stderr index db8bed100a63..22e479268856 100644 --- a/tests/ui/test-attrs/test-on-not-fn.stderr +++ b/tests/ui/test-attrs/test-on-not-fn.stderr @@ -1,5 +1,5 @@ error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:3:1 + --> $DIR/test-on-not-fn.rs:4:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -13,7 +13,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:6:1 + --> $DIR/test-on-not-fn.rs:7:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -33,7 +33,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:20:1 + --> $DIR/test-on-not-fn.rs:21:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -47,7 +47,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:23:1 + --> $DIR/test-on-not-fn.rs:24:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -61,7 +61,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:26:1 + --> $DIR/test-on-not-fn.rs:27:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -75,7 +75,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:29:1 + --> $DIR/test-on-not-fn.rs:30:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -89,7 +89,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:32:1 + --> $DIR/test-on-not-fn.rs:33:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -103,7 +103,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:35:1 + --> $DIR/test-on-not-fn.rs:36:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -119,7 +119,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:40:1 + --> $DIR/test-on-not-fn.rs:41:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -133,7 +133,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:43:1 + --> $DIR/test-on-not-fn.rs:44:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -150,7 +150,7 @@ LL + #[cfg(test)] | error: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:50:1 + --> $DIR/test-on-not-fn.rs:51:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions @@ -168,7 +168,7 @@ LL + #[cfg(test)] | warning: the `#[test]` attribute may only be used on a free function - --> $DIR/test-on-not-fn.rs:61:1 + --> $DIR/test-on-not-fn.rs:62:1 | LL | #[test] | ^^^^^^^ the `#[test]` macro causes a function to be run as a test and has no effect on non-functions diff --git a/tests/ui/test-attrs/test-passed.rs b/tests/ui/test-attrs/test-passed.rs index 959470adcc42..034051e4eb6d 100644 --- a/tests/ui/test-attrs/test-passed.rs +++ b/tests/ui/test-attrs/test-passed.rs @@ -4,6 +4,7 @@ //@ run-pass //@ check-run-results //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ reference: attributes.testing.test.success // Tests the output of the test harness with only passed tests. diff --git a/tests/ui/test-attrs/test-should-panic-attr.rs b/tests/ui/test-attrs/test-should-panic-attr.rs index e6de07d00941..b095099daad0 100644 --- a/tests/ui/test-attrs/test-should-panic-attr.rs +++ b/tests/ui/test-attrs/test-should-panic-attr.rs @@ -1,4 +1,5 @@ //@ compile-flags: --test +//@ reference: attributes.testing.should_panic.syntax #[test] #[should_panic = "foo"] diff --git a/tests/ui/test-attrs/test-should-panic-attr.stderr b/tests/ui/test-attrs/test-should-panic-attr.stderr index 475a55ad0cbc..48f6b0d37cb1 100644 --- a/tests/ui/test-attrs/test-should-panic-attr.stderr +++ b/tests/ui/test-attrs/test-should-panic-attr.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:10:1 + --> $DIR/test-should-panic-attr.rs:11:1 | LL | #[should_panic(expected)] | ^^^^^^^^^^^^^^^--------^^ @@ -19,7 +19,7 @@ LL + #[should_panic] | error[E0539]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:19:1 + --> $DIR/test-should-panic-attr.rs:20:1 | LL | #[should_panic(expect)] | ^^^^^^^^^^^^^^--------^ @@ -39,7 +39,7 @@ LL + #[should_panic] | error[E0539]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:28:1 + --> $DIR/test-should-panic-attr.rs:29:1 | LL | #[should_panic(expected(foo, bar))] | ^^^^^^^^^^^^^^^------------------^^ @@ -60,7 +60,7 @@ LL + #[should_panic] | error[E0805]: malformed `should_panic` attribute input - --> $DIR/test-should-panic-attr.rs:37:1 + --> $DIR/test-should-panic-attr.rs:38:1 | LL | #[should_panic(expected = "foo", bar)] | ^^^^^^^^^^^^^^-----------------------^ diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.rs b/tests/ui/test-attrs/test-should-panic-failed-show-span.rs index 22a6f4a835e2..f8c1840ab79f 100644 --- a/tests/ui/test-attrs/test-should-panic-failed-show-span.rs +++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.rs @@ -8,6 +8,7 @@ //@ normalize-stdout: "TypeId\(0x[0-9a-f]+\)" -> "TypeId($$HEX)" //@ needs-threads //@ needs-unwind (panic) +//@ reference: attributes.testing.should_panic.expected #[test] #[should_panic] diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr index ab36bc2beb9e..398479f15fa2 100644 --- a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr +++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr @@ -1,13 +1,13 @@ -thread 'should_panic_with_any_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:15:5: +thread 'should_panic_with_any_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:16:5: Panic! note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -thread 'should_panic_with_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:21:5: +thread 'should_panic_with_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:22:5: message -thread 'should_panic_with_substring_panics_with_incorrect_string' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:39:5: +thread 'should_panic_with_substring_panics_with_incorrect_string' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:40:5: ZOMGWTFBBQ -thread 'should_panic_with_substring_panics_with_non_string_value' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:46:5: +thread 'should_panic_with_substring_panics_with_non_string_value' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:47:5: Box diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout index 492f54debc82..c28403a11e8e 100644 --- a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout +++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stdout @@ -10,9 +10,9 @@ test should_panic_with_substring_panics_with_non_string_value - should panic ... failures: ---- should_panic_with_any_message_does_not_panic stdout ---- -note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:26:4 +note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:27:4 ---- should_panic_with_message_does_not_panic stdout ---- -note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:32:4 +note: test did not panic as expected at $DIR/test-should-panic-failed-show-span.rs:33:4 ---- should_panic_with_substring_panics_with_incorrect_string stdout ---- note: panic did not contain expected string panic message: "ZOMGWTFBBQ" diff --git a/tests/ui/test-attrs/test-vs-cfg-test.rs b/tests/ui/test-attrs/test-vs-cfg-test.rs index d7d9e61103c9..634511fdff39 100644 --- a/tests/ui/test-attrs/test-vs-cfg-test.rs +++ b/tests/ui/test-attrs/test-vs-cfg-test.rs @@ -1,5 +1,6 @@ //@ run-pass //@ compile-flags: --cfg test +//@ reference: cfg.test // Make sure `--cfg test` does not inject test harness diff --git a/tests/ui/thir-print/c-variadic.stdout b/tests/ui/thir-print/c-variadic.stdout index d64b2b9aa9d1..a426902b2deb 100644 --- a/tests/ui/thir-print/c-variadic.stdout +++ b/tests/ui/thir-print/c-variadic.stdout @@ -6,7 +6,7 @@ params: [ self_kind: None hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).1)) param: Some( - Pat: { + Pat { ty: i32 span: $DIR/c-variadic.rs:7:26: 7:27 (#0) kind: PatKind { @@ -16,13 +16,13 @@ params: [ ) } Param { - ty: std::ffi::VaListImpl<'{erased}> + ty: std::ffi::VaList<'{erased}> ty_span: None self_kind: None hir_id: Some(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).3)) param: Some( - Pat: { - ty: std::ffi::VaListImpl<'{erased}> + Pat { + ty: std::ffi::VaList<'{erased}> span: $DIR/c-variadic.rs:7:34: 7:37 (#0) kind: PatKind { Missing @@ -39,7 +39,7 @@ body: kind: Scope { region_scope: Node(6) - lint_level: Explicit(HirId(DefId(0:3 ~ c_variadic[a5de]::foo).6)) + hir_id: HirId(DefId(0:3 ~ c_variadic[a5de]::foo).6) value: Expr { ty: () diff --git a/tests/ui/thir-print/offset_of.stdout b/tests/ui/thir-print/offset_of.stdout index 846817f47528..25c099438754 100644 --- a/tests/ui/thir-print/offset_of.stdout +++ b/tests/ui/thir-print/offset_of.stdout @@ -9,7 +9,7 @@ body: kind: Scope { region_scope: Node(52) - lint_level: Explicit(HirId(DefId(offset_of::concrete).52)) + hir_id: HirId(DefId(offset_of::concrete).52) value: Expr { ty: () @@ -27,7 +27,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 0} init_scope: Node(2) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:37:9: 37:10 (#0) kind: PatKind { @@ -51,7 +51,7 @@ body: kind: Scope { region_scope: Node(3) - lint_level: Explicit(HirId(DefId(offset_of::concrete).3)) + hir_id: HirId(DefId(offset_of::concrete).3) value: Expr { ty: usize @@ -67,8 +67,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).10)) - span: $DIR/offset_of.rs:37:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::concrete).10) + span: $DIR/offset_of.rs:37:5: 37:33 (#0) } } Stmt { @@ -76,7 +76,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 1} init_scope: Node(12) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:38:9: 38:10 (#0) kind: PatKind { @@ -100,7 +100,7 @@ body: kind: Scope { region_scope: Node(13) - lint_level: Explicit(HirId(DefId(offset_of::concrete).13)) + hir_id: HirId(DefId(offset_of::concrete).13) value: Expr { ty: usize @@ -116,8 +116,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).20)) - span: $DIR/offset_of.rs:38:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::concrete).20) + span: $DIR/offset_of.rs:38:5: 38:33 (#0) } } Stmt { @@ -125,7 +125,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 2} init_scope: Node(22) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:39:9: 39:10 (#0) kind: PatKind { @@ -149,7 +149,7 @@ body: kind: Scope { region_scope: Node(23) - lint_level: Explicit(HirId(DefId(offset_of::concrete).23)) + hir_id: HirId(DefId(offset_of::concrete).23) value: Expr { ty: usize @@ -165,8 +165,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).30)) - span: $DIR/offset_of.rs:39:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::concrete).30) + span: $DIR/offset_of.rs:39:5: 39:34 (#0) } } Stmt { @@ -174,7 +174,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 3} init_scope: Node(32) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:40:9: 40:11 (#0) kind: PatKind { @@ -198,7 +198,7 @@ body: kind: Scope { region_scope: Node(33) - lint_level: Explicit(HirId(DefId(offset_of::concrete).33)) + hir_id: HirId(DefId(offset_of::concrete).33) value: Expr { ty: usize @@ -214,8 +214,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).40)) - span: $DIR/offset_of.rs:40:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::concrete).40) + span: $DIR/offset_of.rs:40:5: 40:36 (#0) } } Stmt { @@ -223,7 +223,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 4} init_scope: Node(42) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:41:9: 41:11 (#0) kind: PatKind { @@ -247,7 +247,7 @@ body: kind: Scope { region_scope: Node(43) - lint_level: Explicit(HirId(DefId(offset_of::concrete).43)) + hir_id: HirId(DefId(offset_of::concrete).43) value: Expr { ty: usize @@ -263,8 +263,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::concrete).50)) - span: $DIR/offset_of.rs:41:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::concrete).50) + span: $DIR/offset_of.rs:41:5: 41:36 (#0) } } ] @@ -286,7 +286,7 @@ body: kind: Scope { region_scope: Node(5) - lint_level: Explicit(HirId(DefId(offset_of::concrete).5)) + hir_id: HirId(DefId(offset_of::concrete).5) value: Expr { ty: usize @@ -307,7 +307,7 @@ body: kind: Scope { region_scope: Node(7) - lint_level: Explicit(HirId(DefId(offset_of::concrete).7)) + hir_id: HirId(DefId(offset_of::concrete).7) value: Expr { ty: usize @@ -369,7 +369,7 @@ body: kind: Scope { region_scope: Node(15) - lint_level: Explicit(HirId(DefId(offset_of::concrete).15)) + hir_id: HirId(DefId(offset_of::concrete).15) value: Expr { ty: usize @@ -390,7 +390,7 @@ body: kind: Scope { region_scope: Node(17) - lint_level: Explicit(HirId(DefId(offset_of::concrete).17)) + hir_id: HirId(DefId(offset_of::concrete).17) value: Expr { ty: usize @@ -452,7 +452,7 @@ body: kind: Scope { region_scope: Node(25) - lint_level: Explicit(HirId(DefId(offset_of::concrete).25)) + hir_id: HirId(DefId(offset_of::concrete).25) value: Expr { ty: usize @@ -473,7 +473,7 @@ body: kind: Scope { region_scope: Node(27) - lint_level: Explicit(HirId(DefId(offset_of::concrete).27)) + hir_id: HirId(DefId(offset_of::concrete).27) value: Expr { ty: usize @@ -535,7 +535,7 @@ body: kind: Scope { region_scope: Node(35) - lint_level: Explicit(HirId(DefId(offset_of::concrete).35)) + hir_id: HirId(DefId(offset_of::concrete).35) value: Expr { ty: usize @@ -556,7 +556,7 @@ body: kind: Scope { region_scope: Node(37) - lint_level: Explicit(HirId(DefId(offset_of::concrete).37)) + hir_id: HirId(DefId(offset_of::concrete).37) value: Expr { ty: usize @@ -670,7 +670,7 @@ body: kind: Scope { region_scope: Node(45) - lint_level: Explicit(HirId(DefId(offset_of::concrete).45)) + hir_id: HirId(DefId(offset_of::concrete).45) value: Expr { ty: usize @@ -691,7 +691,7 @@ body: kind: Scope { region_scope: Node(47) - lint_level: Explicit(HirId(DefId(offset_of::concrete).47)) + hir_id: HirId(DefId(offset_of::concrete).47) value: Expr { ty: usize @@ -805,7 +805,7 @@ body: kind: Scope { region_scope: Node(50) - lint_level: Explicit(HirId(DefId(offset_of::generic).50)) + hir_id: HirId(DefId(offset_of::generic).50) value: Expr { ty: () @@ -823,7 +823,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 0} init_scope: Node(2) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:45:9: 45:11 (#0) kind: PatKind { @@ -847,7 +847,7 @@ body: kind: Scope { region_scope: Node(3) - lint_level: Explicit(HirId(DefId(offset_of::generic).3)) + hir_id: HirId(DefId(offset_of::generic).3) value: Expr { ty: usize @@ -863,8 +863,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).12)) - span: $DIR/offset_of.rs:45:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::generic).12) + span: $DIR/offset_of.rs:45:5: 45:37 (#0) } } Stmt { @@ -872,7 +872,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 1} init_scope: Node(14) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:46:9: 46:11 (#0) kind: PatKind { @@ -896,7 +896,7 @@ body: kind: Scope { region_scope: Node(15) - lint_level: Explicit(HirId(DefId(offset_of::generic).15)) + hir_id: HirId(DefId(offset_of::generic).15) value: Expr { ty: usize @@ -912,8 +912,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).24)) - span: $DIR/offset_of.rs:46:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::generic).24) + span: $DIR/offset_of.rs:46:5: 46:37 (#0) } } Stmt { @@ -921,7 +921,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 2} init_scope: Node(26) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:47:9: 47:11 (#0) kind: PatKind { @@ -945,7 +945,7 @@ body: kind: Scope { region_scope: Node(27) - lint_level: Explicit(HirId(DefId(offset_of::generic).27)) + hir_id: HirId(DefId(offset_of::generic).27) value: Expr { ty: usize @@ -961,8 +961,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).36)) - span: $DIR/offset_of.rs:47:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::generic).36) + span: $DIR/offset_of.rs:47:5: 47:37 (#0) } } Stmt { @@ -970,7 +970,7 @@ body: remainder_scope: Remainder { block: 1, first_statement_index: 3} init_scope: Node(38) pattern: - Pat: { + Pat { ty: usize span: $DIR/offset_of.rs:48:9: 48:11 (#0) kind: PatKind { @@ -994,7 +994,7 @@ body: kind: Scope { region_scope: Node(39) - lint_level: Explicit(HirId(DefId(offset_of::generic).39)) + hir_id: HirId(DefId(offset_of::generic).39) value: Expr { ty: usize @@ -1010,8 +1010,8 @@ body: } ) else_block: None - lint_level: Explicit(HirId(DefId(offset_of::generic).48)) - span: $DIR/offset_of.rs:48:5: 1433:57 (#0) + hir_id: HirId(DefId(offset_of::generic).48) + span: $DIR/offset_of.rs:48:5: 48:37 (#0) } } ] @@ -1033,7 +1033,7 @@ body: kind: Scope { region_scope: Node(5) - lint_level: Explicit(HirId(DefId(offset_of::generic).5)) + hir_id: HirId(DefId(offset_of::generic).5) value: Expr { ty: usize @@ -1054,7 +1054,7 @@ body: kind: Scope { region_scope: Node(7) - lint_level: Explicit(HirId(DefId(offset_of::generic).7)) + hir_id: HirId(DefId(offset_of::generic).7) value: Expr { ty: usize @@ -1116,7 +1116,7 @@ body: kind: Scope { region_scope: Node(17) - lint_level: Explicit(HirId(DefId(offset_of::generic).17)) + hir_id: HirId(DefId(offset_of::generic).17) value: Expr { ty: usize @@ -1137,7 +1137,7 @@ body: kind: Scope { region_scope: Node(19) - lint_level: Explicit(HirId(DefId(offset_of::generic).19)) + hir_id: HirId(DefId(offset_of::generic).19) value: Expr { ty: usize @@ -1199,7 +1199,7 @@ body: kind: Scope { region_scope: Node(29) - lint_level: Explicit(HirId(DefId(offset_of::generic).29)) + hir_id: HirId(DefId(offset_of::generic).29) value: Expr { ty: usize @@ -1220,7 +1220,7 @@ body: kind: Scope { region_scope: Node(31) - lint_level: Explicit(HirId(DefId(offset_of::generic).31)) + hir_id: HirId(DefId(offset_of::generic).31) value: Expr { ty: usize @@ -1282,7 +1282,7 @@ body: kind: Scope { region_scope: Node(41) - lint_level: Explicit(HirId(DefId(offset_of::generic).41)) + hir_id: HirId(DefId(offset_of::generic).41) value: Expr { ty: usize @@ -1303,7 +1303,7 @@ body: kind: Scope { region_scope: Node(43) - lint_level: Explicit(HirId(DefId(offset_of::generic).43)) + hir_id: HirId(DefId(offset_of::generic).43) value: Expr { ty: usize diff --git a/tests/ui/thir-print/str-patterns.rs b/tests/ui/thir-print/str-patterns.rs new file mode 100644 index 000000000000..4ad782f63a50 --- /dev/null +++ b/tests/ui/thir-print/str-patterns.rs @@ -0,0 +1,17 @@ +#![crate_type = "rlib"] +//@ edition: 2024 +//@ compile-flags: -Zunpretty=thir-flat +//@ check-pass + +// Snapshot test capturing the THIR pattern structure produced by +// string-literal and string-constant patterns. + +pub fn hello_world(x: &str) { + match x { + "hello" => {} + CONSTANT => {} + _ => {} + } +} + +const CONSTANT: &str = "constant"; diff --git a/tests/ui/thir-print/str-patterns.stdout b/tests/ui/thir-print/str-patterns.stdout new file mode 100644 index 000000000000..09212e7d68ae --- /dev/null +++ b/tests/ui/thir-print/str-patterns.stdout @@ -0,0 +1,326 @@ +DefId(0:3 ~ str_patterns[fc71]::hello_world): +Thir { + body_type: Fn( + fn(&'{erased} str), + ), + arms: [ + Arm { + pattern: Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:11:9: 11:16 (#0), + extra: None, + kind: Deref { + pin: Not, + subpattern: Pat { + ty: str, + span: $DIR/str-patterns.rs:11:9: 11:16 (#0), + extra: None, + kind: Constant { + value: Value { + ty: str, + valtree: Branch( + [ + 104_u8, + 101_u8, + 108_u8, + 108_u8, + 111_u8, + ], + ), + }, + }, + }, + }, + }, + guard: None, + body: e3, + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).9), + scope: Node(9), + span: $DIR/str-patterns.rs:11:9: 11:22 (#0), + }, + Arm { + pattern: Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:12:9: 12:17 (#0), + extra: Some( + PatExtra { + expanded_const: Some( + DefId(0:4 ~ str_patterns[fc71]::CONSTANT), + ), + ascriptions: [], + }, + ), + kind: Deref { + pin: Not, + subpattern: Pat { + ty: str, + span: $DIR/str-patterns.rs:12:9: 12:17 (#0), + extra: None, + kind: Constant { + value: Value { + ty: str, + valtree: Branch( + [ + 99_u8, + 111_u8, + 110_u8, + 115_u8, + 116_u8, + 97_u8, + 110_u8, + 116_u8, + ], + ), + }, + }, + }, + }, + }, + guard: None, + body: e5, + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).15), + scope: Node(15), + span: $DIR/str-patterns.rs:12:9: 12:23 (#0), + }, + Arm { + pattern: Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:13:9: 13:10 (#0), + extra: None, + kind: Wild, + }, + guard: None, + body: e7, + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).19), + scope: Node(19), + span: $DIR/str-patterns.rs:13:9: 13:16 (#0), + }, + ], + blocks: [ + Block { + targeted_by_break: false, + region_scope: Node(11), + span: $DIR/str-patterns.rs:11:20: 11:22 (#0), + stmts: [], + expr: None, + safety_mode: Safe, + }, + Block { + targeted_by_break: false, + region_scope: Node(17), + span: $DIR/str-patterns.rs:12:21: 12:23 (#0), + stmts: [], + expr: None, + safety_mode: Safe, + }, + Block { + targeted_by_break: false, + region_scope: Node(21), + span: $DIR/str-patterns.rs:13:14: 13:16 (#0), + stmts: [], + expr: None, + safety_mode: Safe, + }, + Block { + targeted_by_break: false, + region_scope: Node(3), + span: $DIR/str-patterns.rs:9:29: 15:2 (#0), + stmts: [], + expr: Some( + e9, + ), + safety_mode: Safe, + }, + ], + exprs: [ + Expr { + kind: VarRef { + id: LocalVarId( + HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).2), + ), + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:10:11: 10:12 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(5), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).5), + value: e0, + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:10:11: 10:12 (#0), + }, + Expr { + kind: Block { + block: b0, + }, + ty: (), + temp_scope_id: 10, + span: $DIR/str-patterns.rs:11:20: 11:22 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(10), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).10), + value: e2, + }, + ty: (), + temp_scope_id: 10, + span: $DIR/str-patterns.rs:11:20: 11:22 (#0), + }, + Expr { + kind: Block { + block: b1, + }, + ty: (), + temp_scope_id: 16, + span: $DIR/str-patterns.rs:12:21: 12:23 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(16), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).16), + value: e4, + }, + ty: (), + temp_scope_id: 16, + span: $DIR/str-patterns.rs:12:21: 12:23 (#0), + }, + Expr { + kind: Block { + block: b2, + }, + ty: (), + temp_scope_id: 20, + span: $DIR/str-patterns.rs:13:14: 13:16 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(20), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).20), + value: e6, + }, + ty: (), + temp_scope_id: 20, + span: $DIR/str-patterns.rs:13:14: 13:16 (#0), + }, + Expr { + kind: Match { + scrutinee: e1, + arms: [ + a0, + a1, + a2, + ], + match_source: Normal, + }, + ty: (), + temp_scope_id: 4, + span: $DIR/str-patterns.rs:10:5: 14:6 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(4), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).4), + value: e8, + }, + ty: (), + temp_scope_id: 4, + span: $DIR/str-patterns.rs:10:5: 14:6 (#0), + }, + Expr { + kind: Block { + block: b3, + }, + ty: (), + temp_scope_id: 22, + span: $DIR/str-patterns.rs:9:29: 15:2 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(22), + hir_id: HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).22), + value: e10, + }, + ty: (), + temp_scope_id: 22, + span: $DIR/str-patterns.rs:9:29: 15:2 (#0), + }, + ], + stmts: [], + params: [ + Param { + pat: Some( + Pat { + ty: &'{erased} str, + span: $DIR/str-patterns.rs:9:20: 9:21 (#0), + extra: None, + kind: Binding { + name: "x", + mode: BindingMode( + No, + Not, + ), + var: LocalVarId( + HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).2), + ), + ty: &'{erased} str, + subpattern: None, + is_primary: true, + is_shorthand: false, + }, + }, + ), + ty: &'{erased} str, + ty_span: Some( + $DIR/str-patterns.rs:9:23: 9:27 (#0), + ), + self_kind: None, + hir_id: Some( + HirId(DefId(0:3 ~ str_patterns[fc71]::hello_world).1), + ), + }, + ], +} + +DefId(0:4 ~ str_patterns[fc71]::CONSTANT): +Thir { + body_type: Const( + &'{erased} str, + ), + arms: [], + blocks: [], + exprs: [ + Expr { + kind: Literal { + lit: Spanned { + node: Str( + "constant", + Cooked, + ), + span: $DIR/str-patterns.rs:17:24: 17:34 (#0), + }, + neg: false, + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:17:24: 17:34 (#0), + }, + Expr { + kind: Scope { + region_scope: Node(5), + hir_id: HirId(DefId(0:4 ~ str_patterns[fc71]::CONSTANT).5), + value: e0, + }, + ty: &'{erased} str, + temp_scope_id: 5, + span: $DIR/str-patterns.rs:17:24: 17:34 (#0), + }, + ], + stmts: [], + params: [], +} + diff --git a/tests/ui/thir-print/thir-flat-const-variant.stdout b/tests/ui/thir-print/thir-flat-const-variant.stdout index 750a47a7141c..908684094ec3 100644 --- a/tests/ui/thir-print/thir-flat-const-variant.stdout +++ b/tests/ui/thir-print/thir-flat-const-variant.stdout @@ -17,9 +17,7 @@ Thir { Expr { kind: Scope { region_scope: Node(7), - lint_level: Explicit( - HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).7), - ), + hir_id: HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).7), value: e0, }, ty: (), @@ -49,9 +47,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).3), - ), + hir_id: HirId(DefId(0:8 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR1).3), value: e2, }, ty: Foo, @@ -82,9 +78,7 @@ Thir { Expr { kind: Scope { region_scope: Node(8), - lint_level: Explicit( - HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).8), - ), + hir_id: HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).8), value: e0, }, ty: (), @@ -114,9 +108,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).3), - ), + hir_id: HirId(DefId(0:9 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR2).3), value: e2, }, ty: Foo, @@ -147,9 +139,7 @@ Thir { Expr { kind: Scope { region_scope: Node(7), - lint_level: Explicit( - HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).7), - ), + hir_id: HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).7), value: e0, }, ty: (), @@ -179,9 +169,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).3), - ), + hir_id: HirId(DefId(0:10 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR3).3), value: e2, }, ty: Foo, @@ -212,9 +200,7 @@ Thir { Expr { kind: Scope { region_scope: Node(8), - lint_level: Explicit( - HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).8), - ), + hir_id: HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).8), value: e0, }, ty: (), @@ -244,9 +230,7 @@ Thir { Expr { kind: Scope { region_scope: Node(3), - lint_level: Explicit( - HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).3), - ), + hir_id: HirId(DefId(0:11 ~ thir_flat_const_variant[1f54]::{impl#0}::BAR4).3), value: e2, }, ty: Foo, @@ -286,9 +270,7 @@ Thir { Expr { kind: Scope { region_scope: Node(2), - lint_level: Explicit( - HirId(DefId(0:12 ~ thir_flat_const_variant[1f54]::main).2), - ), + hir_id: HirId(DefId(0:12 ~ thir_flat_const_variant[1f54]::main).2), value: e0, }, ty: (), diff --git a/tests/ui/thir-print/thir-flat.stdout b/tests/ui/thir-print/thir-flat.stdout index f01d64e60b3d..37106427745e 100644 --- a/tests/ui/thir-print/thir-flat.stdout +++ b/tests/ui/thir-print/thir-flat.stdout @@ -26,9 +26,7 @@ Thir { Expr { kind: Scope { region_scope: Node(2), - lint_level: Explicit( - HirId(DefId(0:3 ~ thir_flat[7b97]::main).2), - ), + hir_id: HirId(DefId(0:3 ~ thir_flat[7b97]::main).2), value: e0, }, ty: (), diff --git a/tests/ui/thir-print/thir-tree-field-expr-index.rs b/tests/ui/thir-print/thir-tree-field-expr-index.rs new file mode 100644 index 000000000000..399b78528289 --- /dev/null +++ b/tests/ui/thir-print/thir-tree-field-expr-index.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ compile-flags: -Zunpretty=thir-tree + +struct S { + a: u32, + b: u32, + c: u32, + d: u32, + e: u32, +} + +fn update(x: u32) { + let s = S { a: x, b: x, c: x, d: x, e: x }; + + S { a: x , ..s }; + S { b: x , ..s }; + S { c: x , ..s }; + S { d: x , ..s }; + S { e: x , ..s }; + + S { b: x, d: x, ..s }; + S { a: x, c: x, e: x, ..s }; +} + +fn main() {} diff --git a/tests/ui/thir-print/thir-tree-field-expr-index.stdout b/tests/ui/thir-print/thir-tree-field-expr-index.stdout new file mode 100644 index 000000000000..5bf97a185290 --- /dev/null +++ b/tests/ui/thir-print/thir-tree-field-expr-index.stdout @@ -0,0 +1,921 @@ +DefId(0:9 ~ thir_tree_field_expr_index[5059]::update): +params: [ + Param { + ty: u32 + ty_span: Some($DIR/thir-tree-field-expr-index.rs:12:14: 12:17 (#0)) + self_kind: None + hir_id: Some(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).1)) + param: Some( + Pat { + ty: u32 + span: $DIR/thir-tree-field-expr-index.rs:12:11: 12:12 (#0) + kind: PatKind { + Binding { + name: "x" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + ty: u32 + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + ) + } +] +body: + Expr { + ty: () + temp_scope_id: 89 + span: $DIR/thir-tree-field-expr-index.rs:12:19: 23:2 (#0) + kind: + Scope { + region_scope: Node(89) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).89) + value: + Expr { + ty: () + temp_scope_id: 89 + span: $DIR/thir-tree-field-expr-index.rs:12:19: 23:2 (#0) + kind: + Block { + targeted_by_break: false + span: $DIR/thir-tree-field-expr-index.rs:12:19: 23:2 (#0) + region_scope: Node(3) + safety_mode: Safe + stmts: [ + Stmt { + kind: Let { + remainder_scope: Remainder { block: 3, first_statement_index: 0} + init_scope: Node(4) + pattern: + Pat { + ty: S + span: $DIR/thir-tree-field-expr-index.rs:13:7: 13:8 (#0) + kind: PatKind { + Binding { + name: "s" + mode: BindingMode(No, Not) + var: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + ty: S + is_primary: true + is_shorthand: false + subpattern: None + } + } + } + , + initializer: Some( + Expr { + ty: S + temp_scope_id: 5 + span: $DIR/thir-tree-field-expr-index.rs:13:11: 13:45 (#0) + kind: + Scope { + region_scope: Node(5) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).5) + value: + Expr { + ty: S + temp_scope_id: 5 + span: $DIR/thir-tree-field-expr-index.rs:13:11: 13:45 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 0: + Expr { + ty: u32 + temp_scope_id: 8 + span: $DIR/thir-tree-field-expr-index.rs:13:18: 13:19 (#0) + kind: + Scope { + region_scope: Node(8) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).8) + value: + Expr { + ty: u32 + temp_scope_id: 8 + span: $DIR/thir-tree-field-expr-index.rs:13:18: 13:19 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 1: + Expr { + ty: u32 + temp_scope_id: 11 + span: $DIR/thir-tree-field-expr-index.rs:13:24: 13:25 (#0) + kind: + Scope { + region_scope: Node(11) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).11) + value: + Expr { + ty: u32 + temp_scope_id: 11 + span: $DIR/thir-tree-field-expr-index.rs:13:24: 13:25 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 2: + Expr { + ty: u32 + temp_scope_id: 14 + span: $DIR/thir-tree-field-expr-index.rs:13:30: 13:31 (#0) + kind: + Scope { + region_scope: Node(14) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).14) + value: + Expr { + ty: u32 + temp_scope_id: 14 + span: $DIR/thir-tree-field-expr-index.rs:13:30: 13:31 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 3: + Expr { + ty: u32 + temp_scope_id: 17 + span: $DIR/thir-tree-field-expr-index.rs:13:36: 13:37 (#0) + kind: + Scope { + region_scope: Node(17) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).17) + value: + Expr { + ty: u32 + temp_scope_id: 17 + span: $DIR/thir-tree-field-expr-index.rs:13:36: 13:37 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 4: + Expr { + ty: u32 + temp_scope_id: 20 + span: $DIR/thir-tree-field-expr-index.rs:13:42: 13:43 (#0) + kind: + Scope { + region_scope: Node(20) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).20) + value: + Expr { + ty: u32 + temp_scope_id: 20 + span: $DIR/thir-tree-field-expr-index.rs:13:42: 13:43 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: None + } + } + } + } + ) + else_block: None + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).22) + span: $DIR/thir-tree-field-expr-index.rs:13:3: 13:45 (#0) + } + } + Stmt { + kind: Expr { + scope: Node(31) + expr: + Expr { + ty: S + temp_scope_id: 24 + span: $DIR/thir-tree-field-expr-index.rs:15:3: 15:19 (#0) + kind: + Scope { + region_scope: Node(24) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).24) + value: + Expr { + ty: S + temp_scope_id: 24 + span: $DIR/thir-tree-field-expr-index.rs:15:3: 15:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 0: + Expr { + ty: u32 + temp_scope_id: 29 + span: $DIR/thir-tree-field-expr-index.rs:15:10: 15:11 (#0) + kind: + Scope { + region_scope: Node(29) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).29) + value: + Expr { + ty: u32 + temp_scope_id: 29 + span: $DIR/thir-tree-field-expr-index.rs:15:10: 15:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 25 + span: $DIR/thir-tree-field-expr-index.rs:15:16: 15:17 (#0) + kind: + Scope { + region_scope: Node(25) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).25) + value: + Expr { + ty: S + temp_scope_id: 25 + span: $DIR/thir-tree-field-expr-index.rs:15:16: 15:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(39) + expr: + Expr { + ty: S + temp_scope_id: 32 + span: $DIR/thir-tree-field-expr-index.rs:16:3: 16:19 (#0) + kind: + Scope { + region_scope: Node(32) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).32) + value: + Expr { + ty: S + temp_scope_id: 32 + span: $DIR/thir-tree-field-expr-index.rs:16:3: 16:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 1: + Expr { + ty: u32 + temp_scope_id: 37 + span: $DIR/thir-tree-field-expr-index.rs:16:10: 16:11 (#0) + kind: + Scope { + region_scope: Node(37) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).37) + value: + Expr { + ty: u32 + temp_scope_id: 37 + span: $DIR/thir-tree-field-expr-index.rs:16:10: 16:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 33 + span: $DIR/thir-tree-field-expr-index.rs:16:16: 16:17 (#0) + kind: + Scope { + region_scope: Node(33) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).33) + value: + Expr { + ty: S + temp_scope_id: 33 + span: $DIR/thir-tree-field-expr-index.rs:16:16: 16:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(47) + expr: + Expr { + ty: S + temp_scope_id: 40 + span: $DIR/thir-tree-field-expr-index.rs:17:3: 17:19 (#0) + kind: + Scope { + region_scope: Node(40) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).40) + value: + Expr { + ty: S + temp_scope_id: 40 + span: $DIR/thir-tree-field-expr-index.rs:17:3: 17:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 2: + Expr { + ty: u32 + temp_scope_id: 45 + span: $DIR/thir-tree-field-expr-index.rs:17:10: 17:11 (#0) + kind: + Scope { + region_scope: Node(45) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).45) + value: + Expr { + ty: u32 + temp_scope_id: 45 + span: $DIR/thir-tree-field-expr-index.rs:17:10: 17:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 41 + span: $DIR/thir-tree-field-expr-index.rs:17:16: 17:17 (#0) + kind: + Scope { + region_scope: Node(41) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).41) + value: + Expr { + ty: S + temp_scope_id: 41 + span: $DIR/thir-tree-field-expr-index.rs:17:16: 17:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(55) + expr: + Expr { + ty: S + temp_scope_id: 48 + span: $DIR/thir-tree-field-expr-index.rs:18:3: 18:19 (#0) + kind: + Scope { + region_scope: Node(48) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).48) + value: + Expr { + ty: S + temp_scope_id: 48 + span: $DIR/thir-tree-field-expr-index.rs:18:3: 18:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 3: + Expr { + ty: u32 + temp_scope_id: 53 + span: $DIR/thir-tree-field-expr-index.rs:18:10: 18:11 (#0) + kind: + Scope { + region_scope: Node(53) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).53) + value: + Expr { + ty: u32 + temp_scope_id: 53 + span: $DIR/thir-tree-field-expr-index.rs:18:10: 18:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 49 + span: $DIR/thir-tree-field-expr-index.rs:18:16: 18:17 (#0) + kind: + Scope { + region_scope: Node(49) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).49) + value: + Expr { + ty: S + temp_scope_id: 49 + span: $DIR/thir-tree-field-expr-index.rs:18:16: 18:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(63) + expr: + Expr { + ty: S + temp_scope_id: 56 + span: $DIR/thir-tree-field-expr-index.rs:19:3: 19:19 (#0) + kind: + Scope { + region_scope: Node(56) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).56) + value: + Expr { + ty: S + temp_scope_id: 56 + span: $DIR/thir-tree-field-expr-index.rs:19:3: 19:19 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 4: + Expr { + ty: u32 + temp_scope_id: 61 + span: $DIR/thir-tree-field-expr-index.rs:19:10: 19:11 (#0) + kind: + Scope { + region_scope: Node(61) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).61) + value: + Expr { + ty: u32 + temp_scope_id: 61 + span: $DIR/thir-tree-field-expr-index.rs:19:10: 19:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 57 + span: $DIR/thir-tree-field-expr-index.rs:19:16: 19:17 (#0) + kind: + Scope { + region_scope: Node(57) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).57) + value: + Expr { + ty: S + temp_scope_id: 57 + span: $DIR/thir-tree-field-expr-index.rs:19:16: 19:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(74) + expr: + Expr { + ty: S + temp_scope_id: 64 + span: $DIR/thir-tree-field-expr-index.rs:21:3: 21:24 (#0) + kind: + Scope { + region_scope: Node(64) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).64) + value: + Expr { + ty: S + temp_scope_id: 64 + span: $DIR/thir-tree-field-expr-index.rs:21:3: 21:24 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 1: + Expr { + ty: u32 + temp_scope_id: 69 + span: $DIR/thir-tree-field-expr-index.rs:21:10: 21:11 (#0) + kind: + Scope { + region_scope: Node(69) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).69) + value: + Expr { + ty: u32 + temp_scope_id: 69 + span: $DIR/thir-tree-field-expr-index.rs:21:10: 21:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 3: + Expr { + ty: u32 + temp_scope_id: 72 + span: $DIR/thir-tree-field-expr-index.rs:21:16: 21:17 (#0) + kind: + Scope { + region_scope: Node(72) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).72) + value: + Expr { + ty: u32 + temp_scope_id: 72 + span: $DIR/thir-tree-field-expr-index.rs:21:16: 21:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 65 + span: $DIR/thir-tree-field-expr-index.rs:21:21: 21:22 (#0) + kind: + Scope { + region_scope: Node(65) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).65) + value: + Expr { + ty: S + temp_scope_id: 65 + span: $DIR/thir-tree-field-expr-index.rs:21:21: 21:22 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + Stmt { + kind: Expr { + scope: Node(88) + expr: + Expr { + ty: S + temp_scope_id: 75 + span: $DIR/thir-tree-field-expr-index.rs:22:3: 22:30 (#0) + kind: + Scope { + region_scope: Node(75) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).75) + value: + Expr { + ty: S + temp_scope_id: 75 + span: $DIR/thir-tree-field-expr-index.rs:22:3: 22:30 (#0) + kind: + Adt { + adt_def: + AdtDef { + did: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S) + variants: [VariantDef { def_id: DefId(0:3 ~ thir_tree_field_expr_index[5059]::S), ctor: None, name: "S", discr: Relative(0), fields: [FieldDef { did: DefId(0:4 ~ thir_tree_field_expr_index[5059]::S::a), name: "a", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:5 ~ thir_tree_field_expr_index[5059]::S::b), name: "b", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:6 ~ thir_tree_field_expr_index[5059]::S::c), name: "c", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:7 ~ thir_tree_field_expr_index[5059]::S::d), name: "d", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }, FieldDef { did: DefId(0:8 ~ thir_tree_field_expr_index[5059]::S::e), name: "e", vis: Restricted(DefId(0:0 ~ thir_tree_field_expr_index[5059])), safety: Safe, value: None }], tainted: None, flags: }] + flags: IS_STRUCT + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7076349371981215213 } + } + variant_index: 0 + args: [] + user_ty: None + field 0: + Expr { + ty: u32 + temp_scope_id: 80 + span: $DIR/thir-tree-field-expr-index.rs:22:10: 22:11 (#0) + kind: + Scope { + region_scope: Node(80) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).80) + value: + Expr { + ty: u32 + temp_scope_id: 80 + span: $DIR/thir-tree-field-expr-index.rs:22:10: 22:11 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 2: + Expr { + ty: u32 + temp_scope_id: 83 + span: $DIR/thir-tree-field-expr-index.rs:22:16: 22:17 (#0) + kind: + Scope { + region_scope: Node(83) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).83) + value: + Expr { + ty: u32 + temp_scope_id: 83 + span: $DIR/thir-tree-field-expr-index.rs:22:16: 22:17 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + field 4: + Expr { + ty: u32 + temp_scope_id: 86 + span: $DIR/thir-tree-field-expr-index.rs:22:22: 22:23 (#0) + kind: + Scope { + region_scope: Node(86) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).86) + value: + Expr { + ty: u32 + temp_scope_id: 86 + span: $DIR/thir-tree-field-expr-index.rs:22:22: 22:23 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).2)) + } + } + } + } + base: + FruInfo { + base: + Expr { + ty: S + temp_scope_id: 76 + span: $DIR/thir-tree-field-expr-index.rs:22:27: 22:28 (#0) + kind: + Scope { + region_scope: Node(76) + hir_id: HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).76) + value: + Expr { + ty: S + temp_scope_id: 76 + span: $DIR/thir-tree-field-expr-index.rs:22:27: 22:28 (#0) + kind: + VarRef { + id: LocalVarId(HirId(DefId(0:9 ~ thir_tree_field_expr_index[5059]::update).23)) + } + } + } + } + field_types: [ + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ty: u32 + ] + } + } + } + } + } + } + } + ] + expr: [] + } + } + } + } + + +DefId(0:10 ~ thir_tree_field_expr_index[5059]::main): +params: [ +] +body: + Expr { + ty: () + temp_scope_id: 2 + span: $DIR/thir-tree-field-expr-index.rs:25:11: 25:13 (#0) + kind: + Scope { + region_scope: Node(2) + hir_id: HirId(DefId(0:10 ~ thir_tree_field_expr_index[5059]::main).2) + value: + Expr { + ty: () + temp_scope_id: 2 + span: $DIR/thir-tree-field-expr-index.rs:25:11: 25:13 (#0) + kind: + Block { + targeted_by_break: false + span: $DIR/thir-tree-field-expr-index.rs:25:11: 25:13 (#0) + region_scope: Node(1) + safety_mode: Safe + stmts: [] + expr: [] + } + } + } + } + + diff --git a/tests/ui/thir-print/thir-tree-loop-match.stdout b/tests/ui/thir-print/thir-tree-loop-match.stdout index 5f6b130c3905..1bfd3f0952a3 100644 --- a/tests/ui/thir-print/thir-tree-loop-match.stdout +++ b/tests/ui/thir-print/thir-tree-loop-match.stdout @@ -6,7 +6,7 @@ params: [ self_kind: None hir_id: Some(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).1)) param: Some( - Pat: { + Pat { ty: bool span: $DIR/thir-tree-loop-match.rs:7:12: 7:21 (#0) kind: PatKind { @@ -32,7 +32,7 @@ body: kind: Scope { region_scope: Node(28) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).28)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).28) value: Expr { ty: bool @@ -53,7 +53,7 @@ body: kind: Scope { region_scope: Node(4) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).4)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).4) value: Expr { ty: bool @@ -76,7 +76,7 @@ body: kind: Scope { region_scope: Node(7) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).7)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).7) value: Expr { ty: bool @@ -101,7 +101,7 @@ body: kind: Scope { region_scope: Node(12) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).12)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).12) value: Expr { ty: bool @@ -117,7 +117,7 @@ body: arms: [ Arm { pattern: - Pat: { + Pat { ty: bool span: $DIR/thir-tree-loop-match.rs:12:17: 12:21 (#0) kind: PatKind { @@ -135,7 +135,7 @@ body: kind: Scope { region_scope: Node(17) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).17)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).17) value: Expr { ty: bool @@ -166,7 +166,7 @@ body: kind: Scope { region_scope: Node(19) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).19)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).19) value: Expr { ty: ! @@ -183,7 +183,7 @@ body: kind: Scope { region_scope: Node(20) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).20)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).20) value: Expr { ty: bool @@ -209,13 +209,13 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).16)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).16) scope: Node(16) span: $DIR/thir-tree-loop-match.rs:12:17: 15:18 (#0) } Arm { pattern: - Pat: { + Pat { ty: bool span: $DIR/thir-tree-loop-match.rs:16:17: 16:22 (#0) kind: PatKind { @@ -233,7 +233,7 @@ body: kind: Scope { region_scope: Node(25) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).25)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).25) value: Expr { ty: bool @@ -256,7 +256,7 @@ body: kind: Scope { region_scope: Node(26) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).26)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).26) value: Expr { ty: bool @@ -275,7 +275,7 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).24)) + hir_id: HirId(DefId(0:3 ~ thir_tree_loop_match[3c53]::boolean).24) scope: Node(24) span: $DIR/thir-tree-loop-match.rs:16:17: 16:38 (#0) } @@ -304,7 +304,7 @@ body: kind: Scope { region_scope: Node(2) - lint_level: Explicit(HirId(DefId(0:4 ~ thir_tree_loop_match[3c53]::main).2)) + hir_id: HirId(DefId(0:4 ~ thir_tree_loop_match[3c53]::main).2) value: Expr { ty: () diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index 8a2bad56c126..31f8d368736c 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -6,7 +6,7 @@ params: [ self_kind: None hir_id: Some(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).1)) param: Some( - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:15:14: 15:17 (#0) kind: PatKind { @@ -32,7 +32,7 @@ body: kind: Scope { region_scope: Node(28) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).28)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).28) value: Expr { ty: bool @@ -53,7 +53,7 @@ body: kind: Scope { region_scope: Node(4) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).4)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).4) value: Expr { ty: bool @@ -69,7 +69,7 @@ body: kind: Scope { region_scope: Node(5) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).5)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).5) value: Expr { ty: Foo @@ -85,7 +85,7 @@ body: arms: [ Arm { pattern: - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:17:9: 17:32 (#0) kind: PatKind { @@ -95,11 +95,12 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } + } args: [] variant_index: 0 subpatterns: [ - Pat: { + Pat { ty: Bar span: $DIR/thir-tree-match.rs:17:21: 17:31 (#0) kind: PatKind { @@ -109,7 +110,8 @@ body: did: DefId(0:3 ~ thir_tree_match[fcf8]::Bar) variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], tainted: None, flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 7908585036048874241 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 7908585036048874241 } + } args: [] variant_index: 0 subpatterns: [] @@ -129,7 +131,7 @@ body: kind: Scope { region_scope: Node(15) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).15)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).15) value: Expr { ty: bool @@ -141,13 +143,13 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).14) scope: Node(14) span: $DIR/thir-tree-match.rs:17:9: 17:40 (#0) } Arm { pattern: - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:18:9: 18:23 (#0) kind: PatKind { @@ -157,11 +159,12 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } + } args: [] variant_index: 0 subpatterns: [ - Pat: { + Pat { ty: Bar span: $DIR/thir-tree-match.rs:18:21: 18:22 (#0) kind: PatKind { @@ -181,7 +184,7 @@ body: kind: Scope { region_scope: Node(21) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).21)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).21) value: Expr { ty: bool @@ -193,13 +196,13 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).20) scope: Node(20) span: $DIR/thir-tree-match.rs:18:9: 18:32 (#0) } Arm { pattern: - Pat: { + Pat { ty: Foo span: $DIR/thir-tree-match.rs:19:9: 19:20 (#0) kind: PatKind { @@ -209,7 +212,8 @@ body: did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])), safety: Safe, value: None }], tainted: None, flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], tainted: None, flags: }] flags: IS_ENUM - repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 13397682652773712997 } + repr: ReprOptions { int: None, align: None, pack: None, flags: , scalable: None, field_shuffle_seed: 13397682652773712997 } + } args: [] variant_index: 1 subpatterns: [] @@ -225,7 +229,7 @@ body: kind: Scope { region_scope: Node(27) - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).27)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).27) value: Expr { ty: bool @@ -237,7 +241,7 @@ body: } } } - lint_level: Explicit(HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).26)) + hir_id: HirId(DefId(0:16 ~ thir_tree_match[fcf8]::has_match).26) scope: Node(26) span: $DIR/thir-tree-match.rs:19:9: 19:28 (#0) } @@ -263,7 +267,7 @@ body: kind: Scope { region_scope: Node(2) - lint_level: Explicit(HirId(DefId(0:17 ~ thir_tree_match[fcf8]::main).2)) + hir_id: HirId(DefId(0:17 ~ thir_tree_match[fcf8]::main).2) value: Expr { ty: () diff --git a/tests/ui/thir-print/thir-tree.stdout b/tests/ui/thir-print/thir-tree.stdout index d61176d6480f..25d0ccfa7a05 100644 --- a/tests/ui/thir-print/thir-tree.stdout +++ b/tests/ui/thir-print/thir-tree.stdout @@ -9,7 +9,7 @@ body: kind: Scope { region_scope: Node(2) - lint_level: Explicit(HirId(DefId(0:3 ~ thir_tree[7aaa]::main).2)) + hir_id: HirId(DefId(0:3 ~ thir_tree[7aaa]::main).2) value: Expr { ty: () diff --git a/tests/ui/thread-local/no-unstable.stderr b/tests/ui/thread-local/no-unstable.stderr index fbcd804d9178..438020d00b7d 100644 --- a/tests/ui/thread-local/no-unstable.stderr +++ b/tests/ui/thread-local/no-unstable.stderr @@ -10,7 +10,6 @@ LL | | } = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable = note: the `#[rustc_dummy]` attribute is an internal implementation detail that will never be stable = note: the `#[rustc_dummy]` attribute is used for rustc unit tests - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_process_attrs` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: use of an internal attribute --> $DIR/no-unstable.rs:1:1 @@ -24,7 +23,6 @@ LL | | } = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable = note: the `#[rustc_dummy]` attribute is an internal implementation detail that will never be stable = note: the `#[rustc_dummy]` attribute is used for rustc unit tests - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_process_attrs` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: `#[used(linker)]` is currently unstable --> $DIR/no-unstable.rs:1:1 @@ -38,7 +36,6 @@ LL | | } = note: see issue #93798 for more information = help: add `#![feature(used_with_arg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_process_attrs` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) error: `#[used]` attribute cannot be used on constants --> $DIR/no-unstable.rs:1:1 @@ -50,7 +47,6 @@ LL | | } | |_^ | = help: `#[used]` can only be applied to statics - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_process_attrs` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/thread-local/non-static.rs b/tests/ui/thread-local/non-static.rs index f1c4273870bf..f14ff20f449b 100644 --- a/tests/ui/thread-local/non-static.rs +++ b/tests/ui/thread-local/non-static.rs @@ -2,19 +2,19 @@ #![feature(thread_local)] #[thread_local] -//~^ ERROR attribute should be applied to a static +//~^ ERROR `#[thread_local]` attribute cannot be used on constants const A: u32 = 0; #[thread_local] -//~^ ERROR attribute should be applied to a static +//~^ ERROR `#[thread_local]` attribute cannot be used on functions fn main() { #[thread_local] || {}; - //~^ ERROR attribute should be applied to a static + //~^ ERROR `#[thread_local]` attribute cannot be used on closures } struct S { #[thread_local] - //~^ ERROR attribute should be applied to a static + //~^ ERROR `#[thread_local]` attribute cannot be used on struct fields a: String, b: String, } diff --git a/tests/ui/thread-local/non-static.stderr b/tests/ui/thread-local/non-static.stderr index 09a1618d6e71..c83a6beb4c6a 100644 --- a/tests/ui/thread-local/non-static.stderr +++ b/tests/ui/thread-local/non-static.stderr @@ -1,38 +1,34 @@ -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on constants --> $DIR/non-static.rs:4:1 | LL | #[thread_local] | ^^^^^^^^^^^^^^^ -LL | -LL | const A: u32 = 0; - | ----------------- not a static + | + = help: `#[thread_local]` can be applied to foreign statics and statics -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on functions --> $DIR/non-static.rs:8:1 | -LL | #[thread_local] - | ^^^^^^^^^^^^^^^ -LL | -LL | / fn main() { -LL | | #[thread_local] || {}; -LL | | -LL | | } - | |_- not a static +LL | #[thread_local] + | ^^^^^^^^^^^^^^^ + | + = help: `#[thread_local]` can be applied to foreign statics and statics -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on closures --> $DIR/non-static.rs:11:5 | LL | #[thread_local] || {}; - | ^^^^^^^^^^^^^^^ ----- not a static + | ^^^^^^^^^^^^^^^ + | + = help: `#[thread_local]` can be applied to foreign statics and statics -error: attribute should be applied to a static +error: `#[thread_local]` attribute cannot be used on struct fields --> $DIR/non-static.rs:16:5 | LL | #[thread_local] | ^^^^^^^^^^^^^^^ -LL | -LL | a: String, - | --------- not a static + | + = help: `#[thread_local]` can be applied to foreign statics and statics error: aborting due to 4 previous errors diff --git a/tests/ui/threads-sendsync/recursive-thread-spawn.rs b/tests/ui/threads-sendsync/recursive-thread-spawn.rs new file mode 100644 index 000000000000..974f3a74f146 --- /dev/null +++ b/tests/ui/threads-sendsync/recursive-thread-spawn.rs @@ -0,0 +1,21 @@ +//@ check-pass + +use std::thread::Builder; + +static GENERATIONS: usize = 1024 + 256 + 128 + 49; + +fn spawn(mut f: Box) { + Builder::new().stack_size(32 * 1024).spawn(move || f()); +} + +fn child_no(x: usize) -> Box { + Box::new(move || { + if x < GENERATIONS { + spawn(child_no(x + 1)); + } + }) +} + +pub fn main() { + spawn(child_no(0)); +} diff --git a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs index b2d22631c1a5..42135fe1c45b 100644 --- a/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs +++ b/tests/ui/threads-sendsync/std-sync-right-kind-impls.rs @@ -1,6 +1,6 @@ //@ run-pass -use std::sync; +use std::{fs, net, sync}; fn assert_both() {} @@ -12,4 +12,20 @@ fn main() { assert_both::>(); assert_both::>(); assert_both::(); + + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::(); } diff --git a/tests/ui/threads-sendsync/thread-join-unwrap.rs b/tests/ui/threads-sendsync/thread-join-unwrap.rs new file mode 100644 index 000000000000..6288e15b1874 --- /dev/null +++ b/tests/ui/threads-sendsync/thread-join-unwrap.rs @@ -0,0 +1,9 @@ +//! Regression test for unwrapping the result of `join`, issue https://github.com/rust-lang/rust/issues/21291 +//@ run-pass +//@ needs-threads + +use std::thread; + +fn main() { + thread::spawn(|| {}).join().unwrap() +} diff --git a/tests/ui/threads-sendsync/tls-init-on-init.rs b/tests/ui/threads-sendsync/tls-init-on-init.rs index 1cae19aae86c..d7c110e80e85 100644 --- a/tests/ui/threads-sendsync/tls-init-on-init.rs +++ b/tests/ui/threads-sendsync/tls-init-on-init.rs @@ -1,7 +1,5 @@ //@ run-pass -#![allow(stable_features)] //@ needs-threads -#![feature(thread_local_try_with)] use std::sync::atomic::{AtomicUsize, Ordering}; use std::thread; diff --git a/tests/ui/threads-sendsync/tls-try-with.rs b/tests/ui/threads-sendsync/tls-try-with.rs index 04071e77daa4..1d0c5de7d87f 100644 --- a/tests/ui/threads-sendsync/tls-try-with.rs +++ b/tests/ui/threads-sendsync/tls-try-with.rs @@ -1,7 +1,5 @@ //@ run-pass -#![allow(stable_features)] //@ needs-threads -#![feature(thread_local_try_with)] use std::thread; diff --git a/tests/ui/tool-attributes/tool-attributes-shadowing.rs b/tests/ui/tool-attributes/tool-attributes-shadowing.rs index 21bbaa3a7105..582c99b089f5 100644 --- a/tests/ui/tool-attributes/tool-attributes-shadowing.rs +++ b/tests/ui/tool-attributes/tool-attributes-shadowing.rs @@ -1,4 +1,4 @@ mod rustfmt {} -#[rustfmt::skip] //~ ERROR failed to resolve: could not find `skip` in `rustfmt` +#[rustfmt::skip] //~ ERROR: cannot find `skip` in `rustfmt` fn main() {} diff --git a/tests/ui/tool-attributes/tool-attributes-shadowing.stderr b/tests/ui/tool-attributes/tool-attributes-shadowing.stderr index f2da61727228..5ca1fdf586d4 100644 --- a/tests/ui/tool-attributes/tool-attributes-shadowing.stderr +++ b/tests/ui/tool-attributes/tool-attributes-shadowing.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `skip` in `rustfmt` +error[E0433]: cannot find `skip` in `rustfmt` --> $DIR/tool-attributes-shadowing.rs:3:12 | LL | #[rustfmt::skip] diff --git a/tests/ui/tool-attributes/unknown-tool-name.rs b/tests/ui/tool-attributes/unknown-tool-name.rs index ba21aecc230a..a87385329eff 100644 --- a/tests/ui/tool-attributes/unknown-tool-name.rs +++ b/tests/ui/tool-attributes/unknown-tool-name.rs @@ -1,2 +1,3 @@ -#[foo::bar] //~ ERROR failed to resolve: use of unresolved module or unlinked crate `foo` +#[foo::bar] //~ ERROR: cannot find module or crate `foo` +//~^ NOTE: use of unresolved module or unlinked crate `foo` fn main() {} diff --git a/tests/ui/tool-attributes/unknown-tool-name.stderr b/tests/ui/tool-attributes/unknown-tool-name.stderr index 9b636fcb0bdd..5a2b0e840be3 100644 --- a/tests/ui/tool-attributes/unknown-tool-name.stderr +++ b/tests/ui/tool-attributes/unknown-tool-name.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `foo` +error[E0433]: cannot find module or crate `foo` in this scope --> $DIR/unknown-tool-name.rs:1:3 | LL | #[foo::bar] diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs index 2d6d6170fe0b..09864a6e3090 100644 --- a/tests/ui/track-diagnostics/track.rs +++ b/tests/ui/track-diagnostics/track.rs @@ -7,6 +7,7 @@ // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" //@ normalize-stderr: "note: rustc .+ running on .+" -> "note: rustc $$VERSION running on $$TARGET" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" // The test becomes too flaky if we care about exact args. If `-Z ui-testing` // from compiletest and `-Z track-diagnostics` from `// compile-flags` at the diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs index 591b84f330b7..145b2a3e5d57 100644 --- a/tests/ui/track-diagnostics/track2.rs +++ b/tests/ui/track-diagnostics/track2.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" fn main() { let _moved @ _from = String::from("foo"); diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs index a39e71915d90..144f2794e910 100644 --- a/tests/ui/track-diagnostics/track3.rs +++ b/tests/ui/track-diagnostics/track3.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" fn main() { let _unimported = Blah { field: u8 }; diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs index 0038c616aa55..2ab7d5423303 100644 --- a/tests/ui/track-diagnostics/track4.rs +++ b/tests/ui/track-diagnostics/track4.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" pub onion { //~^ ERROR missing `enum` for enum definition diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs index 09fda4eb5273..4d47f56e5806 100644 --- a/tests/ui/track-diagnostics/track5.rs +++ b/tests/ui/track-diagnostics/track5.rs @@ -4,6 +4,7 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" } //~^ ERROR unexpected closing delimiter: `}` diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index 11d3b7e9764b..aa75c5691e5f 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -4,13 +4,13 @@ // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" - +//@ normalize-stderr: "/rustc(?:-dev)?/[a-z0-9.]+/" -> "" pub trait Foo { fn bar(); } -impl Foo for T { +impl Foo for T { default fn bar() {} //~^ ERROR specialization is unstable //~| NOTE created at diff --git a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs index d8fd1d44a985..37fa01692053 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.rs @@ -9,3 +9,11 @@ fn main() { //~| HELP try using a fully qualified path to specify the expected types //~| HELP consider removing this method call, as the receiver has type `Bar` and `Bar: From` trivially holds } + +// regression test for https://github.com/rust-lang/rust/issues/149487. +fn quux() { + let mut tx_heights: std::collections::BTreeMap<(), Option<()>> = <_>::default(); + tx_heights.get(&()).unwrap_or_default(); + //~^ ERROR the trait bound `&Option<()>: Default` is not satisfied + //~| HELP: the trait `Default` is implemented for `Option` +} diff --git a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr index 7d795581ea9d..f0c993125279 100644 --- a/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr +++ b/tests/ui/trait-bounds/argument-with-unnecessary-method-call.stderr @@ -23,6 +23,18 @@ LL - qux(Bar.into()); LL + qux(Bar); | -error: aborting due to 1 previous error +error[E0277]: the trait bound `&Option<()>: Default` is not satisfied + --> $DIR/argument-with-unnecessary-method-call.rs:16:25 + | +LL | tx_heights.get(&()).unwrap_or_default(); + | ^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `&Option<()>` + | +help: the trait `Default` is implemented for `Option` + --> $SRC_DIR/core/src/option.rs:LL:COL +note: required by a bound in `Option::::unwrap_or_default` + --> $SRC_DIR/core/src/option.rs:LL:COL -For more information about this error, try `rustc --explain E0283`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0283. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/trait-bounds/sort-missing-ord-bound.rs b/tests/ui/trait-bounds/sort-missing-ord-bound.rs new file mode 100644 index 000000000000..8d4ea8815017 --- /dev/null +++ b/tests/ui/trait-bounds/sort-missing-ord-bound.rs @@ -0,0 +1,10 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/20162 +struct X { + x: i32, +} + +fn main() { + let mut b: Vec = vec![]; + b.sort(); + //~^ ERROR `X: Ord` is not satisfied +} diff --git a/tests/ui/trait-bounds/sort-missing-ord-bound.stderr b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr new file mode 100644 index 000000000000..c11781e5fff3 --- /dev/null +++ b/tests/ui/trait-bounds/sort-missing-ord-bound.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `X: Ord` is not satisfied + --> $DIR/sort-missing-ord-bound.rs:8:7 + | +LL | b.sort(); + | ^^^^ the trait `Ord` is not implemented for `X` + | +note: required by a bound in `slice::::sort` + --> $SRC_DIR/alloc/src/slice.rs:LL:COL +help: consider annotating `X` with `#[derive(Ord)]` + | +LL + #[derive(Ord)] +LL | struct X { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr b/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr index 4ce936582f43..b459ad47e067 100644 --- a/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr +++ b/tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr @@ -22,7 +22,7 @@ LL | type P = [u8]; | ^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` -note: required by a bound in `Trait::P` +note: required by a bound in `main::Trait::P` --> $DIR/suggest-maybe-sized-bound.rs:13:9 | LL | type P; diff --git a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr index dfa47f2ab468..9ae209d5aa96 100644 --- a/tests/ui/trait-bounds/unstable-trait-suggestion.stderr +++ b/tests/ui/trait-bounds/unstable-trait-suggestion.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: Unstable` is not satisfied --> $DIR/unstable-trait-suggestion.rs:13:9 | LL | foo(t) - | --- ^ the trait `Unstable` is not implemented for `T` + | --- ^ the nightly-only, unstable trait `Unstable` is not implemented for `T` | | | required by a bound introduced by this call | @@ -16,12 +16,13 @@ help: consider restricting type parameter `T` with unstable trait `Unstable` LL | pub fn bar(t: T) { | ++++++++++ -error[E0277]: the trait bound `T: Step` is not satisfied +error[E0277]: `std::ops::Range` is not an iterator --> $DIR/unstable-trait-suggestion.rs:17:14 | LL | for _ in t {} - | ^ the trait `Step` is not implemented for `T` + | ^ `Range` is not an iterator | + = note: `Range` only implements `Iterator` for select types in the standard library, particularly integers; to see the full list of types, see the documentation for the unstable `Step` trait = note: required for `std::ops::Range` to implement `Iterator` = note: required for `std::ops::Range` to implement `IntoIterator` help: consider restricting type parameter `T` with unstable trait `Step` diff --git a/tests/ui/traits/alias/object-fail.stderr b/tests/ui/traits/alias/object-fail.stderr index d60d88434077..088af686258a 100644 --- a/tests/ui/traits/alias/object-fail.stderr +++ b/tests/ui/traits/alias/object-fail.stderr @@ -19,7 +19,7 @@ error[E0191]: the value of the associated type `Item` in `Iterator` must be spec --> $DIR/object-fail.rs:9:17 | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); - | ^^^^^^^^^^^^^ help: specify the associated type: `IteratorAlias` + | ^^^^^^^^^^^^^ help: specify the associated type: `IteratorAlias` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/associated-item-unsatisfied-trait-bounds.rs b/tests/ui/traits/associated-item-unsatisfied-trait-bounds.rs new file mode 100644 index 000000000000..4fb4cd61ac51 --- /dev/null +++ b/tests/ui/traits/associated-item-unsatisfied-trait-bounds.rs @@ -0,0 +1,9 @@ +struct Foo; +trait Bar {} +trait Baz {} +trait Bat { fn bat(&self); } +impl Bat for T where T: 'static + Bar + Baz { fn bat(&self) { println!("generic bat"); } } + +pub fn main() { + Foo::bat(()); //~ ERROR E0599 +} diff --git a/tests/ui/traits/associated-item-unsatisfied-trait-bounds.stderr b/tests/ui/traits/associated-item-unsatisfied-trait-bounds.stderr new file mode 100644 index 000000000000..42969de715eb --- /dev/null +++ b/tests/ui/traits/associated-item-unsatisfied-trait-bounds.stderr @@ -0,0 +1,33 @@ +error[E0599]: the function or associated item `bat` exists for struct `Foo`, but its trait bounds were not satisfied + --> $DIR/associated-item-unsatisfied-trait-bounds.rs:8:10 + | +LL | struct Foo; + | ---------- function or associated item `bat` not found for this struct because `Foo` doesn't implement `Bar` or `Baz` +... +LL | Foo::bat(()); + | ^^^ function or associated item cannot be called on `Foo` due to unsatisfied trait bounds + | +note: for `bat` to be available, `Foo` must implement `Bar` and `Baz` + --> $DIR/associated-item-unsatisfied-trait-bounds.rs:5:38 + | +LL | impl Bat for T where T: 'static + Bar + Baz { fn bat(&self) { println!("generic bat"); } } + | --- - ^^^ ^^^ unsatisfied trait bound introduced here + | | + | unsatisfied trait bound introduced here +note: the traits `Bar` and `Baz` must be implemented + --> $DIR/associated-item-unsatisfied-trait-bounds.rs:2:1 + | +LL | trait Bar {} + | ^^^^^^^^^ +LL | trait Baz {} + | ^^^^^^^^^ + = help: items from traits can only be used if the trait is implemented and in scope +note: `Bat` defines an item `bat`, perhaps you need to implement it + --> $DIR/associated-item-unsatisfied-trait-bounds.rs:4:1 + | +LL | trait Bat { fn bat(&self); } + | ^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs new file mode 100644 index 000000000000..f1dffc0ff6b4 --- /dev/null +++ b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs @@ -0,0 +1,17 @@ +// A regression test for https://github.com/rust-lang/rust/issues/148121 + +pub trait Super { + type X; +} + +pub trait Zelf: Super {} + +pub trait A {} + +impl A for dyn Super {} +//~^ ERROR: trait takes 1 generic argument but 0 generic arguments were supplied + +impl A for dyn Zelf {} +//~^ ERROR: trait takes 1 generic argument but 0 generic arguments were supplied + +fn main() {} diff --git a/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr new file mode 100644 index 000000000000..5a7969193b55 --- /dev/null +++ b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr @@ -0,0 +1,35 @@ +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:11:16 + | +LL | impl A for dyn Super {} + | ^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `X` + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:3:11 + | +LL | pub trait Super { + | ^^^^^ - +help: add missing generic argument + | +LL | impl A for dyn Super {} + | ++ + +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:14:16 + | +LL | impl A for dyn Zelf {} + | ^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `X` + --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:7:11 + | +LL | pub trait Zelf: Super {} + | ^^^^ - +help: add missing generic argument + | +LL | impl A for dyn Zelf {} + | ++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr index 40936ce1ec34..660bbc120d0e 100644 --- a/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr +++ b/tests/ui/traits/associated_type_bound/assoc_type_bound_with_struct.stderr @@ -84,11 +84,15 @@ error[E0404]: expected trait, found struct `String` --> $DIR/assoc_type_bound_with_struct.rs:19:51 | LL | fn issue_95327() where ::Assoc: String {} - | ^^^^^^ help: a trait with a similar name exists: `ToString` + | ^^^^^^ | --> $SRC_DIR/alloc/src/string.rs:LL:COL | = note: similarly named trait `ToString` defined here +help: a trait with a similar name exists + | +LL | fn issue_95327() where ::Assoc: ToString {} + | ++ error: aborting due to 6 previous errors diff --git a/tests/ui/traits/auxiliary/force_unstable.rs b/tests/ui/traits/auxiliary/force_unstable.rs new file mode 100644 index 000000000000..ce71e1241f9c --- /dev/null +++ b/tests/ui/traits/auxiliary/force_unstable.rs @@ -0,0 +1,7 @@ +//@ edition: 2024 +//@ compile-flags: -Zforce-unstable-if-unmarked + +// Auxiliary crate that uses `-Zforce-unstable-if-unmarked` to export an +// "unstable" trait. + +pub trait ForeignTrait {} diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc.stderr index 5064b60bfd57..472ac187a966 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-xc.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-xc.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `usize: Trait` is not satisfied +error[E0277]: the trait bound `usize: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc.rs:7:15 | LL | fn explode(x: Foo) {} - | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` + | ^^^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `usize` | note: required by a bound in `Foo` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18 @@ -10,11 +10,11 @@ note: required by a bound in `Foo` LL | pub struct Foo { | ^^^^^ required by this bound in `Foo` -error[E0277]: the trait bound `f32: Trait` is not satisfied +error[E0277]: the trait bound `f32: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc.rs:10:14 | LL | fn kaboom(y: Bar) {} - | ^^^^^^^^ the trait `Trait` is not implemented for `f32` + | ^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `f32` | note: required by a bound in `Bar` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16 diff --git a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr index 1f46415e2436..5cf682a5045e 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-xc1.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `{integer}: Trait` is not satisfied +error[E0277]: the trait bound `{integer}: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc1.rs:9:12 | LL | x: 3 - | ^ the trait `Trait` is not implemented for `{integer}` + | ^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `{integer}` | note: required by a bound in `Foo` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:18 @@ -10,11 +10,11 @@ note: required by a bound in `Foo` LL | pub struct Foo { | ^^^^^ required by this bound in `Foo` -error[E0277]: the trait bound `f64: Trait` is not satisfied +error[E0277]: the trait bound `f64: on_structs_and_enums_xc::Trait` is not satisfied --> $DIR/on-structs-and-enums-xc1.rs:12:14 | LL | let bar: Bar = return; - | ^^^^^^^^ the trait `Trait` is not implemented for `f64` + | ^^^^^^^^ the trait `on_structs_and_enums_xc::Trait` is not implemented for `f64` | note: required by a bound in `Bar` --> $DIR/auxiliary/on_structs_and_enums_xc.rs:9:16 diff --git a/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs b/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs new file mode 100644 index 000000000000..41ae91afad49 --- /dev/null +++ b/tests/ui/traits/bound/recursive-trait-bound-on-type-param.rs @@ -0,0 +1,12 @@ +//! regression test for +//@ check-pass + +trait A {} +struct B +where + B: A>, +{ + t: T, +} + +fn main() {} diff --git a/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs b/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs index 0da68afb5926..1b04d8f91827 100644 --- a/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs +++ b/tests/ui/traits/bound/unknown-assoc-with-const-arg.rs @@ -7,7 +7,7 @@ trait X { trait Y { fn a() -> NOT_EXIST::unknown<{}> {} - //~^ ERROR: failed to resolve: use of undeclared type `NOT_EXIST` + //~^ ERROR: cannot find type `NOT_EXIST` } trait Z { diff --git a/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr b/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr index 49e41f75ff35..6a78fa04fe66 100644 --- a/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr +++ b/tests/ui/traits/bound/unknown-assoc-with-const-arg.stderr @@ -10,7 +10,7 @@ error[E0220]: associated type `unknown` not found for `T` LL | fn a() -> T::unknown<{}> {} | ^^^^^^^ associated type `unknown` not found -error[E0433]: failed to resolve: use of undeclared type `NOT_EXIST` +error[E0433]: cannot find type `NOT_EXIST` in this scope --> $DIR/unknown-assoc-with-const-arg.rs:9:15 | LL | fn a() -> NOT_EXIST::unknown<{}> {} diff --git a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr index 5f4974e6f237..6a7d3c850c92 100644 --- a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr +++ b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr @@ -5,7 +5,7 @@ LL | type Output; | ----------- `Output` defined here ... LL | let x = &10 as &dyn Add; - | ^^^ help: specify the associated type: `Add` + | ^^^ help: specify the associated type: `Add` error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/call.rs b/tests/ui/traits/const-traits/call.rs index b1080fe78bb5..360c08e1b7fe 100644 --- a/tests/ui/traits/const-traits/call.rs +++ b/tests/ui/traits/const-traits/call.rs @@ -3,7 +3,7 @@ #![feature(const_closures, const_trait_impl)] #![allow(incomplete_features)] -pub const _: () = { +const _: () = { assert!((const || true)()); //~^ ERROR }: [const] Fn()` is not satisfied }; diff --git a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs index 30002038f689..e355ee724d1b 100644 --- a/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs +++ b/tests/ui/traits/const-traits/const_closure-const_trait_impl-ice-113381.rs @@ -13,6 +13,4 @@ impl Foo for () { fn main() { (const || (()).foo())(); - // ^ ERROR: cannot call non-const method `<() as Foo>::foo` in constant functions - // FIXME(const_trait_impl) this should probably say constant closures } diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs index 0bc25ce5f650..e61ae2760aab 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.rs @@ -1,15 +1,15 @@ -//@ known-bug: #110395 -#![feature(derive_const)] +#![feature(const_default, derive_const)] pub struct A; -impl std::fmt::Debug for A { - fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - panic!() +impl Default for A { + fn default() -> A { + A } } -#[derive_const(Debug)] +#[derive_const(Default)] pub struct S(A); +//~^ ERROR: cannot call non-const associated function fn main() {} diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr index 93638801895d..558957985328 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-non-const-type.stderr @@ -1,20 +1,13 @@ -error: const `impl` for trait `Debug` which is not `const` - --> $DIR/derive-const-non-const-type.rs:12:16 +error[E0015]: cannot call non-const associated function `::default` in constant functions + --> $DIR/derive-const-non-const-type.rs:12:14 | -LL | #[derive_const(Debug)] - | ^^^^^ this trait is not `const` - | - = note: marking a trait with `const` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error[E0015]: cannot call non-const method `Formatter::<'_>::debug_tuple_field1_finish` in constant functions - --> $DIR/derive-const-non-const-type.rs:12:16 - | -LL | #[derive_const(Debug)] - | ^^^^^ +LL | #[derive_const(Default)] + | ------- in this derive macro expansion +LL | pub struct S(A); + | ^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr index e499451d8971..d2eea3a805d9 100644 --- a/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr +++ b/tests/ui/traits/const-traits/ice-120503-async-const-method.stderr @@ -42,10 +42,16 @@ error[E0425]: cannot find function `main8` in this scope --> $DIR/ice-120503-async-const-method.rs:11:9 | LL | main8().await; - | ^^^^^ help: a function with a similar name exists: `main` + | ^^^^^ ... LL | fn main() {} | --------- similarly named function `main` defined here + | +help: a function with a similar name exists + | +LL - main8().await; +LL + main().await; + | error: aborting due to 5 previous errors diff --git a/tests/ui/traits/const-traits/issue-102156.stderr b/tests/ui/traits/const-traits/issue-102156.stderr index 20505b685f30..1fce5f1b18fe 100644 --- a/tests/ui/traits/const-traits/issue-102156.stderr +++ b/tests/ui/traits/const-traits/issue-102156.stderr @@ -1,22 +1,27 @@ -error[E0433]: failed to resolve: you might be missing crate `core` +error[E0433]: cannot find `core` in the crate root --> $DIR/issue-102156.rs:5:5 | LL | use core::convert::{From, TryFrom}; - | ^^^^ - | | - | you might be missing crate `core` - | help: try using `std` instead of `core`: `std` + | ^^^^ you might be missing crate `core` + | +help: try using `std` instead of `core` + | +LL - use core::convert::{From, TryFrom}; +LL + use std::convert::{From, TryFrom}; + | -error[E0433]: failed to resolve: you might be missing crate `core` +error[E0433]: cannot find `core` in the crate root --> $DIR/issue-102156.rs:5:5 | LL | use core::convert::{From, TryFrom}; - | ^^^^ - | | - | you might be missing crate `core` - | help: try using `std` instead of `core`: `std` + | ^^^^ you might be missing crate `core` | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: try using `std` instead of `core` + | +LL - use core::convert::{From, TryFrom}; +LL + use std::convert::{From, TryFrom}; + | error: aborting due to 2 previous errors diff --git a/tests/ui/traits/const-traits/issue-79450.rs b/tests/ui/traits/const-traits/issue-79450.rs index e74da811fc80..c6234f8616d7 100644 --- a/tests/ui/traits/const-traits/issue-79450.rs +++ b/tests/ui/traits/const-traits/issue-79450.rs @@ -5,7 +5,7 @@ const trait Tr { fn req(&self); fn prov(&self) { - println!("lul"); //~ ERROR: cannot call non-const function `_print` in constant functions + println!("lul"); //~ ERROR: cannot call non-const function `std::io::_print` in constant functions self.req(); } } diff --git a/tests/ui/traits/const-traits/issue-79450.stderr b/tests/ui/traits/const-traits/issue-79450.stderr index c10023e9f0ef..82d5ea34582f 100644 --- a/tests/ui/traits/const-traits/issue-79450.stderr +++ b/tests/ui/traits/const-traits/issue-79450.stderr @@ -1,4 +1,4 @@ -error[E0015]: cannot call non-const function `_print` in constant functions +error[E0015]: cannot call non-const function `std::io::_print` in constant functions --> $DIR/issue-79450.rs:8:9 | LL | println!("lul"); @@ -7,7 +7,6 @@ LL | println!("lul"); note: function `_print` is not const --> $SRC_DIR/std/src/io/stdio.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/mismatched_generic_args.stderr b/tests/ui/traits/const-traits/mismatched_generic_args.stderr index 8e12b40381fd..e8103313dc4f 100644 --- a/tests/ui/traits/const-traits/mismatched_generic_args.stderr +++ b/tests/ui/traits/const-traits/mismatched_generic_args.stderr @@ -5,7 +5,13 @@ LL | pub fn add(x: Quantity) -> Quantity { | - similarly named const parameter `U` defined here LL | LL | x + y - | ^ help: a const parameter with a similar name exists: `U` + | ^ + | +help: a const parameter with a similar name exists + | +LL - x + y +LL + x + U + | warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/mismatched_generic_args.rs:1:12 diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs index d0470fa34584..de5bedf0ace7 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.rs @@ -10,6 +10,8 @@ impl Foo for () { } fn main() { + // #150052 deduplicate diagnostics for const trait supertraits + // so we only get one error here (const || { (()).foo() })(); //~^ ERROR: }: [const] Fn()` is not satisfied } diff --git a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr index dcf65ab69408..efbedca1c7e7 100644 --- a/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr +++ b/tests/ui/traits/const-traits/non-const-op-const-closure-non-const-outer.stderr @@ -1,5 +1,5 @@ -error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:13:6: 13:14}: [const] Fn()` is not satisfied - --> $DIR/non-const-op-const-closure-non-const-outer.rs:13:5 +error[E0277]: the trait bound `{closure@$DIR/non-const-op-const-closure-non-const-outer.rs:15:6: 15:14}: [const] Fn()` is not satisfied + --> $DIR/non-const-op-const-closure-non-const-outer.rs:15:5 | LL | (const || { (()).foo() })(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/traits/const-traits/partial/attr-gate.rs b/tests/ui/traits/const-traits/partial/attr-gate.rs new file mode 100644 index 000000000000..c59a03de2153 --- /dev/null +++ b/tests/ui/traits/const-traits/partial/attr-gate.rs @@ -0,0 +1,7 @@ +trait A { + #[rustc_non_const_trait_method] + //~^ ERROR: use of an internal attribute + fn a(); +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/partial/attr-gate.stderr b/tests/ui/traits/const-traits/partial/attr-gate.stderr new file mode 100644 index 000000000000..e46e35d036be --- /dev/null +++ b/tests/ui/traits/const-traits/partial/attr-gate.stderr @@ -0,0 +1,13 @@ +error[E0658]: use of an internal attribute + --> $DIR/attr-gate.rs:2:5 + | +LL | #[rustc_non_const_trait_method] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + = note: the `#[rustc_non_const_trait_method]` attribute is an internal implementation detail that will never be stable + = note: `#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods as non-const to allow large traits an easier transition to const + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/const-traits/partial/no-const-callers.rs b/tests/ui/traits/const-traits/partial/no-const-callers.rs new file mode 100644 index 000000000000..7c198f41ce42 --- /dev/null +++ b/tests/ui/traits/const-traits/partial/no-const-callers.rs @@ -0,0 +1,39 @@ +#![feature(const_trait_impl, rustc_attrs)] + +const trait A { + fn a(); + #[rustc_non_const_trait_method] + fn b() { println!("hi"); } +} + +impl const A for () { + fn a() {} +} + +impl const A for u8 { + fn a() {} + fn b() { println!("hello"); } + //~^ ERROR: cannot call non-const function +} + +impl const A for i8 { + fn a() {} + fn b() {} +} + +const fn foo() { + T::a(); + T::b(); + //~^ ERROR: cannot call non-const associated function + <()>::a(); + <()>::b(); + //~^ ERROR: cannot call non-const associated function + u8::a(); + u8::b(); + //~^ ERROR: cannot call non-const associated function + i8::a(); + i8::b(); + //~^ ERROR: cannot call non-const associated function +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/partial/no-const-callers.stderr b/tests/ui/traits/const-traits/partial/no-const-callers.stderr new file mode 100644 index 000000000000..bbb4495943ed --- /dev/null +++ b/tests/ui/traits/const-traits/partial/no-const-callers.stderr @@ -0,0 +1,45 @@ +error[E0015]: cannot call non-const function `std::io::_print` in constant functions + --> $DIR/no-const-callers.rs:15:14 + | +LL | fn b() { println!("hello"); } + | ^^^^^^^^^^^^^^^^^ + | +note: function `_print` is not const + --> $SRC_DIR/std/src/io/stdio.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const associated function `::b` in constant functions + --> $DIR/no-const-callers.rs:26:5 + | +LL | T::b(); + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const associated function `<() as A>::b` in constant functions + --> $DIR/no-const-callers.rs:29:5 + | +LL | <()>::b(); + | ^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const associated function `::b` in constant functions + --> $DIR/no-const-callers.rs:32:5 + | +LL | u8::b(); + | ^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error[E0015]: cannot call non-const associated function `::b` in constant functions + --> $DIR/no-const-callers.rs:35:5 + | +LL | i8::b(); + | ^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/rustc-impl-const-stability.rs b/tests/ui/traits/const-traits/rustc-impl-const-stability.rs new file mode 100644 index 000000000000..7d30342d11ca --- /dev/null +++ b/tests/ui/traits/const-traits/rustc-impl-const-stability.rs @@ -0,0 +1,18 @@ +//@ check-pass + +#![crate_type = "lib"] +#![feature(staged_api, const_trait_impl, const_default)] +#![stable(feature = "foo", since = "1.0.0")] + +#[stable(feature = "potato", since = "1.27.0")] +pub struct Data { + _data: u128, +} + +#[stable(feature = "potato", since = "1.27.0")] +#[rustc_const_unstable(feature = "data_foo", issue = "none")] +impl const Default for Data { + fn default() -> Data { + Data { _data: 0xbeef } + } +} diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs index 5125d2580238..f771107ec068 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.rs @@ -1,7 +1,5 @@ // Tests that trait bounds on specializing trait impls must be `[const]` if the // same bound is present on the default impl and is `[const]` there. -//@ known-bug: #110395 -// FIXME(const_trait_impl) ^ should error #![feature(const_trait_impl)] #![feature(rustc_attrs)] @@ -23,9 +21,9 @@ where default fn bar() {} } -impl Bar for T +impl Bar for T //~ ERROR conflicting implementations of trait `Bar` where - T: Foo, //FIXME ~ ERROR missing `[const]` qualifier + T: Foo, T: Specialize, { fn bar() {} @@ -42,7 +40,7 @@ where default fn baz() {} } -impl const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz` +impl const Baz for T //~ ERROR conflicting implementations of trait `Baz` where T: Foo, T: Specialize, diff --git a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr index 85e9fda5c2a3..ff27559c8ec6 100644 --- a/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr +++ b/tests/ui/traits/const-traits/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Bar` - --> $DIR/const-default-bound-non-const-specialized-bound.rs:26:1 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:24:1 | LL | / impl const Bar for T LL | | where @@ -8,19 +8,19 @@ LL | | T: [const] Foo, ... LL | / impl Bar for T LL | | where -LL | | T: Foo, //FIXME ~ ERROR missing `[const]` qualifier +LL | | T: Foo, LL | | T: Specialize, | |__________________^ conflicting implementation error[E0119]: conflicting implementations of trait `Baz` - --> $DIR/const-default-bound-non-const-specialized-bound.rs:45:1 + --> $DIR/const-default-bound-non-const-specialized-bound.rs:43:1 | LL | / impl const Baz for T LL | | where LL | | T: [const] Foo, | |___________________- first implementation here ... -LL | / impl const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz` +LL | / impl const Baz for T LL | | where LL | | T: Foo, LL | | T: Specialize, diff --git a/tests/ui/traits/const-traits/specialization/pass.rs b/tests/ui/traits/const-traits/specialization/pass.rs new file mode 100644 index 000000000000..0ba4e40ee30a --- /dev/null +++ b/tests/ui/traits/const-traits/specialization/pass.rs @@ -0,0 +1,53 @@ +//@ check-pass +#![feature(const_trait_impl, const_default, min_specialization, rustc_attrs)] +#![allow(internal_features)] + +#[rustc_specialization_trait] +pub const unsafe trait Sup { + fn foo() -> u32; +} + +#[rustc_specialization_trait] +pub const unsafe trait Sub: [const] Sup {} + +unsafe impl const Sup for u8 { + default fn foo() -> u32 { + 1 + } +} + +unsafe impl const Sup for () { + fn foo() -> u32 { + 42 + } +} + +unsafe impl const Sub for () {} + +pub const trait A { + fn a() -> u32; +} + +impl const A for T { + default fn a() -> u32 { + 2 + } +} + +impl const A for T { + default fn a() -> u32 { + 3 + } +} + +impl const A for T { + fn a() -> u32 { + T::foo() + } +} + +const _: () = assert!(<()>::a() == 42); +const _: () = assert!(::a() == 3); +const _: () = assert!(::a() == 2); + +fn main() {} diff --git a/tests/ui/traits/const-traits/specializing-constness-2.rs b/tests/ui/traits/const-traits/specialization/specializing-constness-2.rs similarity index 81% rename from tests/ui/traits/const-traits/specializing-constness-2.rs rename to tests/ui/traits/const-traits/specialization/specializing-constness-2.rs index 455dd111603d..78cfbe361d91 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.rs +++ b/tests/ui/traits/const-traits/specialization/specializing-constness-2.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl, min_specialization, rustc_attrs)] -//@ known-bug: #110395 +#![allow(internal_features)] + #[rustc_specialization_trait] pub const trait Sup {} @@ -23,7 +24,7 @@ impl const A for T { const fn generic() { ::a(); - //FIXME ~^ ERROR: the trait bound `T: [const] Sup` is not satisfied + //~^ ERROR: the trait bound `T: [const] A` is not satisfied } fn main() {} diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specialization/specializing-constness-2.stderr similarity index 88% rename from tests/ui/traits/const-traits/specializing-constness-2.stderr rename to tests/ui/traits/const-traits/specialization/specializing-constness-2.stderr index bd6ffa544d0e..bb1c9ac78531 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.stderr +++ b/tests/ui/traits/const-traits/specialization/specializing-constness-2.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `T: [const] A` is not satisfied - --> $DIR/specializing-constness-2.rs:25:6 + --> $DIR/specializing-constness-2.rs:26:6 | LL | ::a(); | ^ diff --git a/tests/ui/traits/const-traits/specializing-constness.rs b/tests/ui/traits/const-traits/specialization/specializing-constness.rs similarity index 100% rename from tests/ui/traits/const-traits/specializing-constness.rs rename to tests/ui/traits/const-traits/specialization/specializing-constness.rs diff --git a/tests/ui/traits/const-traits/specializing-constness.stderr b/tests/ui/traits/const-traits/specialization/specializing-constness.stderr similarity index 100% rename from tests/ui/traits/const-traits/specializing-constness.stderr rename to tests/ui/traits/const-traits/specialization/specializing-constness.stderr diff --git a/tests/ui/traits/const-traits/staged-api.rs b/tests/ui/traits/const-traits/staged-api.rs index 6d0a84797ea2..cd74bb45f651 100644 --- a/tests/ui/traits/const-traits/staged-api.rs +++ b/tests/ui/traits/const-traits/staged-api.rs @@ -5,7 +5,7 @@ #![feature(local_feature)] #![feature(const_trait_impl)] #![feature(staged_api)] -#![feature(rustc_allow_const_fn_unstable)] +#![feature(rustc_attrs)] #![stable(feature = "rust1", since = "1.0.0")] //@ aux-build: staged-api.rs diff --git a/tests/ui/traits/cycle-cache-err-60010.stderr b/tests/ui/traits/cycle-cache-err-60010.stderr index 4f5e31818321..9665d5badf59 100644 --- a/tests/ui/traits/cycle-cache-err-60010.stderr +++ b/tests/ui/traits/cycle-cache-err-60010.stderr @@ -6,7 +6,7 @@ LL | _parse: >::Data, | note: required because it appears within the type `PhantomData` --> $SRC_DIR/core/src/marker.rs:LL:COL -note: required because it appears within the type `Unique` +note: required because it appears within the type `std::ptr::Unique` --> $SRC_DIR/core/src/ptr/unique.rs:LL:COL note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -45,7 +45,7 @@ LL | type Storage = SalsaStorage; | note: required because it appears within the type `PhantomData` --> $SRC_DIR/core/src/marker.rs:LL:COL -note: required because it appears within the type `Unique` +note: required because it appears within the type `std::ptr::Unique` --> $SRC_DIR/core/src/ptr/unique.rs:LL:COL note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/tests/ui/traits/deep-norm-pending.rs b/tests/ui/traits/deep-norm-pending.rs index d6c498dcf2bd..9b1ec522bef3 100644 --- a/tests/ui/traits/deep-norm-pending.rs +++ b/tests/ui/traits/deep-norm-pending.rs @@ -7,11 +7,11 @@ trait Bar { //~^ ERROR the trait bound `T: Foo` is not satisfied } impl Bar for T -//~^ ERROR the trait bound `T: Foo` is not satisfied +//~^ ERROR the trait bound `T: Bar` is not satisfied +//~| ERROR the trait bound `T: Foo` is not satisfied where ::Assoc: Sized, //~^ ERROR the trait bound `T: Foo` is not satisfied - //~| ERROR the trait bound `T: Foo` is not satisfied { fn method() {} //~^ ERROR the trait bound `T: Foo` is not satisfied diff --git a/tests/ui/traits/deep-norm-pending.stderr b/tests/ui/traits/deep-norm-pending.stderr index c1d6120c390d..f2b59748ced9 100644 --- a/tests/ui/traits/deep-norm-pending.stderr +++ b/tests/ui/traits/deep-norm-pending.stderr @@ -3,6 +3,7 @@ error[E0277]: the trait bound `T: Foo` is not satisfied | LL | / impl Bar for T LL | | +LL | | LL | | where LL | | ::Assoc: Sized, | |_____________________________^ the trait `Foo` is not implemented for `T` @@ -85,12 +86,20 @@ help: consider further restricting type parameter `T` with trait `Foo` LL | ::Assoc: Sized, T: Foo | ++++++ -error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:12:24 +error[E0277]: the trait bound `T: Bar` is not satisfied + --> $DIR/deep-norm-pending.rs:9:17 | +LL | impl Bar for T + | ^ the trait `Foo` is not implemented for `T` + | +note: required for `T` to implement `Bar` + --> $DIR/deep-norm-pending.rs:9:9 + | +LL | impl Bar for T + | ^^^ ^ +... LL | ::Assoc: Sized, - | ^^^^^ the trait `Foo` is not implemented for `T` - | + | ----- unsatisfied trait bound introduced here help: consider further restricting type parameter `T` with trait `Foo` | LL | ::Assoc: Sized, T: Foo @@ -109,12 +118,11 @@ LL | ::Assoc: Sized, T: Foo | ++++++ error[E0277]: the trait bound `T: Foo` is not satisfied - --> $DIR/deep-norm-pending.rs:12:24 + --> $DIR/deep-norm-pending.rs:13:24 | LL | ::Assoc: Sized, | ^^^^^ the trait `Foo` is not implemented for `T` | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: consider further restricting type parameter `T` with trait `Foo` | LL | ::Assoc: Sized, T: Foo diff --git a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs index 9b2e489c5425..82d0fa36d7ec 100644 --- a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs +++ b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs @@ -12,7 +12,7 @@ trait Tr1 { } #[rustc_must_implement_one_of(a)] -//~^ ERROR the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args +//~^ ERROR malformed trait Tr2 { fn a() {} } @@ -36,11 +36,11 @@ trait Tr5 { } #[rustc_must_implement_one_of(abc, xyz)] -//~^ ERROR attribute should be applied to a trait +//~^ ERROR `#[rustc_must_implement_one_of]` attribute cannot be used on functions fn function() {} #[rustc_must_implement_one_of(abc, xyz)] -//~^ ERROR attribute should be applied to a trait +//~^ ERROR `#[rustc_must_implement_one_of]` attribute cannot be used on structs struct Struct {} fn main() {} diff --git a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr index cf197d035b38..0d854b4594fa 100644 --- a/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr +++ b/tests/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr @@ -1,26 +1,36 @@ -error: malformed `rustc_must_implement_one_of` attribute input +error[E0539]: malformed `rustc_must_implement_one_of` attribute input + --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 + | +LL | #[rustc_must_implement_one_of(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^ + | | | + | | expected 2 or more items + | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` + +error[E0539]: malformed `rustc_must_implement_one_of` attribute input --> $DIR/rustc_must_implement_one_of_misuse.rs:20:1 | LL | #[rustc_must_implement_one_of] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]` -error: attribute should be applied to a trait +error: `#[rustc_must_implement_one_of]` attribute cannot be used on functions --> $DIR/rustc_must_implement_one_of_misuse.rs:38:1 | LL | #[rustc_must_implement_one_of(abc, xyz)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | fn function() {} - | ---------------- not a trait + | + = help: `#[rustc_must_implement_one_of]` can only be applied to traits -error: attribute should be applied to a trait +error: `#[rustc_must_implement_one_of]` attribute cannot be used on structs --> $DIR/rustc_must_implement_one_of_misuse.rs:42:1 | LL | #[rustc_must_implement_one_of(abc, xyz)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct Struct {} - | ---------------- not a trait + | + = help: `#[rustc_must_implement_one_of]` can only be applied to traits error: function not found in this trait --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31 @@ -40,12 +50,6 @@ error: function not found in this trait LL | #[rustc_must_implement_one_of(a, b)] | ^ -error: the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args - --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1 - | -LL | #[rustc_must_implement_one_of(a)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: not a function --> $DIR/rustc_must_implement_one_of_misuse.rs:26:5 | @@ -98,3 +102,4 @@ LL | #[rustc_must_implement_one_of(a, b)] error: aborting due to 11 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/traits/deny-builtin-object-impl.current.stderr b/tests/ui/traits/deny-builtin-object-impl.current.stderr index d6f4762d0996..928d16aa4329 100644 --- a/tests/ui/traits/deny-builtin-object-impl.current.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.current.stderr @@ -4,41 +4,67 @@ error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted LL | impl NotImplYesObject for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `NotImplYesObject` not allowed -error[E0277]: the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:37:32 +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:23:28 + | +LL | impl YesImplNotObject2 for dyn YesImplNotObject2 {} + | ^^^^^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 + | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... + +error[E0038]: the trait `NotImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:37:36 | LL | test_not_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | ^^^^^^^^^^^^^^^^ `NotImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:12:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:11:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility LL | trait NotImplNotObject {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `test_not_impl_not_object` - --> $DIR/deny-builtin-object-impl.rs:28:32 - | -LL | fn test_not_impl_not_object() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `test_not_impl_not_object` + | ---------------- this trait is not dyn compatible... -error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:40:32 +error[E0038]: the trait `YesImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:40:36 | LL | test_yes_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` + | ^^^^^^^^^^^^^^^^ `YesImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:15:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:14:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility LL | trait YesImplNotObject {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `test_yes_impl_not_object` - --> $DIR/deny-builtin-object-impl.rs:30:32 + | ---------------- this trait is not dyn compatible... + +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:43:37 | -LL | fn test_yes_impl_not_object() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` +LL | test_yes_impl_not_object2::(); + | ^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 + | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0322. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0038, E0322. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/deny-builtin-object-impl.next.stderr b/tests/ui/traits/deny-builtin-object-impl.next.stderr index d6f4762d0996..928d16aa4329 100644 --- a/tests/ui/traits/deny-builtin-object-impl.next.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.next.stderr @@ -4,41 +4,67 @@ error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted LL | impl NotImplYesObject for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `NotImplYesObject` not allowed -error[E0277]: the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:37:32 +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:23:28 + | +LL | impl YesImplNotObject2 for dyn YesImplNotObject2 {} + | ^^^^^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 + | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... + +error[E0038]: the trait `NotImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:37:36 | LL | test_not_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | ^^^^^^^^^^^^^^^^ `NotImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:12:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:11:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility LL | trait NotImplNotObject {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `test_not_impl_not_object` - --> $DIR/deny-builtin-object-impl.rs:28:32 - | -LL | fn test_not_impl_not_object() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `test_not_impl_not_object` + | ---------------- this trait is not dyn compatible... -error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:40:32 +error[E0038]: the trait `YesImplNotObject` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:40:36 | LL | test_yes_impl_not_object::(); - | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` + | ^^^^^^^^^^^^^^^^ `YesImplNotObject` is not dyn compatible | -help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:15:1 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:14:1 | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility LL | trait YesImplNotObject {} - | ^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `test_yes_impl_not_object` - --> $DIR/deny-builtin-object-impl.rs:30:32 + | ---------------- this trait is not dyn compatible... + +error[E0038]: the trait `YesImplNotObject2` is not dyn compatible + --> $DIR/deny-builtin-object-impl.rs:43:37 | -LL | fn test_yes_impl_not_object() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` +LL | test_yes_impl_not_object2::(); + | ^^^^^^^^^^^^^^^^^ `YesImplNotObject2` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/deny-builtin-object-impl.rs:17:1 + | +LL | #[rustc_dyn_incompatible_trait] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because it opted out of dyn-compatibility +LL | trait YesImplNotObject2 {} + | ----------------- this trait is not dyn compatible... -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0277, E0322. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0038, E0322. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/deny-builtin-object-impl.rs b/tests/ui/traits/deny-builtin-object-impl.rs index 9d02ab7bd469..5924b3fa2857 100644 --- a/tests/ui/traits/deny-builtin-object-impl.rs +++ b/tests/ui/traits/deny-builtin-object-impl.rs @@ -8,20 +8,20 @@ trait NotImplYesObject {} #[rustc_deny_explicit_impl] -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] trait NotImplNotObject {} -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] trait YesImplNotObject {} -#[rustc_do_not_implement_via_object] +#[rustc_dyn_incompatible_trait] trait YesImplNotObject2 {} impl NotImplYesObject for () {} //~^ ERROR explicit impls for the `NotImplYesObject` trait are not permitted -// If there is no automatic impl then we can add a manual impl: impl YesImplNotObject2 for dyn YesImplNotObject2 {} +//~^ ERROR the trait `YesImplNotObject2` is not dyn compatible fn test_not_impl_yes_object() {} @@ -35,10 +35,11 @@ fn main() { test_not_impl_yes_object::(); test_not_impl_not_object::(); - //~^ ERROR the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + //~^ ERROR the trait `NotImplNotObject` is not dyn compatible test_yes_impl_not_object::(); - //~^ ERROR the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + //~^ ERROR the trait `YesImplNotObject` is not dyn compatible test_yes_impl_not_object2::(); + //~^ ERROR the trait `YesImplNotObject2` is not dyn compatible } diff --git a/tests/ui/traits/derive-implicit-bound-on-clone.rs b/tests/ui/traits/derive-implicit-bound-on-clone.rs new file mode 100644 index 000000000000..a4c9e88ef576 --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound-on-clone.rs @@ -0,0 +1,24 @@ +// Issue #146515 +use std::rc::Rc; + +#[derive(Clone)] +struct ContainsRc { //~ HELP `Clone` is not implemented + value: Rc<(T, K)>, +} + +fn clone_me(x: &ContainsRc) -> ContainsRc { + x.clone() //~ ERROR E0308 + //~^ HELP consider manually implementing `Clone` +} + +#[derive(Clone)] +struct ContainsRcSingle { //~ HELP `Clone` is not implemented + value: Rc, +} + +fn clone_me_single(x: &ContainsRcSingle) -> ContainsRcSingle { + x.clone() //~ ERROR E0308 + //~^ HELP consider manually implementing `Clone` +} + +fn main() {} diff --git a/tests/ui/traits/derive-implicit-bound-on-clone.stderr b/tests/ui/traits/derive-implicit-bound-on-clone.stderr new file mode 100644 index 000000000000..2fb039f96528 --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound-on-clone.stderr @@ -0,0 +1,53 @@ +error[E0308]: mismatched types + --> $DIR/derive-implicit-bound-on-clone.rs:10:5 + | +LL | fn clone_me(x: &ContainsRc) -> ContainsRc { + | ---------------- expected `ContainsRc` because of return type +LL | x.clone() + | ^^^^^^^^^ expected `ContainsRc`, found `&ContainsRc` + | + = note: expected struct `ContainsRc<_, _>` + found reference `&ContainsRc<_, _>` +note: `ContainsRc` does not implement `Clone`, so `&ContainsRc` was cloned instead + --> $DIR/derive-implicit-bound-on-clone.rs:10:5 + | +LL | x.clone() + | ^ +help: `Clone` is not implemented because the some trait bounds could not be satisfied + --> $DIR/derive-implicit-bound-on-clone.rs:5:19 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct ContainsRc { + | ^ ^ derive introduces an implicit unsatisfied trait bound `K: Clone` + | | + | derive introduces an implicit unsatisfied trait bound `T: Clone` + = help: consider manually implementing `Clone` to avoid the implicit type parameter bounds + +error[E0308]: mismatched types + --> $DIR/derive-implicit-bound-on-clone.rs:20:5 + | +LL | fn clone_me_single(x: &ContainsRcSingle) -> ContainsRcSingle { + | ------------------- expected `ContainsRcSingle` because of return type +LL | x.clone() + | ^^^^^^^^^ expected `ContainsRcSingle`, found `&ContainsRcSingle` + | + = note: expected struct `ContainsRcSingle<_>` + found reference `&ContainsRcSingle<_>` +note: `ContainsRcSingle` does not implement `Clone`, so `&ContainsRcSingle` was cloned instead + --> $DIR/derive-implicit-bound-on-clone.rs:20:5 + | +LL | x.clone() + | ^ +help: `Clone` is not implemented because a trait bound is not satisfied + --> $DIR/derive-implicit-bound-on-clone.rs:15:25 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct ContainsRcSingle { + | ^ derive introduces an implicit `T: Clone` bound + = help: consider manually implementing `Clone` to avoid the implicit type parameter bounds + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/derive-implicit-bound.rs b/tests/ui/traits/derive-implicit-bound.rs new file mode 100644 index 000000000000..22fb68f37c5c --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound.rs @@ -0,0 +1,34 @@ +// Second case reported in issue #108894. + +use std::marker::PhantomData; + +#[derive(PartialEq, Eq)] +pub struct Id(PhantomData); + +// manual implementation which would break the usage of const patterns +// impl PartialEq for Id { fn eq(&self, _: &Id) -> bool { true } } +// impl Eq for Id {} + +// This derive is undesired but cannot be removed without +// breaking the usages below +// #[derive(PartialEq, Eq)] +struct SomeNode(); + +fn accept_eq(_: &impl PartialEq) { } + +fn main() { + let node = Id::(PhantomData); + + // this will only work if + // - `Partial/Eq` is implemented manually, or + // - `SomeNode` also needlessly(?) implements `Partial/Eq` + accept_eq(&node); //~ ERROR can't compare `SomeNode` with `SomeNode` + + const CONST_ID: Id:: = Id::(PhantomData); + // this will work only when `Partial/Eq` is being derived + // otherwise: error: to use a constant of type `Id` in a pattern, + // `Id` must be annotated with `#[derive(PartialEq, Eq)]` + match node { + CONST_ID => {} + } +} diff --git a/tests/ui/traits/derive-implicit-bound.stderr b/tests/ui/traits/derive-implicit-bound.stderr new file mode 100644 index 000000000000..fe2bc77b9529 --- /dev/null +++ b/tests/ui/traits/derive-implicit-bound.stderr @@ -0,0 +1,31 @@ +error[E0277]: can't compare `SomeNode` with `SomeNode` + --> $DIR/derive-implicit-bound.rs:25:15 + | +LL | accept_eq(&node); + | --------- ^^^^^ no implementation for `SomeNode == SomeNode` + | | + | required by a bound introduced by this call + | + = help: the trait `PartialEq` is not implemented for `SomeNode` +note: required for `Id` to implement `PartialEq` + --> $DIR/derive-implicit-bound.rs:6:12 + | +LL | #[derive(PartialEq, Eq)] + | --------- in this derive macro expansion +LL | pub struct Id(PhantomData); + | ^^ - type parameter would need to implement `PartialEq` + = help: consider manually implementing `PartialEq` to avoid undesired bounds +note: required by a bound in `accept_eq` + --> $DIR/derive-implicit-bound.rs:17:23 + | +LL | fn accept_eq(_: &impl PartialEq) { } + | ^^^^^^^^^ required by this bound in `accept_eq` +help: consider annotating `SomeNode` with `#[derive(PartialEq)]` + | +LL + #[derive(PartialEq)] +LL | struct SomeNode(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr b/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr index b5a9b82a93a3..0dd2ffffdfea 100644 --- a/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr +++ b/tests/ui/traits/dyn-iterator-deref-in-for-loop.current.stderr @@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator` is not an iterator --> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17 | LL | for item in *things { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator` | - = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` help: consider mutably borrowing here | diff --git a/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr b/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr index b5a9b82a93a3..0dd2ffffdfea 100644 --- a/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr +++ b/tests/ui/traits/dyn-iterator-deref-in-for-loop.next.stderr @@ -2,9 +2,9 @@ error[E0277]: `dyn Iterator` is not an iterator --> $DIR/dyn-iterator-deref-in-for-loop.rs:9:17 | LL | for item in *things { - | ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator` + | ^^^^^^^ the trait `Sized` is not implemented for `dyn Iterator` | - = note: the trait bound `dyn Iterator: IntoIterator` is not satisfied + = note: the trait bound `Sized` is not satisfied = note: required for `dyn Iterator` to implement `IntoIterator` help: consider mutably borrowing here | diff --git a/tests/ui/traits/explicit-reference-cast.rs b/tests/ui/traits/explicit-reference-cast.rs new file mode 100644 index 000000000000..efb4f10bea67 --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast.rs @@ -0,0 +1,50 @@ +// compile-fail + +use std::convert::TryFrom; +use std::path::{Path, PathBuf}; + +pub struct ToolA(PathBuf); +//~^ HELP the trait `From<&PathBuf>` is not implemented for `ToolA` + +impl From<&Path> for ToolA { + //~^ HELP the following other types implement trait `From` + fn from(p: &Path) -> ToolA { + ToolA(p.to_path_buf()) + } +} + +// Add a different From impl to ensure we suggest the correct cast +impl From<&str> for ToolA { + fn from(s: &str) -> ToolA { + ToolA(PathBuf::from(s)) + } +} + +pub struct ToolB(PathBuf); +//~^ HELP the trait `From<&PathBuf>` is not implemented for `ToolB` +//~| HELP the trait `From<&PathBuf>` is not implemented for `ToolB` + +impl TryFrom<&Path> for ToolB { + //~^ HELP the trait `TryFrom<&PathBuf>` is not implemented for `ToolB` + //~| HELP the trait `TryFrom<&PathBuf>` is not implemented for `ToolB` + type Error = (); + + fn try_from(p: &Path) -> Result { + Ok(ToolB(p.to_path_buf())) + } +} + +fn main() { + let path = PathBuf::new(); + + let _ = ToolA::from(&path); + //~^ ERROR the trait bound `ToolA: From<&PathBuf>` is not satisfied + //~| HELP consider casting the `&PathBuf` value to `&Path` + let _ = ToolB::try_from(&path); + //~^ ERROR the trait bound `ToolB: TryFrom<&PathBuf>` is not satisfied + //~| ERROR the trait bound `ToolB: From<&PathBuf>` is not satisfied + //~| HELP consider casting the `&PathBuf` value to `&Path` + //~| HELP consider casting the `&PathBuf` value to `&Path` + //~| HELP for that trait implementation, expected `Path`, found `PathBuf` + //~| HELP for that trait implementation, expected `Path`, found `PathBuf` +} diff --git a/tests/ui/traits/explicit-reference-cast.stderr b/tests/ui/traits/explicit-reference-cast.stderr new file mode 100644 index 000000000000..924de3d5bbe3 --- /dev/null +++ b/tests/ui/traits/explicit-reference-cast.stderr @@ -0,0 +1,68 @@ +error[E0277]: the trait bound `ToolA: From<&PathBuf>` is not satisfied + --> $DIR/explicit-reference-cast.rs:40:13 + | +LL | let _ = ToolA::from(&path); + | ^^^^^ unsatisfied trait bound + | + = help: consider casting the `&PathBuf` value to `&Path` +help: the trait `From<&PathBuf>` is not implemented for `ToolA` + --> $DIR/explicit-reference-cast.rs:6:1 + | +LL | pub struct ToolA(PathBuf); + | ^^^^^^^^^^^^^^^^ +help: the following other types implement trait `From` + --> $DIR/explicit-reference-cast.rs:9:1 + | +LL | impl From<&Path> for ToolA { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `ToolA` implements `From<&Path>` +... +LL | impl From<&str> for ToolA { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `ToolA` implements `From<&str>` + +error[E0277]: the trait bound `ToolB: TryFrom<&PathBuf>` is not satisfied + --> $DIR/explicit-reference-cast.rs:43:13 + | +LL | let _ = ToolB::try_from(&path); + | ^^^^^ unsatisfied trait bound + | + = help: consider casting the `&PathBuf` value to `&Path` +help: the trait `From<&PathBuf>` is not implemented for `ToolB` + --> $DIR/explicit-reference-cast.rs:23:1 + | +LL | pub struct ToolB(PathBuf); + | ^^^^^^^^^^^^^^^^ +help: the trait `TryFrom<&PathBuf>` is not implemented for `ToolB` + but trait `TryFrom<&Path>` is implemented for it + --> $DIR/explicit-reference-cast.rs:27:1 + | +LL | impl TryFrom<&Path> for ToolB { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: for that trait implementation, expected `Path`, found `PathBuf` + = note: required for `&PathBuf` to implement `Into` + = note: required for `ToolB` to implement `TryFrom<&PathBuf>` + +error[E0277]: the trait bound `ToolB: From<&PathBuf>` is not satisfied + --> $DIR/explicit-reference-cast.rs:43:13 + | +LL | let _ = ToolB::try_from(&path); + | ^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | + = help: consider casting the `&PathBuf` value to `&Path` +help: the trait `From<&PathBuf>` is not implemented for `ToolB` + --> $DIR/explicit-reference-cast.rs:23:1 + | +LL | pub struct ToolB(PathBuf); + | ^^^^^^^^^^^^^^^^ +help: the trait `TryFrom<&PathBuf>` is not implemented for `ToolB` + but trait `TryFrom<&Path>` is implemented for it + --> $DIR/explicit-reference-cast.rs:27:1 + | +LL | impl TryFrom<&Path> for ToolB { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: for that trait implementation, expected `Path`, found `PathBuf` + = note: required for `&PathBuf` to implement `Into` + = note: required for `ToolB` to implement `TryFrom<&PathBuf>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/final/dyn-compat.rs b/tests/ui/traits/final/dyn-compat.rs new file mode 100644 index 000000000000..d600058820c2 --- /dev/null +++ b/tests/ui/traits/final/dyn-compat.rs @@ -0,0 +1,40 @@ +//@ run-pass + +#![feature(final_associated_functions)] + +trait FinalNoReceiver { + final fn no_receiver() {} +} + +trait FinalGeneric { + final fn generic(&self, _value: T) {} +} + +trait FinalSelfParam { + final fn self_param(&self, _other: &Self) {} +} + +trait FinalSelfReturn { + final fn self_return(&self) -> &Self { + self + } +} + +struct S; + +impl FinalNoReceiver for S {} +impl FinalGeneric for S {} +impl FinalSelfParam for S {} +impl FinalSelfReturn for S {} + +fn main() { + let s = S; + ::no_receiver(); + let obj_generic: &dyn FinalGeneric = &s; + let obj_param: &dyn FinalSelfParam = &s; + let obj_return: &dyn FinalSelfReturn = &s; + obj_generic.generic(1u8); + obj_param.self_param(obj_param); + let _ = obj_return.self_return(); + let _: &dyn FinalNoReceiver = &s; +} diff --git a/tests/ui/traits/final/final-kw.gated.stderr b/tests/ui/traits/final/final-kw.gated.stderr new file mode 100644 index 000000000000..62a39d7ca202 --- /dev/null +++ b/tests/ui/traits/final/final-kw.gated.stderr @@ -0,0 +1,13 @@ +error[E0658]: `final` on trait functions is experimental + --> $DIR/final-kw.rs:5:5 + | +LL | final fn foo() {} + | ^^^^^ + | + = note: see issue #131179 for more information + = help: add `#![feature(final_associated_functions)]` 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: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/final/final-kw.rs b/tests/ui/traits/final/final-kw.rs new file mode 100644 index 000000000000..ed675dea6608 --- /dev/null +++ b/tests/ui/traits/final/final-kw.rs @@ -0,0 +1,9 @@ +//@ revisions: ungated gated + +#[cfg(ungated)] +trait Trait { + final fn foo() {} + //~^ ERROR `final` on trait functions is experimental +} + +fn main() {} diff --git a/tests/ui/traits/final/final-kw.ungated.stderr b/tests/ui/traits/final/final-kw.ungated.stderr new file mode 100644 index 000000000000..62a39d7ca202 --- /dev/null +++ b/tests/ui/traits/final/final-kw.ungated.stderr @@ -0,0 +1,13 @@ +error[E0658]: `final` on trait functions is experimental + --> $DIR/final-kw.rs:5:5 + | +LL | final fn foo() {} + | ^^^^^ + | + = note: see issue #131179 for more information + = help: add `#![feature(final_associated_functions)]` 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: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/traits/final/final-must-have-body.rs b/tests/ui/traits/final/final-must-have-body.rs new file mode 100644 index 000000000000..57ed26c3e78d --- /dev/null +++ b/tests/ui/traits/final/final-must-have-body.rs @@ -0,0 +1,8 @@ +#![feature(final_associated_functions)] + +trait Foo { + final fn method(); + //~^ ERROR `final` is only allowed on associated functions if they have a body +} + +fn main() {} diff --git a/tests/ui/traits/final/final-must-have-body.stderr b/tests/ui/traits/final/final-must-have-body.stderr new file mode 100644 index 000000000000..e4f1ffb701e8 --- /dev/null +++ b/tests/ui/traits/final/final-must-have-body.stderr @@ -0,0 +1,10 @@ +error: `final` is only allowed on associated functions if they have a body + --> $DIR/final-must-have-body.rs:4:5 + | +LL | final fn method(); + | -----^^^^^^^^^^^^^ + | | + | `final` because of this + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/final/overriding.rs b/tests/ui/traits/final/overriding.rs new file mode 100644 index 000000000000..f91451852ff0 --- /dev/null +++ b/tests/ui/traits/final/overriding.rs @@ -0,0 +1,12 @@ +#![feature(final_associated_functions)] + +trait Foo { + final fn method() {} +} + +impl Foo for () { + fn method() {} + //~^ ERROR cannot override `method` because it already has a `final` definition in the trait +} + +fn main() {} diff --git a/tests/ui/traits/final/overriding.stderr b/tests/ui/traits/final/overriding.stderr new file mode 100644 index 000000000000..b5598565072f --- /dev/null +++ b/tests/ui/traits/final/overriding.stderr @@ -0,0 +1,14 @@ +error: cannot override `method` because it already has a `final` definition in the trait + --> $DIR/overriding.rs:8:5 + | +LL | fn method() {} + | ^^^^^^^^^^^ + | +note: `method` is marked final here + --> $DIR/overriding.rs:4:5 + | +LL | final fn method() {} + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/traits/final/positions.rs b/tests/ui/traits/final/positions.rs new file mode 100644 index 000000000000..9bf659e12431 --- /dev/null +++ b/tests/ui/traits/final/positions.rs @@ -0,0 +1,72 @@ +#![feature(final_associated_functions)] + +// Just for exercising the syntax positions +#![feature(associated_type_defaults, extern_types, inherent_associated_types)] +#![allow(incomplete_features)] + +final struct Foo {} +//~^ ERROR a struct cannot be `final` + +final trait Trait { +//~^ ERROR a trait cannot be `final` + + final fn method() {} + // OK! + + final type Foo = (); + //~^ ERROR `final` is only allowed on associated functions in traits + + final const FOO: usize = 1; + //~^ ERROR `final` is only allowed on associated functions in traits +} + +final impl Foo { + final fn method() {} + //~^ ERROR `final` is only allowed on associated functions in traits + + final type Foo = (); + //~^ ERROR `final` is only allowed on associated functions in traits + + final const FOO: usize = 1; + //~^ ERROR `final` is only allowed on associated functions in traits +} + +final impl Trait for Foo { + final fn method() {} + //~^ ERROR `final` is only allowed on associated functions in traits + //~^^ ERROR cannot override `method` because it already has a `final` definition in the trait + + final type Foo = (); + //~^ ERROR `final` is only allowed on associated functions in traits + //~^^ ERROR cannot override `Foo` because it already has a `final` definition in the trait + + final const FOO: usize = 1; + //~^ ERROR `final` is only allowed on associated functions in traits + //~^^ ERROR cannot override `FOO` because it already has a `final` definition in the trait +} + + +final fn foo() {} +//~^ ERROR `final` is only allowed on associated functions in traits + +final type FooTy = (); +//~^ ERROR `final` is only allowed on associated functions in traits + +final const FOO: usize = 0; +//~^ ERROR `final` is only allowed on associated functions in traits + +final unsafe extern "C" { +//~^ ERROR an extern block cannot be `final` + + final fn foo_extern(); + //~^ ERROR `final` is only allowed on associated functions in traits + + final type FooExtern; + //~^ ERROR `final` is only allowed on associated functions in traits + + final static FOO_EXTERN: usize = 0; + //~^ ERROR a static item cannot be `final` + //~| ERROR incorrect `static` inside `extern` block +} + +fn main() {} diff --git a/tests/ui/traits/final/positions.stderr b/tests/ui/traits/final/positions.stderr new file mode 100644 index 000000000000..bcb300e49d1a --- /dev/null +++ b/tests/ui/traits/final/positions.stderr @@ -0,0 +1,187 @@ +error: a struct cannot be `final` + --> $DIR/positions.rs:7:1 + | +LL | final struct Foo {} + | ^^^^^ `final` because of this + | + = note: only associated functions in traits can be `final` + +error: a trait cannot be `final` + --> $DIR/positions.rs:10:1 + | +LL | final trait Trait { + | ^^^^^ `final` because of this + | + = note: only associated functions in traits can be `final` + +error: a static item cannot be `final` + --> $DIR/positions.rs:67:5 + | +LL | final static FOO_EXTERN: usize = 0; + | ^^^^^ `final` because of this + | + = note: only associated functions in traits can be `final` + +error: an extern block cannot be `final` + --> $DIR/positions.rs:58:1 + | +LL | final unsafe extern "C" { + | ^^^^^ `final` because of this + | + = note: only associated functions in traits can be `final` + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:16:5 + | +LL | final type Foo = (); + | -----^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:19:5 + | +LL | final const FOO: usize = 1; + | -----^^^^^^^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:24:5 + | +LL | final fn method() {} + | -----^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:27:5 + | +LL | final type Foo = (); + | -----^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:30:5 + | +LL | final const FOO: usize = 1; + | -----^^^^^^^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:35:5 + | +LL | final fn method() {} + | -----^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:39:5 + | +LL | final type Foo = (); + | -----^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:43:5 + | +LL | final const FOO: usize = 1; + | -----^^^^^^^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:49:1 + | +LL | final fn foo() {} + | -----^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:52:1 + | +LL | final type FooTy = (); + | -----^^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:55:1 + | +LL | final const FOO: usize = 0; + | -----^^^^^^^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:61:5 + | +LL | final fn foo_extern(); + | -----^^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: `final` is only allowed on associated functions in traits + --> $DIR/positions.rs:64:5 + | +LL | final type FooExtern; + | -----^^^^^^^^^^^^^^^^ + | | + | `final` because of this + +error: incorrect `static` inside `extern` block + --> $DIR/positions.rs:67:18 + | +LL | final unsafe extern "C" { + | ----------------------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body +... +LL | final static FOO_EXTERN: usize = 0; + | ^^^^^^^^^^ - the invalid body + | | + | cannot have a body + | + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: cannot override `method` because it already has a `final` definition in the trait + --> $DIR/positions.rs:35:5 + | +LL | final fn method() {} + | ^^^^^^^^^^^^^^^^^ + | +note: `method` is marked final here + --> $DIR/positions.rs:13:5 + | +LL | final fn method() {} + | ^^^^^^^^^^^^^^^^^ + +error: cannot override `Foo` because it already has a `final` definition in the trait + --> $DIR/positions.rs:39:5 + | +LL | final type Foo = (); + | ^^^^^^^^^^^^^^ + | +note: `Foo` is marked final here + --> $DIR/positions.rs:16:5 + | +LL | final type Foo = (); + | ^^^^^^^^^^^^^^ + +error: cannot override `FOO` because it already has a `final` definition in the trait + --> $DIR/positions.rs:43:5 + | +LL | final const FOO: usize = 1; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: `FOO` is marked final here + --> $DIR/positions.rs:19:5 + | +LL | final const FOO: usize = 1; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 21 previous errors + diff --git a/tests/ui/traits/final/works.rs b/tests/ui/traits/final/works.rs new file mode 100644 index 000000000000..e756521701a4 --- /dev/null +++ b/tests/ui/traits/final/works.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(final_associated_functions)] + +trait Foo { + final fn bar(&self) {} +} + +impl Foo for () {} + +fn main() { + ().bar(); +} diff --git a/tests/ui/traits/fmt-pointer-trait.rs b/tests/ui/traits/fmt-pointer-trait.rs deleted file mode 100644 index edf734597f50..000000000000 --- a/tests/ui/traits/fmt-pointer-trait.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ run-pass -use std::ptr; -use std::rc::Rc; -use std::sync::Arc; - -fn main() { - let p: *const u8 = ptr::null(); - let rc = Rc::new(1usize); - let arc = Arc::new(1usize); - let b = Box::new("hi"); - - let _ = format!("{:p}{:p}{:p}", - rc, arc, b); - - if cfg!(target_pointer_width = "32") { - assert_eq!(format!("{:#p}", p), - "0x00000000"); - } else { - assert_eq!(format!("{:#p}", p), - "0x0000000000000000"); - } - assert_eq!(format!("{:p}", p), - "0x0"); -} diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.rs b/tests/ui/traits/ice-with-dyn-pointee-errors.rs index 46cef2c8bc09..bb89f103e3f9 100644 --- a/tests/ui/traits/ice-with-dyn-pointee-errors.rs +++ b/tests/ui/traits/ice-with-dyn-pointee-errors.rs @@ -6,10 +6,12 @@ use core::ptr::Pointee; fn unknown_sized_object_ptr_in(_: &(impl Pointee + ?Sized)) {} fn raw_pointer_in(x: &dyn Pointee) { + //~^ ERROR the trait `Pointee` is not dyn compatible unknown_sized_object_ptr_in(x) - //~^ ERROR type mismatch resolving ` as Pointee>::Metadata == ()` + //~^ ERROR the trait `Pointee` is not dyn compatible } fn main() { raw_pointer_in(&42) + //~^ ERROR the trait `Pointee` is not dyn compatible } diff --git a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr index 5299236026d7..9ff0445cda09 100644 --- a/tests/ui/traits/ice-with-dyn-pointee-errors.stderr +++ b/tests/ui/traits/ice-with-dyn-pointee-errors.stderr @@ -1,19 +1,39 @@ -error[E0271]: type mismatch resolving ` as Pointee>::Metadata == ()` - --> $DIR/ice-with-dyn-pointee-errors.rs:9:33 +error[E0038]: the trait `Pointee` is not dyn compatible + --> $DIR/ice-with-dyn-pointee-errors.rs:8:23 + | +LL | fn raw_pointer_in(x: &dyn Pointee) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `Pointee` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + | + = note: the trait is not dyn compatible because it opted out of dyn-compatibility + +error[E0038]: the trait `Pointee` is not dyn compatible + --> $DIR/ice-with-dyn-pointee-errors.rs:10:5 | LL | unknown_sized_object_ptr_in(x) - | --------------------------- ^ expected `()`, found `DynMetadata>` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Pointee` is not dyn compatible | - = note: expected unit type `()` - found struct `DynMetadata>` -note: required by a bound in `unknown_sized_object_ptr_in` - --> $DIR/ice-with-dyn-pointee-errors.rs:6:50 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL | -LL | fn unknown_sized_object_ptr_in(_: &(impl Pointee + ?Sized)) {} - | ^^^^^^^^^^^^^ required by this bound in `unknown_sized_object_ptr_in` + = note: the trait is not dyn compatible because it opted out of dyn-compatibility -error: aborting due to 1 previous error +error[E0038]: the trait `Pointee` is not dyn compatible + --> $DIR/ice-with-dyn-pointee-errors.rs:15:20 + | +LL | raw_pointer_in(&42) + | ^^^ `Pointee` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + | + = note: the trait is not dyn compatible because it opted out of dyn-compatibility -For more information about this error, try `rustc --explain E0271`. +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/ice-with-dyn-pointee.rs b/tests/ui/traits/ice-with-dyn-pointee.rs deleted file mode 100644 index 45361cc44600..000000000000 --- a/tests/ui/traits/ice-with-dyn-pointee.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#![feature(ptr_metadata)] -// Address issue #112737 -- ICE with dyn Pointee -extern crate core; -use core::ptr::Pointee; - -fn raw_pointer_in(_: &dyn Pointee) {} - -fn main() { - raw_pointer_in(&42) -} diff --git a/tests/ui/traits/ignore-err-impls.stderr b/tests/ui/traits/ignore-err-impls.stderr index 68077c435135..46a2a7d55a2e 100644 --- a/tests/ui/traits/ignore-err-impls.stderr +++ b/tests/ui/traits/ignore-err-impls.stderr @@ -4,10 +4,10 @@ error[E0425]: cannot find type `Type` in this scope LL | impl Generic for S {} | ^^^^ not found in this scope | -help: you might be missing a type parameter +help: consider importing this struct + | +LL + use std::mem::type_info::Type; | -LL | impl Generic for S {} - | ++++++ error: aborting due to 1 previous error diff --git a/tests/ui/traits/impl-for-module.stderr b/tests/ui/traits/impl-for-module.stderr index b715c699e89f..1011a913a4ab 100644 --- a/tests/ui/traits/impl-for-module.stderr +++ b/tests/ui/traits/impl-for-module.stderr @@ -5,7 +5,13 @@ LL | trait A { | ------- similarly named trait `A` defined here ... LL | impl A for a { - | ^ help: a trait with a similar name exists: `A` + | ^ + | +help: a trait with a similar name exists + | +LL - impl A for a { +LL + impl A for A { + | error: aborting due to 1 previous error diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs index d45668312218..6b04004621d8 100644 --- a/tests/ui/traits/issue-106072.rs +++ b/tests/ui/traits/issue-106072.rs @@ -1,6 +1,4 @@ -#[derive(Clone)] -//~^ ERROR expected a type, found a trait -//~| ERROR expected a type, found a trait -struct Foo; -trait Foo {} //~ ERROR the name `Foo` is defined multiple times +#[derive(Clone)] //~ ERROR: expected a type, found a trait +struct Foo; //~ ERROR: expected a type, found a trait +trait Foo {} //~ ERROR: the name `Foo` is defined multiple times fn main() {} diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr index 815787c3bfec..57661fda7307 100644 --- a/tests/ui/traits/issue-106072.stderr +++ b/tests/ui/traits/issue-106072.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Foo` is defined multiple times - --> $DIR/issue-106072.rs:5:1 + --> $DIR/issue-106072.rs:3:1 | LL | struct Foo; | ----------- previous definition of the type `Foo` here @@ -9,18 +9,18 @@ LL | trait Foo {} = note: `Foo` must be defined only once in the type namespace of this module error[E0782]: expected a type, found a trait - --> $DIR/issue-106072.rs:1:10 + --> $DIR/issue-106072.rs:2:8 | LL | #[derive(Clone)] - | ^^^^^ + | ----- in this derive macro expansion +LL | struct Foo; + | ^^^ error[E0782]: expected a type, found a trait --> $DIR/issue-106072.rs:1:10 | LL | #[derive(Clone)] | ^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: aborting due to 3 previous errors diff --git a/tests/ui/traits/issue-18400.stderr b/tests/ui/traits/issue-18400.stderr index 146ba16397a2..af5519a15c23 100644 --- a/tests/ui/traits/issue-18400.stderr +++ b/tests/ui/traits/issue-18400.stderr @@ -11,7 +11,7 @@ note: required for `{integer}` to implement `Set<&[_]>` LL | impl<'a, T, S> Set<&'a [T]> for S where | - ^^^^^^^^^^^^ ^ | | - | unsatisfied trait bound introduced here + | unsatisfied trait bound implicitly introduced here = note: 128 redundant requirements hidden = note: required for `{integer}` to implement `Set<&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[&[_]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]>` diff --git a/tests/ui/traits/issue-50480.rs b/tests/ui/traits/issue-50480.rs index ccd35a850f2d..2f62906e9df3 100644 --- a/tests/ui/traits/issue-50480.rs +++ b/tests/ui/traits/issue-50480.rs @@ -1,18 +1,17 @@ #[derive(Clone, Copy)] -//~^ ERROR the trait `Copy` cannot be implemented for this type struct Foo(N, NotDefined, ::Item, Vec, String); -//~^ ERROR cannot find type `NotDefined` in this scope +//~^ ERROR the trait `Copy` cannot be implemented for this type +//~| ERROR cannot find type `NotDefined` in this scope //~| ERROR cannot find type `NotDefined` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR `i32` is not an iterator //~| ERROR `i32` is not an iterator -#[derive(Clone, Copy)] -//~^ ERROR the trait `Copy` cannot be implemented for this type -//~| ERROR `i32` is not an iterator +#[derive(Clone, Copy)] //~ ERROR `i32` is not an iterator struct Bar(T, N, NotDefined, ::Item, Vec, String); -//~^ ERROR cannot find type `NotDefined` in this scope +//~^ ERROR the trait `Copy` cannot be implemented for this type +//~| ERROR cannot find type `NotDefined` in this scope //~| ERROR cannot find type `N` in this scope //~| ERROR `i32` is not an iterator //~| ERROR `i32` is not an iterator diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr index 32c8b2cf3ac1..1fb5e8b00783 100644 --- a/tests/ui/traits/issue-50480.stderr +++ b/tests/ui/traits/issue-50480.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `N` in this scope - --> $DIR/issue-50480.rs:3:12 + --> $DIR/issue-50480.rs:2:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^ not found in this scope @@ -10,13 +10,13 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ error[E0425]: cannot find type `NotDefined` in this scope - --> $DIR/issue-50480.rs:3:15 + --> $DIR/issue-50480.rs:2:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope error[E0425]: cannot find type `N` in this scope - --> $DIR/issue-50480.rs:3:12 + --> $DIR/issue-50480.rs:2:12 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^ not found in this scope @@ -27,7 +27,7 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); | +++ error[E0425]: cannot find type `NotDefined` in this scope - --> $DIR/issue-50480.rs:3:15 + --> $DIR/issue-50480.rs:2:15 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope @@ -38,7 +38,7 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, St | ++++++++++++ error[E0425]: cannot find type `N` in this scope - --> $DIR/issue-50480.rs:14:18 + --> $DIR/issue-50480.rs:12:18 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | - ^ @@ -56,13 +56,13 @@ LL | struct Bar(T, N, NotDefined, ::Item, Vec, Strin | +++ error[E0425]: cannot find type `NotDefined` in this scope - --> $DIR/issue-50480.rs:14:21 + --> $DIR/issue-50480.rs:12:21 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^ not found in this scope error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:3:27 + --> $DIR/issue-50480.rs:2:27 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator @@ -70,29 +70,27 @@ LL | struct Foo(N, NotDefined, ::Item, Vec, String); = help: the trait `Iterator` is not implemented for `i32` error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-50480.rs:1:17 + --> $DIR/issue-50480.rs:2:8 | LL | #[derive(Clone, Copy)] - | ^^^^ -LL | + | ---- in this derive macro expansion LL | struct Foo(N, NotDefined, ::Item, Vec, String); - | -------- ------ this field does not implement `Copy` + | ^^^ -------- ------ this field does not implement `Copy` | | | this field does not implement `Copy` error[E0204]: the trait `Copy` cannot be implemented for this type - --> $DIR/issue-50480.rs:11:17 + --> $DIR/issue-50480.rs:12:8 | LL | #[derive(Clone, Copy)] - | ^^^^ -... + | ---- in this derive macro expansion LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); - | -------- ------ this field does not implement `Copy` + | ^^^ -------- ------ this field does not implement `Copy` | | | this field does not implement `Copy` error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:14:33 + --> $DIR/issue-50480.rs:12:33 | LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator @@ -100,7 +98,7 @@ LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); = help: the trait `Iterator` is not implemented for `i32` error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:3:28 + --> $DIR/issue-50480.rs:2:28 | LL | struct Foo(N, NotDefined, ::Item, Vec, String); | ^^^ `i32` is not an iterator @@ -116,11 +114,10 @@ LL | #[derive(Clone, Copy)] = help: the trait `Iterator` is not implemented for `i32` error[E0277]: `i32` is not an iterator - --> $DIR/issue-50480.rs:14:33 + --> $DIR/issue-50480.rs:12:33 | LL | #[derive(Clone, Copy)] | ----- in this derive macro expansion -... LL | struct Bar(T, N, NotDefined, ::Item, Vec, String); | ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator | diff --git a/tests/ui/traits/issue-71036.rs b/tests/ui/traits/issue-71036.rs index 69eed0c0462f..9593503240b2 100644 --- a/tests/ui/traits/issue-71036.rs +++ b/tests/ui/traits/issue-71036.rs @@ -10,7 +10,7 @@ struct Foo<'a, T: ?Sized> { impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn> for Foo<'a, T> {} //~^ ERROR the trait bound `&'a T: Unsize<&'a U>` is not satisfied -//~| NOTE the trait `Unsize<&'a U>` is not implemented for `&'a T` +//~| NOTE the nightly-only, unstable trait `Unsize<&'a U>` is not implemented for `&'a T` //~| NOTE all implementations of `Unsize` are provided automatically by the compiler //~| NOTE required for diff --git a/tests/ui/traits/issue-71036.stderr b/tests/ui/traits/issue-71036.stderr index 2452731f19f1..d2d88584f104 100644 --- a/tests/ui/traits/issue-71036.stderr +++ b/tests/ui/traits/issue-71036.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&'a T: Unsize<&'a U>` is not satisfied --> $DIR/issue-71036.rs:11:1 | LL | impl<'a, T: ?Sized + Unsize, U: ?Sized> DispatchFromDyn> for Foo<'a, T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unsize<&'a U>` is not implemented for `&'a T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Unsize<&'a U>` is not implemented for `&'a T` | = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information = note: required for `&'a &'a T` to implement `DispatchFromDyn<&'a &'a U>` diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index edc7f56ea467..b1baabc4394b 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -10,7 +10,7 @@ LL | opts.get(opt.as_ref()); - impl Borrow for String; - impl Borrow for T where T: ?Sized; -note: required by a bound in `HashMap::::get` +note: required by a bound in `HashMap::::get` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL help: consider specifying the generic argument | @@ -44,10 +44,10 @@ LL | let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect( | type must be known at this point | = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate: - - impl From for u32; - impl From for u32; - impl From for u32; - impl From for u32; + - impl From for u32; - impl From for u32; - impl From for u32; help: try using a fully qualified path to specify the expected types diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index eb72b307ed0f..acb67af53f18 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -141,15 +141,15 @@ note: for a trait to be dyn compatible it needs to allow building a vtable --> $DIR/item-privacy.rs:26:15 | LL | const A: u8 = 0; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `A` ... LL | const B: u8 = 0; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `B` ... LL | pub trait C: A + B { | - this trait is not dyn compatible... LL | const C: u8 = 0; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `C` = help: consider moving `C` to another trait = help: consider moving `A` to another trait = help: consider moving `B` to another trait @@ -166,15 +166,15 @@ note: for a trait to be dyn compatible it needs to allow building a vtable --> $DIR/item-privacy.rs:26:15 | LL | const A: u8 = 0; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `A` ... LL | const B: u8 = 0; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `B` ... LL | pub trait C: A + B { | - this trait is not dyn compatible... LL | const C: u8 = 0; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `C` = help: consider moving `C` to another trait = help: consider moving `A` to another trait = help: consider moving `B` to another trait diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr index f450f786f608..b7d8484e1041 100644 --- a/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr +++ b/tests/ui/traits/negative-impls/negated-auto-traits-error.stderr @@ -77,12 +77,12 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely --> $DIR/negated-auto-traits-error.rs:48:13 | LL | is_send(Box::new(TestType)); - | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `Unique` + | ------- ^^^^^^^^^^^^^^^^^^ the trait `Send` is not implemented for `std::ptr::Unique` | | | required by a bound introduced by this call | - = note: the trait bound `Unique: Send` is not satisfied - = note: required for `Unique` to implement `Send` + = note: the trait bound `std::ptr::Unique: Send` is not satisfied + = note: required for `std::ptr::Unique` to implement `Send` note: required because it appears within the type `Box` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` @@ -113,7 +113,7 @@ note: required because it appears within the type `Outer2` | LL | struct Outer2(T); | ^^^^^^ - = note: required for `Unique>` to implement `Send` + = note: required for `std::ptr::Unique>` to implement `Send` note: required because it appears within the type `Box>` --> $SRC_DIR/alloc/src/boxed.rs:LL:COL note: required by a bound in `is_send` diff --git a/tests/ui/traits/next-solver-ice.rs b/tests/ui/traits/next-solver-ice.rs new file mode 100644 index 000000000000..889d1094a103 --- /dev/null +++ b/tests/ui/traits/next-solver-ice.rs @@ -0,0 +1,9 @@ +//@compile-flags: -Znext-solver=globally +//@check-fail + +fn check() { + ::Item>>::from; + //~^ ERROR the trait bound `f32: From<::Item>` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/next-solver-ice.stderr b/tests/ui/traits/next-solver-ice.stderr new file mode 100644 index 000000000000..d6b022d70175 --- /dev/null +++ b/tests/ui/traits/next-solver-ice.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `f32: From<::Item>` is not satisfied + --> $DIR/next-solver-ice.rs:5:6 + | +LL | ::Item>>::from; + | ^^^ the nightly-only, unstable trait `ZeroablePrimitive` is not implemented for `f32` + | + = help: the following other types implement trait `ZeroablePrimitive`: + i128 + i16 + i32 + i64 + i8 + isize + u128 + u16 + and 4 others + = note: required for `f32` to implement `From<::Item>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/coercion/unfulfilled-unsize-coercion-recursion-limit.rs b/tests/ui/traits/next-solver/coercion/unfulfilled-unsize-coercion-recursion-limit.rs new file mode 100644 index 000000000000..24b32db3060d --- /dev/null +++ b/tests/ui/traits/next-solver/coercion/unfulfilled-unsize-coercion-recursion-limit.rs @@ -0,0 +1,35 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// A regression test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/266. +// Ensure that we do not accidentaly trying unfulfilled unsized coercions due to hitting recursion +// limits while trying to find the right fulfillment error source. + +fn argument_coercion(_: &U) {} + +pub fn test() { + argument_coercion(&{ + Nested(0.0, 0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + .add(0.0) + }); +} + +struct Nested(T, R); + +impl Nested { + fn add(self, value: U) -> Nested> { + Nested(value, self) + } +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/coercion/unsize-coercion-recursion-limit.rs b/tests/ui/traits/next-solver/coercion/unsize-coercion-recursion-limit.rs new file mode 100644 index 000000000000..42802e85cda1 --- /dev/null +++ b/tests/ui/traits/next-solver/coercion/unsize-coercion-recursion-limit.rs @@ -0,0 +1,25 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// A test to ensure that unsized coercion is not aborted when visiting a nested goal that +// exceeds the recursion limit and evaluates to `Certainty::Maybe`. +// See https://github.com/rust-lang/rust/pull/152444. + +#![allow(warnings)] + +struct W(T); +type Four = W>>>; +type Sixteen = Four>>>; + +fn ret(x: T) -> Sixteen { + todo!(); +} + +fn please_coerce() { + let mut y = Default::default(); + let x = ret(y); + let _: &Sixteen = &x; + y = 1u32; +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/coroutine.fail.stderr b/tests/ui/traits/next-solver/coroutine.fail.stderr index 8c263e8644bd..a289e9839b23 100644 --- a/tests/ui/traits/next-solver/coroutine.fail.stderr +++ b/tests/ui/traits/next-solver/coroutine.fail.stderr @@ -8,7 +8,7 @@ LL | / || { LL | | LL | | yield (); LL | | }, - | |_________^ the trait `Coroutine` is not implemented for `{coroutine@$DIR/coroutine.rs:20:9: 20:11}` + | |_________^ the nightly-only, unstable trait `Coroutine` is not implemented for `{coroutine@$DIR/coroutine.rs:20:9: 20:11}` | note: required by a bound in `needs_coroutine` --> $DIR/coroutine.rs:14:28 diff --git a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr index db7d2dd3e3a3..8334fdae9485 100644 --- a/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr +++ b/tests/ui/traits/next-solver/dont-ice-on-assoc-projection.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | impl Foo for T where T: Bar {} | ^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0119]: conflicting implementations of trait `Foo` for type `()` diff --git a/tests/ui/traits/next-solver/generalize/relate-alias-in-lub.rs b/tests/ui/traits/next-solver/generalize/relate-alias-in-lub.rs new file mode 100644 index 000000000000..a81e18559a39 --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/relate-alias-in-lub.rs @@ -0,0 +1,30 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass +// Reproduces https://github.com/rust-lang/rust/pull/151746#issuecomment-3822930803. +// +// The change we tried to make there caused relating a type variable with an alias inside lub, +// In 5bd20bbd0ba6c0285664e55a1ffc677d7487c98b, we moved around code +// that adds an alias-relate predicate to be earlier, from one shared codepath into several +// distinct code paths. However, we forgot the codepath in `LatticeOp`, causing an ICE in serde. +// In the end we dropped said commit, but the reproducer is still a useful as test. + +use std::marker::PhantomData; + +pub trait Trait { + type Error; +} + +pub struct Struct(PhantomData); + +impl Trait for () { + type Error = (); +} + +fn main() { + let _: Struct<<() as Trait>::Error> = match loop {} { + b => loop {}, + a => Struct(PhantomData), + }; +} diff --git a/tests/ui/traits/next-solver/generalize/subtype-obligations-bivariant-args.rs b/tests/ui/traits/next-solver/generalize/subtype-obligations-bivariant-args.rs new file mode 100644 index 000000000000..9e25401f0f9a --- /dev/null +++ b/tests/ui/traits/next-solver/generalize/subtype-obligations-bivariant-args.rs @@ -0,0 +1,52 @@ +//@ revisions: old next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Regression test for trait-system-refactor-initiative#250. +// Subtyping previously handled bivariant arguments by emitting +// a `WellFormed` obligation when generalizing them. +// +// This obligation then got dropped inside of an ambiguous `Subtype` +// obligation so we never constrained the bivariant arg. + +// Test case 1 +enum State +where + S: Iterator, +{ + Active { upstream: S }, + WindDown, + Complete, +} + +impl State +where + S: Iterator, +{ + fn foo(self) { + let x = match self { + State::Active { .. } => None, + State::WindDown => None, + State::Complete => Some(State::Complete), + }; + let _: Option> = x; + } +} + +// Test case 2 +trait Trait { + type Assoc; +} +impl Trait for T { + type Assoc = T; +} + +struct Foo, U>(T); + +fn main() { + let x = None.unwrap(); + let y = x; + let _: Foo<_, _> = x; + let _: Foo = x; +} diff --git a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs index 2b4f7ba9fa29..ceef87d76abb 100644 --- a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs +++ b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs @@ -12,8 +12,8 @@ // we already face this difficulty, probably. If we need to fix this by reducing the error margin, // we should improve compiletest. -#[derive(Clone, Eq)] //~ ERROR [E0277] -pub struct Struct(T); +#[derive(Clone, Eq)] +pub struct Struct(T); //~ ERROR [E0277] impl PartialEq for Struct where diff --git a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr index 290b1df1665d..912286a48faf 100644 --- a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr +++ b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr @@ -1,8 +1,10 @@ error[E0277]: the trait bound `T: Clone` is not satisfied - --> $DIR/global-cache-and-parallel-frontend.rs:15:17 + --> $DIR/global-cache-and-parallel-frontend.rs:16:12 | LL | #[derive(Clone, Eq)] - | ^^ the trait `Clone` is not implemented for `T` + | -- in this derive macro expansion +LL | pub struct Struct(T); + | ^^^^^^ the trait `Clone` is not implemented for `T` | note: required for `Struct` to implement `PartialEq` --> $DIR/global-cache-and-parallel-frontend.rs:18:19 diff --git a/tests/ui/traits/next-solver/global-where-bound-normalization.rs b/tests/ui/traits/next-solver/global-where-bound-normalization.rs new file mode 100644 index 000000000000..e57fbf378a0d --- /dev/null +++ b/tests/ui/traits/next-solver/global-where-bound-normalization.rs @@ -0,0 +1,45 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// Regression test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/257. + +#![feature(rustc_attrs)] +#![expect(internal_features)] +#![rustc_no_implicit_bounds] + +pub trait Bound {} +impl Bound for u8 {} + +pub trait Proj { + type Assoc; +} +impl Proj for U { + type Assoc = U; +} +impl Proj for MyField { + type Assoc = u8; +} + +// While wf-checking the global bounds of `fn foo`, elaborating this outlives predicate triggered a +// cycle in the search graph along a particular probe path, which was not an actual solution. +// That cycle then resulted in a forced false-positive ambiguity due to a performance hack in the +// search graph and then ended up floundering the root goal evaluation. +pub trait Field: Proj {} + +struct MyField; +impl Field for MyField {} + +trait IdReqField { + type This; +} +impl IdReqField for F { + type This = F; +} + +fn foo() +where + ::This: Field, +{ +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs b/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs index 2b9454db3fac..4da078dbb4f4 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs +++ b/tests/ui/traits/next-solver/normalize/normalize-const-in-async-body.rs @@ -2,6 +2,8 @@ //@ check-pass //@ edition:2021 +// Regression test for https://github.com/rust-lang/rust/issues/129865. + pub async fn cleanse_old_array_async(_: &[u8; BUCKET_LEN]) {} pub const BUCKET_LEN: usize = 0; diff --git a/tests/ui/traits/next-solver/opaques/eventually-constrained-region.rs b/tests/ui/traits/next-solver/opaques/eventually-constrained-region.rs new file mode 100644 index 000000000000..997bcd6ed9b4 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/eventually-constrained-region.rs @@ -0,0 +1,21 @@ +//@ check-pass +//@ compile-flags: -Znext-solver + +// Regression test for trait-system-refactor-initiative#264. +// +// Some defining uses of opaque types can't constrain captured regions to universals. +// Previouly, we eagerly report error in this case. +// Now we report error only if there's no fully defining use from all bodies of the typeck root. + +struct Inv<'a>(*mut &'a ()); + +fn mk_static() -> Inv<'static> { todo!() } + +fn guide_closure_sig<'a>(f: impl FnOnce() -> Inv<'a>) {} + +fn unconstrained_in_closure() -> impl Sized { + guide_closure_sig(|| unconstrained_in_closure()); + mk_static() +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/method_autoderef_constraints.rs b/tests/ui/traits/next-solver/opaques/method_autoderef_constraints.rs new file mode 100644 index 000000000000..d8375a62bb37 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/method_autoderef_constraints.rs @@ -0,0 +1,38 @@ +//@ compile-flags: -Znext-solver + +// Regression test for trait-system-refactor-initiative/issues/263 +// Previously `method_auto_deref_steps` would also return opaque +// types which have already been defined in the parent context. +// +// We then handled these opaque types by emitting `AliasRelate` goals +// when instantiating its result, assuming that operation to be infallible. +// By returning opaque type constraints from the parent context and +// constraining the hidden type without reproving the item bounds of +// the opaque, this ended up causing ICE. + +use std::ops::Deref; +trait Trait {} +struct Inv(*mut T); +impl Trait for i32 {} +impl Deref for Inv { + type Target = u32; + fn deref(&self) -> &Self::Target { + todo!() + } +} + +fn mk() -> T { todo!() } +fn foo() -> Inv { + //~^ ERROR: the trait bound `u32: Trait` is not satisfied [E0277] + let mut x: Inv<_> = mk(); + if false { + return x; + //~^ ERROR: the trait bound `u32: Trait` is not satisfied [E0277] + } + + x.count_ones(); + x + //~^ ERROR: mismatched types [E0308] +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/method_autoderef_constraints.stderr b/tests/ui/traits/next-solver/opaques/method_autoderef_constraints.stderr new file mode 100644 index 000000000000..c421222309a0 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/method_autoderef_constraints.stderr @@ -0,0 +1,43 @@ +error[E0277]: the trait bound `u32: Trait` is not satisfied + --> $DIR/method_autoderef_constraints.rs:29:16 + | +LL | return x; + | ^ the trait `Trait` is not implemented for `u32` + | +help: the trait `Trait` is implemented for `i32` + --> $DIR/method_autoderef_constraints.rs:16:1 + | +LL | impl Trait for i32 {} + | ^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/method_autoderef_constraints.rs:34:5 + | +LL | fn foo() -> Inv { + | --------------- + | | | + | | the expected opaque type + | expected `Inv` because of return type +... +LL | x + | ^ types differ + | + = note: expected struct `Inv` + found struct `Inv` + +error[E0277]: the trait bound `u32: Trait` is not satisfied + --> $DIR/method_autoderef_constraints.rs:25:1 + | +LL | fn foo() -> Inv { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u32` + | +help: the trait `Trait` is implemented for `i32` + --> $DIR/method_autoderef_constraints.rs:16:1 + | +LL | impl Trait for i32 {} + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/opaques/non-defining-use-borrowck-issue-145748.rs b/tests/ui/traits/next-solver/opaques/non-defining-use-borrowck-issue-145748.rs new file mode 100644 index 000000000000..ae70ffdfdaee --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/non-defining-use-borrowck-issue-145748.rs @@ -0,0 +1,14 @@ +//@ ignore-compare-mode-next-solver +//@ compile-flags: -Znext-solver +//@ check-pass + +// Make sure that we support non-defining uses in borrowck. +// Regression test for https://github.com/rust-lang/rust/issues/145748. + +pub fn f(_: &()) -> impl Fn() + '_ { + || { + let _ = f(&()); + } +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.rs b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.rs new file mode 100644 index 000000000000..61823c1e300d --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -Znext-solver + +// Just for diagnostics completeness. +// This is probably unimportant as we only report one error for such case in HIR typeck. + +#![feature(type_alias_impl_trait)] + +struct Invar<'a>(*mut &'a ()); + +fn mk_invar<'a>(a: &'a i32) -> Invar<'a> { + todo!() +} + +type MultiUse = impl Sized; + +#[define_opaque(MultiUse)] +fn capture_different_universals_not_on_bounds<'a, 'b, 'c>(a: &'a i32, b: &'b i32, c: &'c i32) { + let _ = || -> MultiUse { + //~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700] + mk_invar(a) + }; + let _ = || -> MultiUse { + //~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700] + mk_invar(b) + }; + let _ = || { + let _ = || -> MultiUse { + //~^ ERROR: hidden type for `MultiUse` captures lifetime that does not appear in bounds [E0700] + mk_invar(c) + }; + }; +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.stderr b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.stderr new file mode 100644 index 000000000000..28d9da3d4666 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/report-all-unexpected-hidden-errors.stderr @@ -0,0 +1,36 @@ +error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds + --> $DIR/report-all-unexpected-hidden-errors.rs:18:19 + | +LL | type MultiUse = impl Sized; + | ---------- opaque type defined here +... +LL | let _ = || -> MultiUse { + | ^^^^^^^^ + | + = note: hidden type `Invar<'_>` captures lifetime `'_` + +error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds + --> $DIR/report-all-unexpected-hidden-errors.rs:22:19 + | +LL | type MultiUse = impl Sized; + | ---------- opaque type defined here +... +LL | let _ = || -> MultiUse { + | ^^^^^^^^ + | + = note: hidden type `Invar<'_>` captures lifetime `'_` + +error[E0700]: hidden type for `MultiUse` captures lifetime that does not appear in bounds + --> $DIR/report-all-unexpected-hidden-errors.rs:27:23 + | +LL | type MultiUse = impl Sized; + | ---------- opaque type defined here +... +LL | let _ = || -> MultiUse { + | ^^^^^^^^ + | + = note: hidden type `Invar<'_>` captures lifetime `'_` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/traits/next-solver/stalled-coroutine-obligations.rs b/tests/ui/traits/next-solver/stalled-coroutine-obligations.rs new file mode 100644 index 000000000000..7c789af9e4cc --- /dev/null +++ b/tests/ui/traits/next-solver/stalled-coroutine-obligations.rs @@ -0,0 +1,50 @@ +//@ edition: 2024 +//@ compile-flags: -Znext-solver --diagnostic-width=300 + +// Previously we check stalled coroutine obligations after borrowck pass. +// And we wrongly assume that these obligations hold in borrowck which leads to +// silent normalization failures. +// In the next solver, we register opaques types via `NormalizesTo` goals. +// So these failures also cause those opaques types not registered in storage. +// +// Regression test for #151322 and #151323. + +#![feature(type_alias_impl_trait)] +#![feature(negative_impls)] +#![feature(auto_traits)] + +fn stalled_copy_clone() { + type T = impl Copy; + let foo: T = async {}; + //~^ ERROR: the trait bound + + type U = impl Clone; + let bar: U = async {}; + //~^ ERROR: the trait bound +} + +auto trait Valid {} +struct False; +impl !Valid for False {} + +fn stalled_auto_traits() { + type T = impl Valid; + let a = False; + let foo: T = async { a }; + //~^ ERROR: the trait bound `False: Valid` is not satisfied +} + + +trait Trait { + fn stalled_send(&self, b: *mut ()) -> impl Future + Send { + //~^ ERROR: type mismatch resolving + //~| ERROR: type mismatch resolving + async move { + //~^ ERROR: type mismatch resolving + b + } + } +} + + +fn main() {} diff --git a/tests/ui/traits/next-solver/stalled-coroutine-obligations.stderr b/tests/ui/traits/next-solver/stalled-coroutine-obligations.stderr new file mode 100644 index 000000000000..6afa406bf367 --- /dev/null +++ b/tests/ui/traits/next-solver/stalled-coroutine-obligations.stderr @@ -0,0 +1,62 @@ +error[E0277]: the trait bound `{async block@$DIR/stalled-coroutine-obligations.rs:18:18: 18:23}: Copy` is not satisfied + --> $DIR/stalled-coroutine-obligations.rs:18:14 + | +LL | let foo: T = async {}; + | ^ the trait `Copy` is not implemented for `{async block@$DIR/stalled-coroutine-obligations.rs:18:18: 18:23}` + +error[E0277]: the trait bound `{async block@$DIR/stalled-coroutine-obligations.rs:22:18: 22:23}: Clone` is not satisfied + --> $DIR/stalled-coroutine-obligations.rs:22:14 + | +LL | let bar: U = async {}; + | ^ the trait `Clone` is not implemented for `{async block@$DIR/stalled-coroutine-obligations.rs:22:18: 22:23}` + +error[E0277]: the trait bound `False: Valid` is not satisfied in `{async block@$DIR/stalled-coroutine-obligations.rs:33:18: 33:23}` + --> $DIR/stalled-coroutine-obligations.rs:33:14 + | +LL | let foo: T = async { a }; + | ^ ----- within this `{async block@$DIR/stalled-coroutine-obligations.rs:33:18: 33:23}` + | | + | unsatisfied trait bound + | +help: within `{async block@$DIR/stalled-coroutine-obligations.rs:33:18: 33:23}`, the trait `Valid` is not implemented for `False` + --> $DIR/stalled-coroutine-obligations.rs:27:1 + | +LL | struct False; + | ^^^^^^^^^^^^ +note: captured value does not implement `Valid` + --> $DIR/stalled-coroutine-obligations.rs:33:26 + | +LL | let foo: T = async { a }; + | ^ has type `False` which does not implement `Valid` + +error[E0271]: type mismatch resolving `impl Future + Send == {async block@$DIR/stalled-coroutine-obligations.rs:42:9: 42:19}` + --> $DIR/stalled-coroutine-obligations.rs:39:5 + | +LL | fn stalled_send(&self, b: *mut ()) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `impl Future + Send == {async block@$DIR/stalled-coroutine-obligations.rs:42:9: 42:19}` + --> $DIR/stalled-coroutine-obligations.rs:42:9 + | +LL | / async move { +LL | | +LL | | b +LL | | } + | |_________^ types differ + +error[E0271]: type mismatch resolving `{async block@$DIR/stalled-coroutine-obligations.rs:42:9: 42:19} <: impl Future + Send` + --> $DIR/stalled-coroutine-obligations.rs:39:62 + | +LL | fn stalled_send(&self, b: *mut ()) -> impl Future + Send { + | ______________________________________________________________^ +LL | | +LL | | +LL | | async move { +... | +LL | | } + | |_____^ types differ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr index d79e465b3e38..264ab9bebbb9 100644 --- a/tests/ui/traits/next-solver/well-formed-in-relate.stderr +++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr @@ -9,11 +9,11 @@ LL | x = unconstrained_map(); | = note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`: - impl Fn for &F - where A: Tuple, F: Fn, F: ?Sized; + where A: std::marker::Tuple, F: Fn, F: ?Sized; - impl Fn for Box - where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; + where Args: std::marker::Tuple, F: Fn, A: Allocator, F: ?Sized; - impl Fn for Exclusive - where F: Sync, F: Fn, Args: Tuple; + where F: Sync, F: Fn, Args: std::marker::Tuple; note: required by a bound in `unconstrained_map` --> $DIR/well-formed-in-relate.rs:21:25 | diff --git a/tests/ui/traits/nightly-only-unstable.force.stderr b/tests/ui/traits/nightly-only-unstable.force.stderr new file mode 100644 index 000000000000..c1b5a45dc827 --- /dev/null +++ b/tests/ui/traits/nightly-only-unstable.force.stderr @@ -0,0 +1,36 @@ +error[E0277]: the trait bound `(): LocalTrait` is not satisfied + --> $DIR/nightly-only-unstable.rs:25:21 + | +LL | use_local_trait(()); + | --------------- ^^ the trait `LocalTrait` is not implemented for `()` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/nightly-only-unstable.rs:14:1 + | +LL | trait LocalTrait {} + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `use_local_trait` + --> $DIR/nightly-only-unstable.rs:16:28 + | +LL | fn use_local_trait(_: impl LocalTrait) {} + | ^^^^^^^^^^ required by this bound in `use_local_trait` + +error[E0277]: the trait bound `(): ForeignTrait` is not satisfied + --> $DIR/nightly-only-unstable.rs:31:23 + | +LL | use_foreign_trait(()); + | ----------------- ^^ the trait `ForeignTrait` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `use_foreign_trait` + --> $DIR/nightly-only-unstable.rs:20:30 + | +LL | fn use_foreign_trait(_: impl force_unstable::ForeignTrait) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `use_foreign_trait` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/nightly-only-unstable.normal.stderr b/tests/ui/traits/nightly-only-unstable.normal.stderr new file mode 100644 index 000000000000..51b896cfefdf --- /dev/null +++ b/tests/ui/traits/nightly-only-unstable.normal.stderr @@ -0,0 +1,36 @@ +error[E0277]: the trait bound `(): LocalTrait` is not satisfied + --> $DIR/nightly-only-unstable.rs:25:21 + | +LL | use_local_trait(()); + | --------------- ^^ the trait `LocalTrait` is not implemented for `()` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/nightly-only-unstable.rs:14:1 + | +LL | trait LocalTrait {} + | ^^^^^^^^^^^^^^^^ +note: required by a bound in `use_local_trait` + --> $DIR/nightly-only-unstable.rs:16:28 + | +LL | fn use_local_trait(_: impl LocalTrait) {} + | ^^^^^^^^^^ required by this bound in `use_local_trait` + +error[E0277]: the trait bound `(): ForeignTrait` is not satisfied + --> $DIR/nightly-only-unstable.rs:31:23 + | +LL | use_foreign_trait(()); + | ----------------- ^^ the nightly-only, unstable trait `ForeignTrait` is not implemented for `()` + | | + | required by a bound introduced by this call + | +note: required by a bound in `use_foreign_trait` + --> $DIR/nightly-only-unstable.rs:20:30 + | +LL | fn use_foreign_trait(_: impl force_unstable::ForeignTrait) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `use_foreign_trait` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/nightly-only-unstable.rs b/tests/ui/traits/nightly-only-unstable.rs new file mode 100644 index 000000000000..94f300074390 --- /dev/null +++ b/tests/ui/traits/nightly-only-unstable.rs @@ -0,0 +1,36 @@ +//@ revisions: normal force +//@ edition: 2024 +//@ aux-crate: force_unstable=force_unstable.rs +//@[force] compile-flags: -Zforce-unstable-if-unmarked + +#![feature(rustc_private)] + +// Regression test for . +// +// When building a crate with `-Zforce-unstable-if-unmarked` (e.g. the compiler or stdlib), +// it's unhelpful to mention that a not-implemented trait is unstable, because that will +// be true of every local and foreign trait that isn't explicitly marked stable. + +trait LocalTrait {} + +fn use_local_trait(_: impl LocalTrait) {} +//~^ NOTE required by a bound in `use_local_trait` +//~| NOTE required by this bound in `use_local_trait` + +fn use_foreign_trait(_: impl force_unstable::ForeignTrait) {} +//~^ NOTE required by a bound in `use_foreign_trait` +//~| NOTE required by this bound in `use_foreign_trait` + +fn main() { + use_local_trait(()); + //~^ ERROR the trait bound `(): LocalTrait` is not satisfied + //[normal]~| NOTE the trait `LocalTrait` is not implemented for `()` + //[force]~| NOTE the trait `LocalTrait` is not implemented for `()` + //~| NOTE required by a bound introduced by this call + + use_foreign_trait(()); + //~^ ERROR the trait bound `(): ForeignTrait` is not satisfied + //[normal]~| NOTE the nightly-only, unstable trait `ForeignTrait` is not implemented for `()` + //[force]~| NOTE the trait `ForeignTrait` is not implemented for `()` + //~| NOTE required by a bound introduced by this call +} diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr index 15902bf16de5..c325718b3033 100644 --- a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr @@ -8,15 +8,12 @@ LL | #![feature(non_lifetime_binders)] = note: `#[warn(incomplete_features)]` on by default error[E0309]: the placeholder type `F` may not live long enough - --> $DIR/type-match-with-late-bound.rs:8:1 + --> $DIR/type-match-with-late-bound.rs:8:32 | -LL | async fn walk2<'a, T: 'a>(_: T) - | ^ -- the placeholder type `F` must be valid for the lifetime `'a` as defined here... - | _| - | | -LL | | where -LL | | for F: 'a, - | |_________________^ ...so that the type `F` will meet its required lifetime bounds... +LL | async fn walk2<'a, T: 'a>(_: T) + | -- ^ ...so that the type `F` will meet its required lifetime bounds... + | | + | the placeholder type `F` must be valid for the lifetime `'a` as defined here... | note: ...that is required by this bound --> $DIR/type-match-with-late-bound.rs:10:15 diff --git a/tests/ui/traits/normalize-associated-type-in-where-clause.rs b/tests/ui/traits/normalize-associated-type-in-where-clause.rs new file mode 100644 index 000000000000..25ca4a41aa85 --- /dev/null +++ b/tests/ui/traits/normalize-associated-type-in-where-clause.rs @@ -0,0 +1,30 @@ +//@ run-pass +//! regression test for issue #50825, #51044 +//! Check that the feature gate normalizes associated types. + +#![allow(dead_code)] +struct Foo(T); +struct Duck; +struct Quack; + +trait Hello +where + A: Animal, +{ +} + +trait Animal { + type Noise; +} + +trait Loud {} + +impl Loud for f32 {} + +impl Animal for Duck { + type Noise = Quack; +} + +impl Hello for Foo where f32: Loud<::Noise> {} + +fn main() {} diff --git a/tests/ui/traits/object/with-self-in-projection-output-bad.stderr b/tests/ui/traits/object/with-self-in-projection-output-bad.stderr index c9b36e8d29de..d0cc7f7fc924 100644 --- a/tests/ui/traits/object/with-self-in-projection-output-bad.stderr +++ b/tests/ui/traits/object/with-self-in-projection-output-bad.stderr @@ -5,7 +5,7 @@ LL | type Output; | ----------- `Output` defined here ... LL | let _x: Box> = Box::new(2u32); - | ^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Helper` + | ^^^^^^^^^^^^^^^^^^ help: specify the associated type: `Helper` error[E0191]: the value of the associated type `Output` in `Base` must be specified --> $DIR/with-self-in-projection-output-bad.rs:48:21 @@ -14,7 +14,7 @@ LL | type Output; | ----------- `Output` defined here ... LL | let _y: Box> = Box::new(2u32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `NormalizableHelper` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated type: `NormalizableHelper` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/question-mark-result-err-mismatch.rs b/tests/ui/traits/question-mark-result-err-mismatch.rs index df1d5105a34a..dfea4b93f46d 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.rs +++ b/tests/ui/traits/question-mark-result-err-mismatch.rs @@ -9,7 +9,7 @@ fn foo() -> Result { //~ NOTE expected `String` because of this }); let one = x .map(|s| ()) - .map_err(|e| { //~ NOTE this can't be annotated with `?` because it has type `Result<_, ()>` + .map_err(|e| { //~ NOTE this has type `Result<_, ()>` e; //~ HELP remove this semicolon }) .map(|()| "")?; //~ ERROR `?` couldn't convert the error to `String` diff --git a/tests/ui/traits/question-mark-result-err-mismatch.stderr b/tests/ui/traits/question-mark-result-err-mismatch.stderr index 0f83c9e73a31..be3f17cfc527 100644 --- a/tests/ui/traits/question-mark-result-err-mismatch.stderr +++ b/tests/ui/traits/question-mark-result-err-mismatch.stderr @@ -9,7 +9,7 @@ LL | .map_err(|e| { LL | | e; | | - help: remove this semicolon LL | | }) - | |__________- this can't be annotated with `?` because it has type `Result<_, ()>` + | |__________- this has type `Result<_, ()>` LL | .map(|()| "")?; | ^ the trait `From<()>` is not implemented for `String` | diff --git a/tests/ui/traits/question-mark-span-144304.rs b/tests/ui/traits/question-mark-span-144304.rs new file mode 100644 index 000000000000..bb015cae8ac9 --- /dev/null +++ b/tests/ui/traits/question-mark-span-144304.rs @@ -0,0 +1,8 @@ +//@ ignore-arm - armhf-gnu have more types implement trait `From`, let's skip it +fn f() -> Result<(), i32> { + Err("str").map_err(|e| e)?; //~ ERROR `?` couldn't convert the error to `i32` + Err("str").map_err(|e| e.to_string())?; //~ ERROR `?` couldn't convert the error to `i32` + Ok(()) +} + +fn main() {} diff --git a/tests/ui/traits/question-mark-span-144304.stderr b/tests/ui/traits/question-mark-span-144304.stderr new file mode 100644 index 000000000000..a412da0d235d --- /dev/null +++ b/tests/ui/traits/question-mark-span-144304.stderr @@ -0,0 +1,41 @@ +error[E0277]: `?` couldn't convert the error to `i32` + --> $DIR/question-mark-span-144304.rs:3:30 + | +LL | fn f() -> Result<(), i32> { + | --------------- expected `i32` because of this +LL | Err("str").map_err(|e| e)?; + | ---------- ^ the trait `From<&str>` is not implemented for `i32` + | | + | this has type `Result<_, &str>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = help: the following other types implement trait `From`: + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + +error[E0277]: `?` couldn't convert the error to `i32` + --> $DIR/question-mark-span-144304.rs:4:42 + | +LL | fn f() -> Result<(), i32> { + | --------------- expected `i32` because of this +LL | Err("str").map_err(|e| e)?; +LL | Err("str").map_err(|e| e.to_string())?; + | ---------- --------------------------^ the trait `From` is not implemented for `i32` + | | | + | | this can't be annotated with `?` because it has type `Result<_, String>` + | this has type `Result<_, &str>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = help: the following other types implement trait `From`: + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + `i32` implements `From` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs new file mode 100644 index 000000000000..f82bffc598b8 --- /dev/null +++ b/tests/ui/traits/solver-cycles/assoc-equality-cycle.rs @@ -0,0 +1,10 @@ +//! regression test for https://github.com/rust-lang/rust/issues/21177 +trait Trait { + type A; + type B; +} + +fn foo>() {} +//~^ ERROR cycle detected + +fn main() {} diff --git a/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr new file mode 100644 index 000000000000..a8c0228601a2 --- /dev/null +++ b/tests/ui/traits/solver-cycles/assoc-equality-cycle.stderr @@ -0,0 +1,17 @@ +error[E0391]: cycle detected when computing the bounds for type parameter `T` + --> $DIR/assoc-equality-cycle.rs:7:21 + | +LL | fn foo>() {} + | ^^^^ + | + = note: ...which immediately requires computing the bounds for type parameter `T` again +note: cycle used when computing explicit predicates of `foo` + --> $DIR/assoc-equality-cycle.rs:7:21 + | +LL | fn foo>() {} + | ^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/traits/solver-cycles/self-item-cycle.rs b/tests/ui/traits/solver-cycles/self-item-cycle.rs new file mode 100644 index 000000000000..b0b5ab4235be --- /dev/null +++ b/tests/ui/traits/solver-cycles/self-item-cycle.rs @@ -0,0 +1,6 @@ +//! regression test for https://github.com/rust-lang/rust/issues/20772 +trait T: Iterator //~ ERROR cycle detected +{ +} + +fn main() {} diff --git a/tests/ui/traits/solver-cycles/self-item-cycle.stderr b/tests/ui/traits/solver-cycles/self-item-cycle.stderr new file mode 100644 index 000000000000..9ffb9955af8a --- /dev/null +++ b/tests/ui/traits/solver-cycles/self-item-cycle.stderr @@ -0,0 +1,17 @@ +error[E0391]: cycle detected when computing the super traits of `T` with associated type name `Item` + --> $DIR/self-item-cycle.rs:2:1 + | +LL | trait T: Iterator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: ...which immediately requires computing the super traits of `T` with associated type name `Item` again +note: cycle used when computing the super predicates of `T` + --> $DIR/self-item-cycle.rs:2:1 + | +LL | trait T: Iterator + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr index 07a54d574df4..3bae5798d047 100644 --- a/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr +++ b/tests/ui/traits/suggest-dereferences/invalid-suggest-deref-issue-127590.stderr @@ -24,7 +24,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -55,7 +59,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone( | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `Iterator` = note: required for `Zip, &std::slice::Iter<'_, {integer}>>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -68,7 +76,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter()) { | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -80,7 +92,11 @@ LL | for (src, dest) in std::iter::zip(fields.iter(), &variant.iter().clone( | = help: the trait `Iterator` is not implemented for `&std::slice::Iter<'_, {integer}>` help: the trait `Iterator` is implemented for `std::slice::Iter<'_, T>` + --> $SRC_DIR/core/src/slice/iter/macros.rs:LL:COL --> $SRC_DIR/core/src/slice/iter.rs:LL:COL + ::: $SRC_DIR/core/src/slice/iter.rs:LL:COL + | + = note: in this macro invocation = note: required for `&std::slice::Iter<'_, {integer}>` to implement `IntoIterator` = note: this error originates in the macro `iterator` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/traits/trait-object-method-call-2935.rs b/tests/ui/traits/trait-object-method-call-2935.rs new file mode 100644 index 000000000000..ea24aae89462 --- /dev/null +++ b/tests/ui/traits/trait-object-method-call-2935.rs @@ -0,0 +1,30 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2935 + +//@ run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +//type t = { a: isize }; +// type t = { a: bool }; +type t = bool; + +trait it { + fn f(&self); +} + +impl it for t { + fn f(&self) {} +} + +pub fn main() { + // let x = ({a: 4} as it); + // let y = box ({a: 4}); + // let z = box ({a: 4} as it); + // let z = box ({a: true} as it); + let z: Box<_> = Box::new(Box::new(true) as Box); + // x.f(); + // y.f(); + // (*z).f(); + println!("ok so far..."); + z.f(); //segfault +} diff --git a/tests/ui/traits/trait-object-type-alias-3052.rs b/tests/ui/traits/trait-object-type-alias-3052.rs new file mode 100644 index 000000000000..e601c76713dc --- /dev/null +++ b/tests/ui/traits/trait-object-type-alias-3052.rs @@ -0,0 +1,13 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3052 + +//@ run-pass +#![allow(dead_code)] + +type Connection = Box) + 'static>; + +fn f() -> Option { + let mock_connection: Connection = Box::new(|_| {}); + Some(mock_connection) +} + +pub fn main() {} diff --git a/tests/ui/traits/trait-or-new-type-instead.stderr b/tests/ui/traits/trait-or-new-type-instead.stderr index 5f5aa3ac5698..ad12a84a4b80 100644 --- a/tests/ui/traits/trait-or-new-type-instead.stderr +++ b/tests/ui/traits/trait-or-new-type-instead.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl Option { | ^^^^^^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error: aborting due to 1 previous error diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr index 392680aa5064..1087fac50fd0 100644 --- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr +++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.next.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&dyn for<'a> Subtrait<'a, 'a>: CoerceUnsized<&dyn --> $DIR/higher-ranked-upcasting-ub.rs:22:5 | LL | x - | ^ the trait `Unsize Supertrait<'a, 'b>>` is not implemented for `dyn for<'a> Subtrait<'a, 'a>` + | ^ the nightly-only, unstable trait `Unsize Supertrait<'a, 'b>>` is not implemented for `dyn for<'a> Subtrait<'a, 'a>` | = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information = note: required for `&dyn for<'a> Subtrait<'a, 'a>` to implement `CoerceUnsized<&dyn for<'a, 'b> Supertrait<'a, 'b>>` diff --git a/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr b/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr index e63a0bf50b7a..d2d679243ee7 100644 --- a/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr +++ b/tests/ui/traits/unsize-goal-escaping-bounds.current.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `for<'a> (): Unsize<(dyn Trait + 'a)>` is not sati --> $DIR/unsize-goal-escaping-bounds.rs:20:5 | LL | foo(); - | ^^^^^ the trait `for<'a> Unsize<(dyn Trait + 'a)>` is not implemented for `()` + | ^^^^^ the nightly-only, unstable trait `for<'a> Unsize<(dyn Trait + 'a)>` is not implemented for `()` | = note: all implementations of `Unsize` are provided automatically by the compiler, see for more information note: required by a bound in `foo` diff --git a/tests/ui/traits/unspecified-self-in-trait-ref.stderr b/tests/ui/traits/unspecified-self-in-trait-ref.stderr index 86b77193155d..b7d78a3284e3 100644 --- a/tests/ui/traits/unspecified-self-in-trait-ref.stderr +++ b/tests/ui/traits/unspecified-self-in-trait-ref.stderr @@ -97,7 +97,7 @@ LL | pub trait Bar { LL | let e = Bar::::lol(); | ^^^^^^^^^^^^ missing reference to `A` | - = note: because the parameter default references `Self`, the parameter must be specified on the object type + = note: because the parameter default references `Self`, the parameter must be specified on the trait object type error: aborting due to 5 previous errors; 5 warnings emitted diff --git a/tests/ui/traits/vtable/missing-generics-issue-151330.rs b/tests/ui/traits/vtable/missing-generics-issue-151330.rs new file mode 100644 index 000000000000..352ad7be3d3a --- /dev/null +++ b/tests/ui/traits/vtable/missing-generics-issue-151330.rs @@ -0,0 +1,23 @@ +//@ compile-flags: -Znext-solver=globally +// Regression test for issue https://github.com/rust-lang/rust/issues/151330 + +trait Supertrait {} + +trait Trait

: Supertrait {} +//~^ ERROR missing generics for trait `Supertrait` +//~| ERROR missing generics for trait `Supertrait` +//~| ERROR missing generics for trait `Supertrait` + +impl

Trait

for () {} + +const fn upcast

(x: &dyn Trait

) -> &dyn Trait

{ + x +} + +const fn foo() -> &'static dyn Supertrait<()> { + upcast::<()>(&()) +} + +const _: &'static dyn Supertrait<()> = foo(); + +fn main() {} diff --git a/tests/ui/traits/vtable/missing-generics-issue-151330.stderr b/tests/ui/traits/vtable/missing-generics-issue-151330.stderr new file mode 100644 index 000000000000..65ef08cad32a --- /dev/null +++ b/tests/ui/traits/vtable/missing-generics-issue-151330.stderr @@ -0,0 +1,53 @@ +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

: Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - +help: add missing generic argument + | +LL | trait Trait

: Supertrait {} + | +++ + +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

: Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | trait Trait

: Supertrait {} + | +++ + +error[E0107]: missing generics for trait `Supertrait` + --> $DIR/missing-generics-issue-151330.rs:6:17 + | +LL | trait Trait

: Supertrait {} + | ^^^^^^^^^^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `T` + --> $DIR/missing-generics-issue-151330.rs:4:7 + | +LL | trait Supertrait {} + | ^^^^^^^^^^ - + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing generic argument + | +LL | trait Trait

: Supertrait {} + | +++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs index ec6bb7bbcc59..35465183001a 100644 --- a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs +++ b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.rs @@ -5,8 +5,8 @@ // Issue #148892. //@ aux-crate:crate1=crate1.rs -struct MyStruct; //~ HELP the trait `Trait` is not implemented for `MyStruct` +struct MyStruct; //~ HELP the trait `crate1::Trait` is not implemented for `MyStruct` fn main() { - crate1::foo(MyStruct); //~ ERROR the trait bound `MyStruct: Trait` is not satisfied + crate1::foo(MyStruct); //~ ERROR the trait bound `MyStruct: crate1::Trait` is not satisfied } diff --git a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr index 7fec237f54d4..5bcda9f2a95b 100644 --- a/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr +++ b/tests/ui/traits/wrong-multiple-different-versions-of-a-crate.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `MyStruct: Trait` is not satisfied +error[E0277]: the trait bound `MyStruct: crate1::Trait` is not satisfied --> $DIR/wrong-multiple-different-versions-of-a-crate.rs:11:17 | LL | crate1::foo(MyStruct); @@ -6,7 +6,7 @@ LL | crate1::foo(MyStruct); | | | required by a bound introduced by this call | -help: the trait `Trait` is not implemented for `MyStruct` +help: the trait `crate1::Trait` is not implemented for `MyStruct` --> $DIR/wrong-multiple-different-versions-of-a-crate.rs:8:1 | LL | struct MyStruct; diff --git a/tests/ui/transmutability/assoc-bound.stderr b/tests/ui/transmutability/assoc-bound.stderr index 4dff24e2002a..66a81f353815 100644 --- a/tests/ui/transmutability/assoc-bound.stderr +++ b/tests/ui/transmutability/assoc-bound.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `::AssocA: TransmuteFrom<(), Assume { alig LL | type AssocB = T::AssocA; | ^^^^^^^^^ unsatisfied trait bound | - = help: the trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `::AssocA` + = help: the nightly-only, unstable trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `::AssocA` note: required by a bound in `B::AssocB` --> $DIR/assoc-bound.rs:9:18 | diff --git a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr index 6cb6a85c78a6..6f7e9e1bfa33 100644 --- a/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr +++ b/tests/ui/transmutability/dont-assume-err-is-yes-issue-126377.stderr @@ -17,7 +17,7 @@ error[E0277]: the trait bound `(): TransmuteFrom<(), { Assume::SAFETY }>` is not --> $DIR/dont-assume-err-is-yes-issue-126377.rs:14:23 | LL | is_transmutable::<{}>(); - | ^^ the trait `TransmuteFrom<(), { Assume::SAFETY }>` is not implemented for `()` + | ^^ the nightly-only, unstable trait `TransmuteFrom<(), { Assume::SAFETY }>` is not implemented for `()` | note: required by a bound in `is_transmutable` --> $DIR/dont-assume-err-is-yes-issue-126377.rs:9:9 diff --git a/tests/ui/transmutability/non_scalar_alignment_value.rs b/tests/ui/transmutability/non_scalar_alignment_value.rs new file mode 100644 index 000000000000..45c9e61fcfe2 --- /dev/null +++ b/tests/ui/transmutability/non_scalar_alignment_value.rs @@ -0,0 +1,30 @@ +#![feature(min_generic_const_args)] +//~^ WARN the feature `min_generic_const_args` is incomplete + +#![feature(transmutability)] + +mod assert { + use std::mem::{Assume, TransmuteFrom}; + struct Dst {} + fn is_maybe_transmutable() + where + Dst: TransmuteFrom< + (), + { + Assume { + alignment: Assume {}, + //~^ ERROR struct expression with missing field initialiser for `alignment` + //~| ERROR struct expression with missing field initialiser for `lifetimes` + //~| ERROR struct expression with missing field initialiser for `safety` + //~| ERROR struct expression with missing field initialiser for `validity` + lifetimes: const { true }, + safety: const { true }, + validity: const { true }, + } + }, + >, + { + } +} + +fn main() {} diff --git a/tests/ui/transmutability/non_scalar_alignment_value.stderr b/tests/ui/transmutability/non_scalar_alignment_value.stderr new file mode 100644 index 000000000000..d22c6d0b27e8 --- /dev/null +++ b/tests/ui/transmutability/non_scalar_alignment_value.stderr @@ -0,0 +1,35 @@ +warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/non_scalar_alignment_value.rs:1:12 + | +LL | #![feature(min_generic_const_args)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: struct expression with missing field initialiser for `alignment` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^^^^ + +error: struct expression with missing field initialiser for `lifetimes` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^^^^ + +error: struct expression with missing field initialiser for `safety` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^^^^ + +error: struct expression with missing field initialiser for `validity` + --> $DIR/non_scalar_alignment_value.rs:15:32 + | +LL | alignment: Assume {}, + | ^^^^^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted + diff --git a/tests/ui/transmutability/references/unsafecell.stderr b/tests/ui/transmutability/references/unsafecell.stderr index 02a0935e84ea..85d6724b03fa 100644 --- a/tests/ui/transmutability/references/unsafecell.stderr +++ b/tests/ui/transmutability/references/unsafecell.stderr @@ -2,7 +2,7 @@ error[E0277]: `&u8` cannot be safely transmuted into `&UnsafeCell` --> $DIR/unsafecell.rs:27:50 | LL | assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell` + | ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell` | note: required by a bound in `is_maybe_transmutable` --> $DIR/unsafecell.rs:12:14 @@ -17,7 +17,7 @@ error[E0277]: `&UnsafeCell` cannot be safely transmuted into `&UnsafeCell $DIR/unsafecell.rs:29:62 | LL | assert::is_maybe_transmutable::<&'static UnsafeCell, &'static UnsafeCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell` + | ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell` | note: required by a bound in `is_maybe_transmutable` --> $DIR/unsafecell.rs:12:14 @@ -32,7 +32,7 @@ error[E0277]: `&mut bool` cannot be safely transmuted into `&UnsafeCell` --> $DIR/unsafecell.rs:45:56 | LL | assert::is_maybe_transmutable::<&'static mut bool, &'static UnsafeCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell` + | ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell` | note: required by a bound in `is_maybe_transmutable` --> $DIR/unsafecell.rs:12:14 @@ -47,7 +47,7 @@ error[E0277]: `&mut UnsafeCell` cannot be safely transmuted into `&UnsafeC --> $DIR/unsafecell.rs:46:68 | LL | assert::is_maybe_transmutable::<&'static mut UnsafeCell, &'static UnsafeCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell` + | ^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Freeze` is not implemented for `UnsafeCell` | note: required by a bound in `is_maybe_transmutable` --> $DIR/unsafecell.rs:12:14 diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr index 1a0563b469c1..a96876a2c25a 100644 --- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr +++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr @@ -12,7 +12,7 @@ LL | struct ExplicitlyPadded(Box); error[E0391]: cycle detected when computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` | = note: ...which immediately requires computing layout of `should_pad_explicitly_packed_field::ExplicitlyPadded` again - = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::TransmuteFrom` + = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::TransmuteFrom` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 2 previous errors diff --git a/tests/ui/transmutability/transmute-with-type-params.rs b/tests/ui/transmutability/transmute-with-type-params.rs new file mode 100644 index 000000000000..f1630449a41b --- /dev/null +++ b/tests/ui/transmutability/transmute-with-type-params.rs @@ -0,0 +1,21 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ [next] compile-flags: -Znext-solver +//@ check-pass + +// A regression test for https://github.com/rust-lang/rust/issues/151300 + +#![feature(transmutability)] +use std::mem::TransmuteFrom; + +pub fn is_maybe_transmutable() +where + Dst: TransmuteFrom, +{ +} + +fn function_with_generic() { + is_maybe_transmutable::<(), ()>(); +} + +fn main() {} diff --git a/tests/ui/treat-err-as-bug/err.stderr b/tests/ui/treat-err-as-bug/err.stderr index 2a9935c5d22b..8ff267deacef 100644 --- a/tests/ui/treat-err-as-bug/err.stderr +++ b/tests/ui/treat-err-as-bug/err.stderr @@ -5,7 +5,7 @@ LL | pub static C: u32 = 0 - 1; | ^^^^^ evaluation of `C` failed here -error: the compiler unexpectedly panicked. this is a bug. +error: the compiler unexpectedly panicked. This is a bug query stack during panic: #0 [eval_static_initializer] evaluating initializer of static `C` diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.stderr b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr index 88983e95cee7..ae1bad55960e 100644 --- a/tests/ui/treat-err-as-bug/span_delayed_bug.stderr +++ b/tests/ui/treat-err-as-bug/span_delayed_bug.stderr @@ -5,7 +5,7 @@ LL | fn main() {} | ^^^^^^^^^ -error: the compiler unexpectedly panicked. this is a bug. +error: the compiler unexpectedly panicked. This is a bug query stack during panic: #0 [trigger_delayed_bug] triggering a delayed bug for testing incremental diff --git a/tests/ui/trimmed-paths/auxiliary/doc_hidden_helper.rs b/tests/ui/trimmed-paths/auxiliary/doc_hidden_helper.rs new file mode 100644 index 000000000000..2e5e1591606e --- /dev/null +++ b/tests/ui/trimmed-paths/auxiliary/doc_hidden_helper.rs @@ -0,0 +1,18 @@ +//@ edition: 2024 + +pub struct ActuallyPub {} +#[doc(hidden)] +pub struct DocHidden {} + +pub mod pub_mod { + pub struct ActuallyPubInPubMod {} + #[doc(hidden)] + pub struct DocHiddenInPubMod {} +} + +#[doc(hidden)] +pub mod hidden_mod { + pub struct ActuallyPubInHiddenMod {} + #[doc(hidden)] + pub struct DocHiddenInHiddenMod {} +} diff --git a/tests/ui/trimmed-paths/core-unicode.rs b/tests/ui/trimmed-paths/core-unicode.rs new file mode 100644 index 000000000000..4a3eeca62970 --- /dev/null +++ b/tests/ui/trimmed-paths/core-unicode.rs @@ -0,0 +1,19 @@ +//@ edition: 2024 + +// Test that the `#[doc(hidden)]` module `core::unicode` module does not +// disqualify another item named `unicode` from path trimming in diagnostics. + +use core::marker::PhantomData; + +mod inner { + #[expect(non_camel_case_types)] + pub(crate) enum unicode {} +} + +fn main() { + let PhantomData::<(inner::unicode, u32)> = PhantomData::<(u32, inner::unicode)>; + //~^ ERROR mismatched types [E0308] + //~| NOTE expected `PhantomData<(u32, unicode)>`, found `PhantomData<(unicode, u32)>` + //~| NOTE this expression has type `PhantomData<(u32, unicode)>` + //~| NOTE expected struct `PhantomData<(u32, unicode)>` +} diff --git a/tests/ui/trimmed-paths/core-unicode.stderr b/tests/ui/trimmed-paths/core-unicode.stderr new file mode 100644 index 000000000000..7351896b0b54 --- /dev/null +++ b/tests/ui/trimmed-paths/core-unicode.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/core-unicode.rs:14:9 + | +LL | let PhantomData::<(inner::unicode, u32)> = PhantomData::<(u32, inner::unicode)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------------------ this expression has type `PhantomData<(u32, unicode)>` + | | + | expected `PhantomData<(u32, unicode)>`, found `PhantomData<(unicode, u32)>` + | + = note: expected struct `PhantomData<(u32, unicode)>` + found struct `PhantomData<(unicode, u32)>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/trimmed-paths/doc-hidden.rs b/tests/ui/trimmed-paths/doc-hidden.rs new file mode 100644 index 000000000000..c3125385c7e4 --- /dev/null +++ b/tests/ui/trimmed-paths/doc-hidden.rs @@ -0,0 +1,68 @@ +//@ edition: 2024 +//@ aux-crate: helper=doc_hidden_helper.rs + +// Test that `#[doc(hidden)]` items in other crates do not disqualify another +// item with the same name from path trimming in diagnostics. + +// Declare several modules and types whose short names match those in the aux crate. +// +// Of these, only `ActuallyPub` and `ActuallyPubInPubMod` should be disqualified +// from path trimming, because the other names only collide with `#[doc(hidden)]` +// names. +mod local { + pub(crate) struct ActuallyPub {} + pub(crate) struct DocHidden {} + + pub(crate) mod pub_mod { + pub(crate) struct ActuallyPubInPubMod {} + pub(crate) struct DocHiddenInPubMod {} + } + + pub(crate) mod hidden_mod { + pub(crate) struct ActuallyPubInHiddenMod {} + pub(crate) struct DocHiddenInHiddenMod {} + } +} + +fn main() { + uses_local(); + uses_helper(); +} + +fn uses_local() { + use local::{ActuallyPub, DocHidden}; + use local::pub_mod::{ActuallyPubInPubMod, DocHiddenInPubMod}; + use local::hidden_mod::{ActuallyPubInHiddenMod, DocHiddenInHiddenMod}; + + let _: ( + //~^ NOTE expected due to this + ActuallyPub, + DocHidden, + ActuallyPubInPubMod, + DocHiddenInPubMod, + ActuallyPubInHiddenMod, + DocHiddenInHiddenMod, + ) = 3u32; + //~^ ERROR mismatched types [E0308] + //~| NOTE expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + //~| NOTE expected tuple `(local::ActuallyPub, DocHidden, local::pub_mod::ActuallyPubInPubMod, DocHiddenInPubMod, ActuallyPubInHiddenMod, DocHiddenInHiddenMod)` +} + +fn uses_helper() { + use helper::{ActuallyPub, DocHidden}; + use helper::pub_mod::{ActuallyPubInPubMod, DocHiddenInPubMod}; + use helper::hidden_mod::{ActuallyPubInHiddenMod, DocHiddenInHiddenMod}; + + let _: ( + //~^ NOTE expected due to this + ActuallyPub, + DocHidden, + ActuallyPubInPubMod, + DocHiddenInPubMod, + ActuallyPubInHiddenMod, + DocHiddenInHiddenMod, + ) = 3u32; + //~^ ERROR mismatched types [E0308] + //~| NOTE expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + //~| NOTE expected tuple `(doc_hidden_helper::ActuallyPub, doc_hidden_helper::DocHidden, doc_hidden_helper::pub_mod::ActuallyPubInPubMod, doc_hidden_helper::pub_mod::DocHiddenInPubMod, doc_hidden_helper::hidden_mod::ActuallyPubInHiddenMod, doc_hidden_helper::hidden_mod::DocHiddenInHiddenMod)` +} diff --git a/tests/ui/trimmed-paths/doc-hidden.stderr b/tests/ui/trimmed-paths/doc-hidden.stderr new file mode 100644 index 000000000000..167c92c50a35 --- /dev/null +++ b/tests/ui/trimmed-paths/doc-hidden.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/doc-hidden.rs:45:9 + | +LL | let _: ( + | ____________- +LL | | +LL | | ActuallyPub, +LL | | DocHidden, +... | +LL | | DocHiddenInHiddenMod, +LL | | ) = 3u32; + | | - ^^^^ expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + | |_____| + | expected due to this + | + = note: expected tuple `(local::ActuallyPub, DocHidden, local::pub_mod::ActuallyPubInPubMod, DocHiddenInPubMod, ActuallyPubInHiddenMod, DocHiddenInHiddenMod)` + found type `u32` + +error[E0308]: mismatched types + --> $DIR/doc-hidden.rs:64:9 + | +LL | let _: ( + | ____________- +LL | | +LL | | ActuallyPub, +LL | | DocHidden, +... | +LL | | DocHiddenInHiddenMod, +LL | | ) = 3u32; + | | - ^^^^ expected `(ActuallyPub, ..., ..., ..., ..., ...)`, found `u32` + | |_____| + | expected due to this + | + = note: expected tuple `(doc_hidden_helper::ActuallyPub, doc_hidden_helper::DocHidden, doc_hidden_helper::pub_mod::ActuallyPubInPubMod, doc_hidden_helper::pub_mod::DocHiddenInPubMod, doc_hidden_helper::hidden_mod::ActuallyPubInHiddenMod, doc_hidden_helper::hidden_mod::DocHiddenInHiddenMod)` + found type `u32` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/try-block/try-block-bad-type-heterogeneous.rs b/tests/ui/try-block/try-block-bad-type-heterogeneous.rs new file mode 100644 index 000000000000..b099651bf8a9 --- /dev/null +++ b/tests/ui/try-block/try-block-bad-type-heterogeneous.rs @@ -0,0 +1,21 @@ +//@ edition: 2018 + +#![feature(try_blocks_heterogeneous)] + +pub fn main() { + let res = try bikeshed Result { + Err("")?; //~ ERROR `?` couldn't convert the error + 5 + }; + + let res = try bikeshed Result { + "" //~ ERROR type mismatch + }; + + let res = try bikeshed Result { }; //~ ERROR type mismatch + + let res = try bikeshed () { }; + //~^ ERROR a `try` block must return `Result` or `Option` + + let res = try bikeshed i32 { 5 }; //~ ERROR a `try` block must return `Result` or `Option` +} diff --git a/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr new file mode 100644 index 000000000000..4962534cf294 --- /dev/null +++ b/tests/ui/try-block/try-block-bad-type-heterogeneous.stderr @@ -0,0 +1,46 @@ +error[E0277]: `?` couldn't convert the error to `TryFromSliceError` + --> $DIR/try-block-bad-type-heterogeneous.rs:7:16 + | +LL | Err("")?; + | -------^ the trait `From<&str>` is not implemented for `TryFromSliceError` + | | + | this can't be annotated with `?` because it has type `Result<_, &str>` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait +help: the trait `From<&str>` is not implemented for `TryFromSliceError` + but trait `From` is implemented for it + --> $SRC_DIR/core/src/array/mod.rs:LL:COL + = help: for that trait implementation, expected `Infallible`, found `&str` + +error[E0271]: type mismatch resolving ` as Try>::Output == &str` + --> $DIR/try-block-bad-type-heterogeneous.rs:12:9 + | +LL | "" + | ^^ expected `&str`, found `i32` + +error[E0271]: type mismatch resolving ` as Try>::Output == ()` + --> $DIR/try-block-bad-type-heterogeneous.rs:15:47 + | +LL | let res = try bikeshed Result { }; + | ^ expected `()`, found `i32` + +error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`) + --> $DIR/try-block-bad-type-heterogeneous.rs:17:33 + | +LL | let res = try bikeshed () { }; + | ^ could not wrap the final value of the block as `()` doesn't implement `Try` + | + = help: the nightly-only, unstable trait `Try` is not implemented for `()` + +error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`) + --> $DIR/try-block-bad-type-heterogeneous.rs:20:34 + | +LL | let res = try bikeshed i32 { 5 }; + | ^ could not wrap the final value of the block as `i32` doesn't implement `Try` + | + = help: the nightly-only, unstable trait `Try` is not implemented for `i32` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0271, E0277. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr index 9df01a4cf5b1..6f806da088b6 100644 --- a/tests/ui/try-block/try-block-bad-type.stderr +++ b/tests/ui/try-block/try-block-bad-type.stderr @@ -29,7 +29,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th LL | let res: () = try { }; | ^ could not wrap the final value of the block as `()` doesn't implement `Try` | - = help: the trait `Try` is not implemented for `()` + = help: the nightly-only, unstable trait `Try` is not implemented for `()` error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`) --> $DIR/try-block-bad-type.rs:20:26 @@ -37,7 +37,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th LL | let res: i32 = try { 5 }; | ^ could not wrap the final value of the block as `i32` doesn't implement `Try` | - = help: the trait `Try` is not implemented for `i32` + = help: the nightly-only, unstable trait `Try` is not implemented for `i32` error: aborting due to 5 previous errors diff --git a/tests/ui/try-block/try-block-heterogeneous.rs b/tests/ui/try-block/try-block-heterogeneous.rs new file mode 100644 index 000000000000..0b17b7c8655d --- /dev/null +++ b/tests/ui/try-block/try-block-heterogeneous.rs @@ -0,0 +1,19 @@ +//@ check-pass +//@ edition: 2018 + +#![feature(try_blocks_heterogeneous)] + +fn foo() -> Result<(), u16> { Ok(()) } + +fn bar() -> Result<(), u32> { Ok(()) } + +fn whatever() -> Result<(), String> { + try bikeshed _ {} +} + +fn main() { + try bikeshed Result<(), u64> { + foo()?; + bar()?; + }; +} diff --git a/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs b/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs new file mode 100644 index 000000000000..980f97ca0672 --- /dev/null +++ b/tests/ui/try-block/try-block-homogeneous-pre-expansion.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ edition: 2018 + +// For historical reasons this is only a warning, not an error. +// See + +fn main() { + #[cfg(false)] + try {} + //~^ warn `try` blocks are unstable + //~| warn unstable syntax can change at any point +} diff --git a/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr b/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr new file mode 100644 index 000000000000..dc92d7e64aff --- /dev/null +++ b/tests/ui/try-block/try-block-homogeneous-pre-expansion.stderr @@ -0,0 +1,14 @@ +warning: `try` blocks are unstable + --> $DIR/try-block-homogeneous-pre-expansion.rs:9:5 + | +LL | try {} + | ^^^^^^ + | + = note: see issue #31436 for more information + = help: add `#![feature(try_blocks)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = warning: unstable syntax can change at any point in the future, causing a hard error! + = note: for more information, see issue #65860 + +warning: 1 warning emitted + diff --git a/tests/ui/try-block/try-block-in-while.stderr b/tests/ui/try-block/try-block-in-while.stderr index 2760e930102b..6d6917362bc7 100644 --- a/tests/ui/try-block/try-block-in-while.stderr +++ b/tests/ui/try-block/try-block-in-while.stderr @@ -4,7 +4,7 @@ error[E0277]: a `try` block must return `Result` or `Option` (or another type th LL | while try { false } {} | ^^^^^ could not wrap the final value of the block as `bool` doesn't implement `Try` | - = help: the trait `Try` is not implemented for `bool` + = help: the nightly-only, unstable trait `Try` is not implemented for `bool` error: aborting due to 1 previous error diff --git a/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr b/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr index 71c7e460c399..7fe151021976 100644 --- a/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr +++ b/tests/ui/try-block/try-block-maybe-bad-lifetime.stderr @@ -22,7 +22,6 @@ LL | }; LL | println!("{}", x); | ^ value borrowed here after move | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value if the performance cost is acceptable | LL | ::std::mem::drop(x.clone()); diff --git a/tests/ui/try-block/try-block-opt-init.stderr b/tests/ui/try-block/try-block-opt-init.stderr index 1679fc2ac18c..b838af5d53b9 100644 --- a/tests/ui/try-block/try-block-opt-init.stderr +++ b/tests/ui/try-block/try-block-opt-init.stderr @@ -9,8 +9,6 @@ LL | cfg_res = 5; ... LL | assert_eq!(cfg_res, 5); | ^^^^^^^^^^^^^^^^^^^^^^ `cfg_res` used here but it is possibly-uninitialized - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index da5c4d03dccb..a566800da53e 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -13,10 +13,16 @@ help: the following other types implement trait `From` --> $SRC_DIR/core/src/convert/num.rs:LL:COL | = note: `u8` implements `From` + ::: $SRC_DIR/core/src/convert/num.rs:LL:COL + | + = note: in this macro invocation --> $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL | - = note: `u8` implements `From` - = note: this error originates in the macro `impl_from` which comes from the expansion of the macro `into_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: `u8` implements `From` + ::: $SRC_DIR/core/src/ascii/ascii_char.rs:LL:COL + | + = note: in this macro invocation + = note: this error originates in the macro `impl_from_bool` which comes from the expansion of the macro `into_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result` --> $DIR/bad-interconversion.rs:9:12 diff --git a/tests/ui/try-trait/bad-question-mark-on-trait-object.rs b/tests/ui/try-trait/bad-question-mark-on-trait-object.rs index 2a0d14b17503..270ec2c532ac 100644 --- a/tests/ui/try-trait/bad-question-mark-on-trait-object.rs +++ b/tests/ui/try-trait/bad-question-mark-on-trait-object.rs @@ -1,6 +1,5 @@ struct E; //~^ NOTE `E` needs to implement `std::error::Error` -//~| NOTE alternatively, `E` needs to implement `Into` struct X; //~ NOTE `X` needs to implement `From` fn foo() -> Result<(), Box> { //~ NOTE required `E: std::error::Error` because of this diff --git a/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr b/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr index dd380850c9ec..7639489b891a 100644 --- a/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr +++ b/tests/ui/try-trait/bad-question-mark-on-trait-object.stderr @@ -1,5 +1,5 @@ error[E0277]: `?` couldn't convert the error: `E: std::error::Error` is not satisfied - --> $DIR/bad-question-mark-on-trait-object.rs:7:13 + --> $DIR/bad-question-mark-on-trait-object.rs:6:13 | LL | fn foo() -> Result<(), Box> { | -------------------------------------- required `E: std::error::Error` because of this @@ -17,7 +17,7 @@ LL | struct E; = note: required for `Box` to implement `From` error[E0277]: `?` couldn't convert the error to `X` - --> $DIR/bad-question-mark-on-trait-object.rs:18:13 + --> $DIR/bad-question-mark-on-trait-object.rs:17:13 | LL | fn bat() -> Result<(), X> { | ------------- expected `X` because of this @@ -27,15 +27,10 @@ LL | Ok(bar()?) | this can't be annotated with `?` because it has type `Result<_, E>` | note: `X` needs to implement `From` - --> $DIR/bad-question-mark-on-trait-object.rs:4:1 + --> $DIR/bad-question-mark-on-trait-object.rs:3:1 | LL | struct X; | ^^^^^^^^ -note: alternatively, `E` needs to implement `Into` - --> $DIR/bad-question-mark-on-trait-object.rs:1:1 - | -LL | struct E; - | ^^^^^^^^ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait error: aborting due to 2 previous errors diff --git a/tests/ui/try-trait/try-operator-on-main.stderr b/tests/ui/try-trait/try-operator-on-main.stderr index 9c2526442ab5..d58720638aec 100644 --- a/tests/ui/try-trait/try-operator-on-main.stderr +++ b/tests/ui/try-trait/try-operator-on-main.stderr @@ -22,7 +22,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | ()?; | ^^^ the `?` operator cannot be applied to type `()` | - = help: the trait `Try` is not implemented for `()` + = help: the nightly-only, unstable trait `Try` is not implemented for `()` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-operator-on-main.rs:10:7 @@ -37,7 +37,7 @@ error[E0277]: the trait bound `(): Try` is not satisfied --> $DIR/try-operator-on-main.rs:14:25 | LL | try_trait_generic::<()>(); - | ^^ the trait `Try` is not implemented for `()` + | ^^ the nightly-only, unstable trait `Try` is not implemented for `()` | note: required by a bound in `try_trait_generic` --> $DIR/try-operator-on-main.rs:17:25 @@ -51,7 +51,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | ()?; | ^^^ the `?` operator cannot be applied to type `()` | - = help: the trait `Try` is not implemented for `()` + = help: the nightly-only, unstable trait `Try` is not implemented for `()` error: aborting due to 5 previous errors diff --git a/tests/ui/tuple/builtin-fail.stderr b/tests/ui/tuple/builtin-fail.stderr index 44e79578f4c9..5e84dbff454d 100644 --- a/tests/ui/tuple/builtin-fail.stderr +++ b/tests/ui/tuple/builtin-fail.stderr @@ -2,7 +2,7 @@ error[E0277]: `T` is not a tuple --> $DIR/builtin-fail.rs:8:23 | LL | assert_is_tuple::(); - | ^ the trait `Tuple` is not implemented for `T` + | ^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `T` | note: required by a bound in `assert_is_tuple` --> $DIR/builtin-fail.rs:3:23 @@ -18,7 +18,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/builtin-fail.rs:13:23 | LL | assert_is_tuple::(); - | ^^^ the trait `Tuple` is not implemented for `i32` + | ^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `assert_is_tuple` --> $DIR/builtin-fail.rs:3:23 @@ -30,7 +30,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/builtin-fail.rs:15:24 | LL | assert_is_tuple::<(i32)>(); - | ^^^ the trait `Tuple` is not implemented for `i32` + | ^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `assert_is_tuple` --> $DIR/builtin-fail.rs:3:23 @@ -44,7 +44,7 @@ error[E0277]: `TupleStruct` is not a tuple LL | assert_is_tuple::(); | ^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `Tuple` is not implemented for `TupleStruct` +help: the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `TupleStruct` --> $DIR/builtin-fail.rs:5:1 | LL | struct TupleStruct(i32, i32); diff --git a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr index 7219fda4772a..6f0c6bb22060 100644 --- a/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr +++ b/tests/ui/type-alias-impl-trait/bound-lifetime-through-dyn-trait.stderr @@ -1,8 +1,8 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/bound-lifetime-through-dyn-trait.rs:6:71 + --> $DIR/bound-lifetime-through-dyn-trait.rs:6:57 | LL | fn dyn_hoops() -> dyn for<'a> Iterator> { - | ^^ + | ^^^^^^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/bound-lifetime-through-dyn-trait.rs:6:37 diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index 31bdd0815ec3..4b17448080ed 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -8,7 +8,6 @@ trait Test<'a> {} pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` -//~| ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` impl Trait<'_> for () { type Assoc = (); diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr index c9f0618639af..cdbcfa6f3dc9 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -2,7 +2,7 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `imp --> $DIR/escaping-bound-var.rs:9:47 | LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^^^^^^^^^^^^ `impl Trait` implicitly captures all lifetimes in scope + | ^^^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/escaping-bound-var.rs:9:25 @@ -10,18 +10,6 @@ note: lifetime declared here LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; | ^^ -error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/escaping-bound-var.rs:9:57 - | -LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^ - | -note: lifetime declared here - --> $DIR/escaping-bound-var.rs:9:25 - | -LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 2aacf9698379..87313e349524 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -18,10 +18,10 @@ LL | call(operation).await | ^^^^^^^^^^^^^^^ expected `{async fn body of operation()}`, got `FutNothing<'_>` | note: previous use here - --> $DIR/hkl_forbidden4.rs:12:1 + --> $DIR/hkl_forbidden4.rs:12:35 | LL | async fn operation(_: &mut ()) -> () { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^ error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr index 7311f5882f75..bbc0b91cd503 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr @@ -28,7 +28,7 @@ error[E0310]: the parameter type `A` may not live long enough --> $DIR/implied_lifetime_wf_check3.rs:55:5 | LL | test_type_param::assert_static::() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | the parameter type `A` must be valid for the static lifetime... | ...so that the type `A` will meet its required lifetime bounds diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr index 3cec4bbb0993..710e4a5ce9e8 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr @@ -21,7 +21,7 @@ error[E0310]: the parameter type `A` may not live long enough --> $DIR/implied_lifetime_wf_check4_static.rs:15:5 | LL | assert_static::() - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | | | the parameter type `A` must be valid for the static lifetime... | ...so that the type `A` will meet its required lifetime bounds diff --git a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.edition2024.stderr b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.edition2024.stderr index a7135e8f05f4..da2099c1ed27 100644 --- a/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.edition2024.stderr +++ b/tests/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.edition2024.stderr @@ -35,7 +35,6 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has | LL | let mut thing = test(&mut z); | ^^^^^^^^^^^^ - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the precise capturing `use<...>` syntax to make the captures explicit | LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + use<> { @@ -57,7 +56,6 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has | LL | let mut thing = test(&mut z); | ^^^^^^^^^^^^ - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the precise capturing `use<...>` syntax to make the captures explicit | LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + use<> { @@ -79,7 +77,6 @@ note: this call may capture more lifetimes than intended, because Rust 2024 has | LL | let mut thing = test(&mut z); | ^^^^^^^^^^^^ - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: use the precise capturing `use<...>` syntax to make the captures explicit | LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + use<> { diff --git a/tests/ui/type-alias-impl-trait/issue-60662.stdout b/tests/ui/type-alias-impl-trait/issue-60662.stdout index 7ad29c88bcfe..dff748b43119 100644 --- a/tests/ui/type-alias-impl-trait/issue-60662.stdout +++ b/tests/ui/type-alias-impl-trait/issue-60662.stdout @@ -3,9 +3,8 @@ //@ edition: 2015 #![feature(type_alias_impl_trait)] -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; trait Animal { } diff --git a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs index 7f0f6a214aae..383d9108eb90 100644 --- a/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs +++ b/tests/ui/type-alias-impl-trait/issue-96572-unconstrained.rs @@ -23,15 +23,6 @@ fn upvar() { }; } -fn enum_upvar() { - type T = impl Copy; - let foo: T = Some((1u32, 2u32)); - let x = move || match foo { - None => (), - Some((a, b)) => (), - }; -} - fn r#struct() { #[derive(Copy, Clone)] struct Foo((u32, u32)); diff --git a/tests/ui/type-alias-impl-trait/nested.stderr b/tests/ui/type-alias-impl-trait/nested.stderr index f72830b864d1..9ac0fe5302be 100644 --- a/tests/ui/type-alias-impl-trait/nested.stderr +++ b/tests/ui/type-alias-impl-trait/nested.stderr @@ -20,7 +20,6 @@ LL | println!("{:?}", bar()); | required by this formatting parameter | = help: the trait `Debug` is not implemented for `Bar` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/opaque-alias-relate-issue-151331.rs b/tests/ui/type-alias-impl-trait/opaque-alias-relate-issue-151331.rs new file mode 100644 index 000000000000..684f2498d584 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/opaque-alias-relate-issue-151331.rs @@ -0,0 +1,10 @@ +//@ compile-flags: -Znext-solver=globally +#![feature(type_alias_impl_trait)] + +type Foo = Vec; + +#[define_opaque(Foo)] +fn make_foo() -> Foo {} +//~^ ERROR type mismatch resolving + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/opaque-alias-relate-issue-151331.stderr b/tests/ui/type-alias-impl-trait/opaque-alias-relate-issue-151331.stderr new file mode 100644 index 000000000000..dd73ed1a247c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/opaque-alias-relate-issue-151331.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `Foo == ()` + --> $DIR/opaque-alias-relate-issue-151331.rs:7:18 + | +LL | fn make_foo() -> Foo {} + | ^^^ types differ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr index 2855c90234d2..ca26e3dd03f3 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -9,6 +9,9 @@ LL | 42_i32 help: the trait `PartialEq` is not implemented for `i32` but trait `PartialEq` is implemented for it --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index 83fed16c0a17..8592de243ada 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -10,6 +10,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/self-referential-4.stderr b/tests/ui/type-alias-impl-trait/self-referential-4.stderr index 4176bf780294..c6bf1973fcbb 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-4.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-4.stderr @@ -9,6 +9,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `Foo<'static, 'b>` @@ -22,6 +25,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `Moo<'static, 'a>` @@ -35,6 +41,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/self-referential.stderr b/tests/ui/type-alias-impl-trait/self-referential.stderr index dc5b9ba7b442..7b4e6e9cac52 100644 --- a/tests/ui/type-alias-impl-trait/self-referential.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential.stderr @@ -10,6 +10,9 @@ LL | i = help: the trait `PartialEq>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)` @@ -24,6 +27,9 @@ LL | (42, i) = help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)` @@ -38,6 +44,9 @@ LL | (42, i) = help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)>` is not implemented for `&i32` help: the trait `PartialEq` is implemented for `i32` --> $SRC_DIR/core/src/cmp.rs:LL:COL + ::: $SRC_DIR/core/src/cmp.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `partial_eq_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr index 1cb33eabd902..e5c35d58b72d 100644 --- a/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr +++ b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr @@ -2,10 +2,16 @@ error[E0425]: cannot find function `value` in this scope --> $DIR/type-error-drop-elaboration.rs:12:5 | LL | value() - | ^^^^^ help: a constant with a similar name exists: `VALUE` + | ^^^^^ ... LL | const VALUE: Foo = foo(); | ------------------------- similarly named constant `VALUE` defined here + | +help: a constant with a similar name exists + | +LL - value() +LL + VALUE() + | error: aborting due to 1 previous error diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed new file mode 100644 index 000000000000..ba94e1967df3 --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.fixed @@ -0,0 +1,39 @@ +//@ run-rustfix +type T = dyn core::fmt::Debug; +//~^ NOTE this type alias is unsized +//~| NOTE this type alias is unsized +//~| NOTE this type alias is unsized + +fn f() -> Box { loop {} } +//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` +//~| NOTE doesn't have a size known at compile-time +//~| NOTE the return type of a function must have a statically known size +//~| HELP consider boxing the return type + +trait X { + fn f(&self) -> Box { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +impl X for () { + fn f(&self) -> Box { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +fn main() { + f(); + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + ().f(); +} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs new file mode 100644 index 000000000000..76f6e7c44342 --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.rs @@ -0,0 +1,39 @@ +//@ run-rustfix +type T = dyn core::fmt::Debug; +//~^ NOTE this type alias is unsized +//~| NOTE this type alias is unsized +//~| NOTE this type alias is unsized + +fn f() -> T { loop {} } +//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +//~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` +//~| NOTE doesn't have a size known at compile-time +//~| NOTE the return type of a function must have a statically known size +//~| HELP consider boxing the return type + +trait X { + fn f(&self) -> T { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +impl X for () { + fn f(&self) -> T { loop {} } + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + //~| HELP consider boxing the return type +} + +fn main() { + f(); + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + //~| HELP the trait `Sized` is not implemented for `(dyn Debug + 'static)` + //~| NOTE doesn't have a size known at compile-time + //~| NOTE the return type of a function must have a statically known size + ().f(); +} diff --git a/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr new file mode 100644 index 000000000000..bb6951687048 --- /dev/null +++ b/tests/ui/type-alias/dyn-trait-type-alias-return-type.stderr @@ -0,0 +1,66 @@ +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:7:11 + | +LL | fn f() -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f() -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:24:20 + | +LL | fn f(&self) -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f(&self) -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:15:20 + | +LL | fn f(&self) -> T { loop {} } + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: this type alias is unsized + --> $DIR/dyn-trait-type-alias-return-type.rs:2:1 + | +LL | type T = dyn core::fmt::Debug; + | ^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` + | +LL | fn f(&self) -> Box { loop {} } + | ++++ + + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-type-alias-return-type.rs:33:5 + | +LL | f(); + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` + = note: the return type of a function must have a statically known size + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias/issue-62263-self-in-atb.rs b/tests/ui/type-alias/issue-62263-self-in-atb.rs index 91522d8912f7..0f8d88310bcd 100644 --- a/tests/ui/type-alias/issue-62263-self-in-atb.rs +++ b/tests/ui/type-alias/issue-62263-self-in-atb.rs @@ -3,6 +3,6 @@ pub trait Trait { } pub type Alias = dyn Trait; -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find `Self` fn main() {} diff --git a/tests/ui/type-alias/issue-62263-self-in-atb.stderr b/tests/ui/type-alias/issue-62263-self-in-atb.stderr index 18c8bc1a1b36..aa9e37ce71c7 100644 --- a/tests/ui/type-alias/issue-62263-self-in-atb.stderr +++ b/tests/ui/type-alias/issue-62263-self-in-atb.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find `Self` in this scope --> $DIR/issue-62263-self-in-atb.rs:5:32 | LL | pub type Alias = dyn Trait; diff --git a/tests/ui/type-alias/issue-62305-self-assoc-ty.rs b/tests/ui/type-alias/issue-62305-self-assoc-ty.rs index a4d9a285485e..47a6838c9100 100644 --- a/tests/ui/type-alias/issue-62305-self-assoc-ty.rs +++ b/tests/ui/type-alias/issue-62305-self-assoc-ty.rs @@ -1,4 +1,4 @@ type Alias = Self::Target; -//~^ ERROR failed to resolve: `Self` +//~^ ERROR cannot find `Self` fn main() {} diff --git a/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr b/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr index a35e644d3aa8..5bec48f007ca 100644 --- a/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr +++ b/tests/ui/type-alias/issue-62305-self-assoc-ty.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions +error[E0433]: cannot find `Self` in this scope --> $DIR/issue-62305-self-assoc-ty.rs:1:14 | LL | type Alias = Self::Target; diff --git a/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.stderr b/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.stderr index 73afefa5a1fd..c198b83e9688 100644 --- a/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.stderr +++ b/tests/ui/type-alias/missing-associated-type-in-trait-object-22434.stderr @@ -5,7 +5,7 @@ LL | type A; | ------ `A` defined here ... LL | type I<'a> = &'a (dyn Foo + 'a); - | ^^^ help: specify the associated type: `Foo` + | ^^^ help: specify the associated type: `Foo` error: aborting due to 1 previous error diff --git a/tests/ui/type-alias/unused_type_parameter.rs b/tests/ui/type-alias/unused_type_parameter.rs new file mode 100644 index 000000000000..64fb98be1bf7 --- /dev/null +++ b/tests/ui/type-alias/unused_type_parameter.rs @@ -0,0 +1,4 @@ +//! regression test for +trait Tr {} +type Huh where T: Tr = isize; //~ ERROR type parameter `T` is never used +fn main() {} diff --git a/tests/ui/type-alias/unused_type_parameter.stderr b/tests/ui/type-alias/unused_type_parameter.stderr new file mode 100644 index 000000000000..a9ddbc8c5001 --- /dev/null +++ b/tests/ui/type-alias/unused_type_parameter.stderr @@ -0,0 +1,11 @@ +error[E0091]: type parameter `T` is never used + --> $DIR/unused_type_parameter.rs:3:10 + | +LL | type Huh where T: Tr = isize; + | ^ unused type parameter + | + = help: consider removing `T` or referring to it in the body of the type alias + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0091`. diff --git a/tests/ui/type-inference/box_has_sigdrop.rs b/tests/ui/type-inference/box_has_sigdrop.rs index 3e801197a78e..2d1b1cd0249e 100644 --- a/tests/ui/type-inference/box_has_sigdrop.rs +++ b/tests/ui/type-inference/box_has_sigdrop.rs @@ -1,4 +1,4 @@ -//@ should-fail +//@ known-bug: unknown //@ compile-flags: -Wrust-2021-incompatible-closure-captures // Inference, canonicalization, and significant drops should work nicely together. // Related issue: #86868 diff --git a/tests/ui/type-inference/panic-with-unspecified-type.rs b/tests/ui/type-inference/panic-with-unspecified-type.rs new file mode 100644 index 000000000000..0f96759e8144 --- /dev/null +++ b/tests/ui/type-inference/panic-with-unspecified-type.rs @@ -0,0 +1,6 @@ +//! regression test for +//@ edition:2015..2021 +fn main() { + panic!(std::default::Default::default()); + //~^ ERROR type annotations needed +} diff --git a/tests/ui/type-inference/panic-with-unspecified-type.stderr b/tests/ui/type-inference/panic-with-unspecified-type.stderr new file mode 100644 index 000000000000..cd8485f392bc --- /dev/null +++ b/tests/ui/type-inference/panic-with-unspecified-type.stderr @@ -0,0 +1,16 @@ +error[E0283]: type annotations needed + --> $DIR/panic-with-unspecified-type.rs:4:12 + | +LL | panic!(std::default::Default::default()); + | -------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | | + | | cannot infer type + | required by a bound introduced by this call + | + = note: cannot satisfy `_: Any` +note: required by a bound in `std::rt::begin_panic` + --> $SRC_DIR/std/src/panicking.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/type-inference/send-with-unspecified-type.rs b/tests/ui/type-inference/send-with-unspecified-type.rs new file mode 100644 index 000000000000..4c2de025d69c --- /dev/null +++ b/tests/ui/type-inference/send-with-unspecified-type.rs @@ -0,0 +1,16 @@ +//! regression test for + +use std::sync::mpsc::channel; +use std::thread::spawn; +use std::marker::PhantomData; + +struct Foo {foo: PhantomData} + +fn main() { + let (tx, rx) = + channel(); + spawn(move || { + tx.send(Foo{ foo: PhantomData }); + //~^ ERROR type annotations needed + }); +} diff --git a/tests/ui/type-inference/send-with-unspecified-type.stderr b/tests/ui/type-inference/send-with-unspecified-type.stderr new file mode 100644 index 000000000000..85692e8ad0cd --- /dev/null +++ b/tests/ui/type-inference/send-with-unspecified-type.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/send-with-unspecified-type.rs:13:27 + | +LL | tx.send(Foo{ foo: PhantomData }); + | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` + | +help: consider specifying the generic argument + | +LL | tx.send(Foo{ foo: PhantomData:: }); + | +++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type-inference/swap-with-unspecified-type.rs b/tests/ui/type-inference/swap-with-unspecified-type.rs new file mode 100644 index 000000000000..db415df19e99 --- /dev/null +++ b/tests/ui/type-inference/swap-with-unspecified-type.rs @@ -0,0 +1,9 @@ +//! regression test for + +fn main() { + use std::mem::{transmute, swap}; + let a = 1; + let b = 2; + unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; + //~^ ERROR type annotations needed +} diff --git a/tests/ui/type-inference/swap-with-unspecified-type.stderr b/tests/ui/type-inference/swap-with-unspecified-type.stderr new file mode 100644 index 000000000000..eaaed559ebf1 --- /dev/null +++ b/tests/ui/type-inference/swap-with-unspecified-type.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/swap-with-unspecified-type.rs:7:13 + | +LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; + | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type/binding-assigned-block-without-tail-expression.stderr b/tests/ui/type/binding-assigned-block-without-tail-expression.stderr index ff34facf3892..ed7ff22e501c 100644 --- a/tests/ui/type/binding-assigned-block-without-tail-expression.stderr +++ b/tests/ui/type/binding-assigned-block-without-tail-expression.stderr @@ -11,7 +11,6 @@ LL | println!("{}", x); | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/binding-assigned-block-without-tail-expression.rs:15:20 @@ -26,7 +25,6 @@ LL | println!("{}", y); | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/binding-assigned-block-without-tail-expression.rs:16:20 @@ -41,7 +39,6 @@ LL | println!("{}", z); | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `()` doesn't implement `std::fmt::Display` --> $DIR/binding-assigned-block-without-tail-expression.rs:17:20 @@ -59,7 +56,6 @@ LL | println!("{}", s); | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/binding-assigned-block-without-tail-expression.rs:18:18 diff --git a/tests/ui/type/issue-7607-1.stderr b/tests/ui/type/issue-7607-1.stderr index ac6034da75f1..8edd0d31d791 100644 --- a/tests/ui/type/issue-7607-1.stderr +++ b/tests/ui/type/issue-7607-1.stderr @@ -2,11 +2,16 @@ error[E0425]: cannot find type `Fo` in this scope --> $DIR/issue-7607-1.rs:5:6 | LL | impl Fo { - | ^^ help: a trait with a similar name exists: `Fn` + | ^^ | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | = note: similarly named trait `Fn` defined here +help: a trait with a similar name exists + | +LL - impl Fo { +LL + impl Fn { + | error: aborting due to 1 previous error diff --git a/tests/ui/type/never-type-inference-fail.rs b/tests/ui/type/never-type-inference-fail.rs new file mode 100644 index 000000000000..76ee3c5f5d56 --- /dev/null +++ b/tests/ui/type/never-type-inference-fail.rs @@ -0,0 +1,6 @@ +//! regression test for issue #2151 + +fn main() { + let x = panic!(); //~ ERROR type annotations needed + x.clone(); +} diff --git a/tests/ui/type/never-type-inference-fail.stderr b/tests/ui/type/never-type-inference-fail.stderr new file mode 100644 index 000000000000..1d2457103f1c --- /dev/null +++ b/tests/ui/type/never-type-inference-fail.stderr @@ -0,0 +1,16 @@ +error[E0282]: type annotations needed + --> $DIR/never-type-inference-fail.rs:4:9 + | +LL | let x = panic!(); + | ^ +LL | x.clone(); + | - type must be known at this point + | +help: consider giving `x` an explicit type + | +LL | let x: /* Type */ = panic!(); + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs deleted file mode 100644 index ff99ac98926c..000000000000 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@known-bug: #127972 -//@ failure-status: 101 -//@ normalize-stderr: "note: .*\n\n" -> "" -//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> "" -//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@ rustc-env:RUST_BACKTRACE=0 - -#![feature(pattern_types, pattern_type_macro, generic_const_exprs)] -#![allow(internal_features)] - -type Pat = - std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>); - -fn main() {} diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr deleted file mode 100644 index ffc6068eb17e..000000000000 --- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.stderr +++ /dev/null @@ -1,21 +0,0 @@ -warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad_const_generics_args_on_const_param.rs:8:47 - | -LL | #![feature(pattern_types, pattern_type_macro, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #76560 for more information - = error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible - --> $DIR/bad_const_generics_args_on_const_param.rs:12:36 - | -LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>); - | ^^^^^^^^^^^^^^^^^^^ - - -Box -query stack during panic: -#0 [type_of] expanding type alias `Pat` -#1 [check_well_formed] checking that `Pat` is well-formed -... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/type/pattern_types/derives_fail.stderr b/tests/ui/type/pattern_types/derives_fail.stderr index 6b2e27494f0e..45c9bae1f280 100644 --- a/tests/ui/type/pattern_types/derives_fail.stderr +++ b/tests/ui/type/pattern_types/derives_fail.stderr @@ -16,7 +16,7 @@ LL | #[repr(transparent)] LL | struct Nanoseconds(NanoI32); | ^^^^^^^ the trait `Eq` is not implemented for `(i32) is 0..=999999999` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: `(i32) is 0..=999999999` doesn't implement `Debug` diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr index bb206d9db3db..7893cc849248 100644 --- a/tests/ui/type/pattern_types/nested.stderr +++ b/tests/ui/type/pattern_types/nested.stderr @@ -13,7 +13,7 @@ error[E0277]: `(u32) is 1..` is not a valid base type for range patterns LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(u32) is 1..` + = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(u32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -31,7 +31,7 @@ error[E0277]: `(i32) is 1..` is not a valid base type for range patterns LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` + = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -55,7 +55,7 @@ error[E0277]: `(i32) is 1..` is not a valid base type for range patterns LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` + = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -92,7 +92,7 @@ error[E0277]: `(i32) is 1..` is not a valid base type for range patterns LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!(); | ^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` + = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `(i32) is 1..` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -110,7 +110,7 @@ error[E0277]: `()` is not a valid base type for range patterns LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); | ^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `()` + = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `()` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -145,7 +145,7 @@ error[E0277]: `()` is not a valid base type for range patterns LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!(); | ^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `()` + = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `()` = help: the following other types implement trait `core::pat::RangePattern`: char i128 @@ -163,7 +163,7 @@ error[E0277]: `f32` is not a valid base type for range patterns LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!(); | ^^^ only integer types and `char` are supported | - = help: the trait `core::pat::RangePattern` is not implemented for `f32` + = help: the nightly-only, unstable trait `core::pat::RangePattern` is not implemented for `f32` = help: the following other types implement trait `core::pat::RangePattern`: i128 i16 diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index ad61e9a59147..0847af2d086f 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -17,7 +17,7 @@ error: layout_of((*const T) is !null) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -64,7 +64,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -96,7 +96,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -126,7 +126,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -186,7 +186,7 @@ error: layout_of((*const [u8]) is !null) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr index adc7320829b9..7206c570187b 100644 --- a/tests/ui/type/pattern_types/or_patterns.stderr +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -57,7 +57,7 @@ error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -102,7 +102,7 @@ error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index c9a846e22f58..6c9acac7eb7b 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -16,7 +16,7 @@ error: layout_of(NonZero) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -61,7 +61,7 @@ error: layout_of((u32) is 1..) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -106,7 +106,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -137,7 +137,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -166,7 +166,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -217,7 +217,7 @@ error: layout_of(Option>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -248,7 +248,7 @@ error: layout_of(Option>) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -277,7 +277,7 @@ error: layout_of(Option>) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -328,7 +328,7 @@ error: layout_of(NonZeroU32New) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -401,7 +401,7 @@ error: layout_of((i8) is -10..=10) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -446,7 +446,7 @@ error: layout_of((i8) is i8::MIN..=0) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, diff --git a/tests/ui/type/recover-from-semicolon-trailing-undefined.rs b/tests/ui/type/recover-from-semicolon-trailing-undefined.rs new file mode 100644 index 000000000000..3e2860eb1343 --- /dev/null +++ b/tests/ui/type/recover-from-semicolon-trailing-undefined.rs @@ -0,0 +1,12 @@ +//@ compile-flags: -Znext-solver=globally + +// Regression test for https://github.com/rust-lang/rust/issues/151610 + +fn main() { + let x_str = { + x!("{}", x); + //~^ ERROR cannot find macro `x` in this scope + }; + println!("{}", x_str); + //~^ ERROR `()` doesn't implement `std::fmt::Display` +} diff --git a/tests/ui/type/recover-from-semicolon-trailing-undefined.stderr b/tests/ui/type/recover-from-semicolon-trailing-undefined.stderr new file mode 100644 index 000000000000..6a8295d49338 --- /dev/null +++ b/tests/ui/type/recover-from-semicolon-trailing-undefined.stderr @@ -0,0 +1,26 @@ +error: cannot find macro `x` in this scope + --> $DIR/recover-from-semicolon-trailing-undefined.rs:7:9 + | +LL | x!("{}", x); + | ^ + +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/recover-from-semicolon-trailing-undefined.rs:10:20 + | +LL | let x_str = { + | _________________- +LL | | x!("{}", x); +LL | | +LL | | }; + | |_____- this block is missing a tail expression +LL | println!("{}", x_str); + | -- ^^^^^ `()` cannot be formatted with the default formatter + | | + | required by this formatting parameter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type/struct-constructor-as-value.rs b/tests/ui/type/struct-constructor-as-value.rs new file mode 100644 index 000000000000..9cac1caf86ec --- /dev/null +++ b/tests/ui/type/struct-constructor-as-value.rs @@ -0,0 +1,7 @@ +//! regression test for + +struct Foo(u32); + +fn test() -> Foo { Foo } //~ ERROR mismatched types + +fn main() {} diff --git a/tests/ui/type/struct-constructor-as-value.stderr b/tests/ui/type/struct-constructor-as-value.stderr new file mode 100644 index 000000000000..5915f971b324 --- /dev/null +++ b/tests/ui/type/struct-constructor-as-value.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/struct-constructor-as-value.rs:5:20 + | +LL | struct Foo(u32); + | ---------- `Foo` defines a struct constructor here, which should be called +LL | +LL | fn test() -> Foo { Foo } + | --- ^^^ expected `Foo`, found struct constructor + | | + | expected `Foo` because of return type + | + = note: expected struct `Foo` + found struct constructor `fn(u32) -> Foo {Foo}` +help: use parentheses to construct this tuple struct + | +LL | fn test() -> Foo { Foo(/* u32 */) } + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type/type-check-defaults.stderr b/tests/ui/type/type-check-defaults.stderr index 4eab611244a6..a3a2ed5aa725 100644 --- a/tests/ui/type/type-check-defaults.stderr +++ b/tests/ui/type/type-check-defaults.stderr @@ -86,13 +86,19 @@ LL | trait ProjectionPred> where T::Item : Add {} help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` note: required by a bound in `ProjectionPred` --> $DIR/type-check-defaults.rs:24:66 | diff --git a/tests/ui/type/type-parameter-defaults-referencing-Self.stderr b/tests/ui/type/type-parameter-defaults-referencing-Self.stderr index 23f10c9262c7..300ad1998e42 100644 --- a/tests/ui/type/type-parameter-defaults-referencing-Self.stderr +++ b/tests/ui/type/type-parameter-defaults-referencing-Self.stderr @@ -7,11 +7,11 @@ LL | trait Foo { LL | fn foo(x: &dyn Foo) { } | ^^^ | - = note: because the parameter default references `Self`, the parameter must be specified on the object type -help: set the type parameter to the desired type + = note: because the parameter default references `Self`, the parameter must be specified on the trait object type +help: explicitly specify the type parameter | -LL | fn foo(x: &dyn Foo) { } - | +++ +LL | fn foo(x: &dyn Foo) { } + | +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/type/type-parameter-names.rs b/tests/ui/type/type-parameter-names.rs index fbd1885f543f..0b427314f133 100644 --- a/tests/ui/type/type-parameter-names.rs +++ b/tests/ui/type/type-parameter-names.rs @@ -1,14 +1,24 @@ // Test that we print out the names of type parameters correctly in // our error messages. +// related issue //@ dont-require-annotations: NOTE fn foo(x: Foo) -> Bar { x -//~^ ERROR mismatched types -//~| NOTE expected type parameter `Bar`, found type parameter `Foo` -//~| NOTE expected type parameter `Bar` -//~| NOTE found type parameter `Foo` + //~^ ERROR mismatched types + //~| NOTE expected type parameter `Bar`, found type parameter `Foo` + //~| NOTE expected type parameter `Bar` + //~| NOTE found type parameter `Foo` +} + +fn bar(x: Foo, y: Bar) { + let mut xx = x; + xx = y; + //~^ ERROR mismatched types + //~| NOTE expected type parameter `Foo`, found type parameter `Bar` + //~| NOTE expected type parameter `Foo` + //~| NOTE found type parameter `Bar` } fn main() {} diff --git a/tests/ui/type/type-parameter-names.stderr b/tests/ui/type/type-parameter-names.stderr index 795a260688c4..f84449ef0d36 100644 --- a/tests/ui/type/type-parameter-names.stderr +++ b/tests/ui/type/type-parameter-names.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-parameter-names.rs:7:5 + --> $DIR/type-parameter-names.rs:8:5 | LL | fn foo(x: Foo) -> Bar { | --- --- --- expected `Bar` because of return type @@ -15,6 +15,23 @@ LL | x = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters = note: the caller chooses a type for `Bar` which can be different from `Foo` -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/type-parameter-names.rs:17:10 + | +LL | fn bar(x: Foo, y: Bar) { + | --- --- found type parameter + | | + | expected type parameter +LL | let mut xx = x; + | - expected due to this value +LL | xx = y; + | ^ expected type parameter `Foo`, found type parameter `Bar` + | + = note: expected type parameter `Foo` + found type parameter `Bar` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type/type-path-err-node-types.rs b/tests/ui/type/type-path-err-node-types.rs index b3795772e6fe..a4ff4f497b47 100644 --- a/tests/ui/type/type-path-err-node-types.rs +++ b/tests/ui/type/type-path-err-node-types.rs @@ -12,7 +12,7 @@ fn ufcs_trait() { } fn ufcs_item() { - NonExistent::Assoc::; //~ ERROR undeclared type `NonExistent` + NonExistent::Assoc::; //~ ERROR cannot find type `NonExistent` } fn method() { diff --git a/tests/ui/type/type-path-err-node-types.stderr b/tests/ui/type/type-path-err-node-types.stderr index a9e999f80b3a..d03d5d0b55c9 100644 --- a/tests/ui/type/type-path-err-node-types.stderr +++ b/tests/ui/type/type-path-err-node-types.stderr @@ -16,7 +16,7 @@ error[E0425]: cannot find value `nonexistent` in this scope LL | nonexistent.nonexistent::(); | ^^^^^^^^^^^ not found in this scope -error[E0433]: failed to resolve: use of undeclared type `NonExistent` +error[E0433]: cannot find type `NonExistent` in this scope --> $DIR/type-path-err-node-types.rs:15:5 | LL | NonExistent::Assoc::; diff --git a/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr b/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr index 31acc5bb10ec..b4bf0e00cfe2 100644 --- a/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr +++ b/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr @@ -14,8 +14,6 @@ error[E0308]: mismatched types | LL | b"abc".iter().for_each(|x| dbg!(x)); | ^^^^^^^ expected `()`, found `&u8` - | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/closure-ty-mismatch-issue-128561.rs:8:9 diff --git a/tests/ui/typeck/for-in-const-eval.rs b/tests/ui/typeck/for-in-const-eval.rs new file mode 100644 index 000000000000..f187a9ef3077 --- /dev/null +++ b/tests/ui/typeck/for-in-const-eval.rs @@ -0,0 +1,5 @@ +//! regression test for issue +fn main() { + Vec::<[(); 1 + for x in 0..1 {}]>::new(); + //~^ ERROR cannot add +} diff --git a/tests/ui/typeck/for-in-const-eval.stderr b/tests/ui/typeck/for-in-const-eval.stderr new file mode 100644 index 000000000000..e7a255849581 --- /dev/null +++ b/tests/ui/typeck/for-in-const-eval.stderr @@ -0,0 +1,21 @@ +error[E0277]: cannot add `()` to `{integer}` + --> $DIR/for-in-const-eval.rs:3:18 + | +LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); + | ^ no implementation for `{integer} + ()` + | + = help: the trait `Add<()>` is not implemented for `{integer}` + = help: the following other types implement trait `Add`: + `&f128` implements `Add` + `&f128` implements `Add` + `&f16` implements `Add` + `&f16` implements `Add` + `&f32` implements `Add` + `&f32` implements `Add` + `&f64` implements `Add` + `&f64` implements `Add` + and 56 others + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/issue-100164.stderr b/tests/ui/typeck/issue-100164.stderr deleted file mode 100644 index 06a132d65142..000000000000 --- a/tests/ui/typeck/issue-100164.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: missing type for `const` item - --> $DIR/issue-100164.rs:3:10 - | -LL | const _A: = 123; - | ^ help: provide a type for the constant: `i32` - -error: missing type for `const` item - --> $DIR/issue-100164.rs:7:14 - | -LL | const _B: = 123; - | ^ help: provide a type for the constant: `i32` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/typeck/issue-105946.stderr b/tests/ui/typeck/issue-105946.stderr index 30fe2000a461..3f8733bda763 100644 --- a/tests/ui/typeck/issue-105946.stderr +++ b/tests/ui/typeck/issue-105946.stderr @@ -4,10 +4,16 @@ error[E0425]: cannot find value `_y` in this scope LL | let [_y..] = [Box::new(1), Box::new(2)]; | ^^ not found in this scope | + = note: range patterns match against the start and end of a range; to bind the components, use a struct pattern help: if you meant to collect the rest of the slice in `_y`, use the at operator | LL | let [_y @ ..] = [Box::new(1), Box::new(2)]; | + +help: if you meant to destructure a range use a struct pattern + | +LL - let [_y..] = [Box::new(1), Box::new(2)]; +LL + let [std::ops::RangeFrom { start: _y }] = [Box::new(1), Box::new(2)]; + | error[E0658]: `X..` patterns in slices are experimental --> $DIR/issue-105946.rs:7:10 diff --git a/tests/ui/typeck/issue-10969.rs b/tests/ui/typeck/issue-10969.rs deleted file mode 100644 index 0b78fc1bb7fa..000000000000 --- a/tests/ui/typeck/issue-10969.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn func(i: i32) { - i(); //~ERROR expected function, found `i32` -} -fn main() { - let i = 0i32; - i(); //~ERROR expected function, found `i32` -} diff --git a/tests/ui/typeck/issue-10969.stderr b/tests/ui/typeck/issue-10969.stderr deleted file mode 100644 index f64b61aaeb05..000000000000 --- a/tests/ui/typeck/issue-10969.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0618]: expected function, found `i32` - --> $DIR/issue-10969.rs:2:5 - | -LL | fn func(i: i32) { - | - `i` has type `i32` -LL | i(); - | ^-- - | | - | call expression requires function - -error[E0618]: expected function, found `i32` - --> $DIR/issue-10969.rs:6:5 - | -LL | let i = 0i32; - | - `i` has type `i32` -LL | i(); - | ^-- - | | - | call expression requires function - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr b/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr index e4834c0308bc..efd8d6e2686c 100644 --- a/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr +++ b/tests/ui/typeck/issue-110017-format-into-help-deletes-macro.stderr @@ -6,17 +6,19 @@ LL | Err(format!("error: {x}")) | = note: expected struct `Box` found struct `String` - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) help: call `Into::into` on this expression to convert `String` into `Box` | LL | Err(format!("error: {x}").into()) | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:23:10 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:17:10 | +LL | format!("error: {}", $x) + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | Err(outer!(x)) - | ^^^^^^^^^ expected `Box`, found `String` + | --------- in this macro invocation | = note: expected struct `Box` found struct `String` @@ -27,10 +29,13 @@ LL | format!("error: {}", $x).into() | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:41:2 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:35:18 | +LL | Err(format!("error: {x}")) + | ^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | entire_fn_outer!(); - | ^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` + | ------------------ in this macro invocation | = note: expected struct `Box` found struct `String` @@ -41,10 +46,13 @@ LL | Err(format!("error: {x}").into()) | +++++++ error[E0308]: mismatched types - --> $DIR/issue-110017-format-into-help-deletes-macro.rs:51:5 + --> $DIR/issue-110017-format-into-help-deletes-macro.rs:45:13 | +LL | Err(format!("error: {}", $x)) + | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box`, found `String` +... LL | nontrivial!(x) - | ^^^^^^^^^^^^^^ expected `Box`, found `String` + | -------------- in this macro invocation | = note: expected struct `Box` found struct `String` diff --git a/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr b/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr index 889d2c94d0cf..cc5a4af88064 100644 --- a/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr +++ b/tests/ui/typeck/issue-112007-leaked-writeln-macro-internals.stderr @@ -12,7 +12,6 @@ LL | | } | = note: expected unit type `()` found enum `Result<(), std::fmt::Error>` - = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a semicolon here | LL | }; @@ -27,13 +26,16 @@ LL | writeln!(w, "but not here")? | + error[E0308]: mismatched types - --> $DIR/issue-112007-leaked-writeln-macro-internals.rs:40:9 + --> $DIR/issue-112007-leaked-writeln-macro-internals.rs:31:9 | +LL | writeln!($w, "but not here") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>` +... LL | / if true { LL | | writeln!(w, "`;?` here ->")?; LL | | } else { LL | | baz!(w) - | | ^^^^^^^ expected `()`, found `Result<(), Error>` + | | ------- in this macro invocation LL | | } | |_____- expected this to be `()` | diff --git a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr index 4ccfacfb0052..1d766e6e5cdb 100644 --- a/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr +++ b/tests/ui/typeck/issue-114423-ice-regression-in-suggestion.stderr @@ -14,7 +14,13 @@ error[E0425]: cannot find value `g` in this scope --> $DIR/issue-114423-ice-regression-in-suggestion.rs:11:22 | LL | let _ = RGB { r, g, b }; - | ^ help: a local variable with a similar name exists: `b` + | ^ + | +help: a local variable with a similar name exists + | +LL - let _ = RGB { r, g, b }; +LL + let _ = RGB { r, b, b }; + | error[E0308]: mismatched types --> $DIR/issue-114423-ice-regression-in-suggestion.rs:7:50 diff --git a/tests/ui/typeck/issue-120856.rs b/tests/ui/typeck/issue-120856.rs index 51dd63a6f89d..bd92adf529f8 100644 --- a/tests/ui/typeck/issue-120856.rs +++ b/tests/ui/typeck/issue-120856.rs @@ -1,5 +1,7 @@ pub type Archived = ::Archived; -//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `m` -//~| ERROR failed to resolve: use of unresolved module or unlinked crate `n` +//~^ ERROR: cannot find module or crate `m` in this scope +//~| ERROR: cannot find module or crate `n` in this scope +//~| NOTE: use of unresolved module or unlinked crate `m` +//~| NOTE: use of unresolved module or unlinked crate `n` fn main() {} diff --git a/tests/ui/typeck/issue-120856.stderr b/tests/ui/typeck/issue-120856.stderr index e366744409f4..026c38da2959 100644 --- a/tests/ui/typeck/issue-120856.stderr +++ b/tests/ui/typeck/issue-120856.stderr @@ -1,24 +1,27 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `n` +error[E0433]: cannot find module or crate `n` in this scope --> $DIR/issue-120856.rs:1:37 | LL | pub type Archived = ::Archived; - | ^ - | | - | use of unresolved module or unlinked crate `n` - | help: a trait with a similar name exists: `Fn` + | ^ use of unresolved module or unlinked crate `n` | = help: you might be missing a crate named `n` +help: a trait with a similar name exists + | +LL | pub type Archived = ::Archived; + | + -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `m` +error[E0433]: cannot find module or crate `m` in this scope --> $DIR/issue-120856.rs:1:25 | LL | pub type Archived = ::Archived; - | ^ - | | - | use of unresolved module or unlinked crate `m` - | help: a type parameter with a similar name exists: `T` + | ^ use of unresolved module or unlinked crate `m` | = help: you might be missing a crate named `m` +help: a type parameter with a similar name exists + | +LL - pub type Archived = ::Archived; +LL + pub type Archived = ::Archived; + | error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/issue-13853.rs b/tests/ui/typeck/issue-13853.rs index ed44d5062614..ac9886d2e724 100644 --- a/tests/ui/typeck/issue-13853.rs +++ b/tests/ui/typeck/issue-13853.rs @@ -25,7 +25,7 @@ impl Node for Stuff { fn iterate>(graph: &G) { for node in graph.iter() { //~ ERROR no method named `iter` found - node.zomg(); //~ ERROR type annotations needed + node.zomg(); } } diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr index 4a39b404770d..45363c87d29d 100644 --- a/tests/ui/typeck/issue-13853.stderr +++ b/tests/ui/typeck/issue-13853.stderr @@ -17,12 +17,6 @@ error[E0599]: no method named `iter` found for reference `&G` in the current sco LL | for node in graph.iter() { | ^^^^ method not found in `&G` -error[E0282]: type annotations needed - --> $DIR/issue-13853.rs:28:9 - | -LL | node.zomg(); - | ^^^^ cannot infer type - error[E0308]: mismatched types --> $DIR/issue-13853.rs:37:13 | @@ -43,7 +37,7 @@ help: consider borrowing here LL | iterate(&graph); | + -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0282, E0308, E0599. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/issue-57404.stderr b/tests/ui/typeck/issue-57404.stderr index 4c1bfc0cbf77..7f8a99ebb917 100644 --- a/tests/ui/typeck/issue-57404.stderr +++ b/tests/ui/typeck/issue-57404.stderr @@ -2,7 +2,7 @@ error[E0277]: `&mut ()` is not a tuple --> $DIR/issue-57404.rs:6:41 | LL | handlers.unwrap().as_mut().call_mut(&mut ()); - | -------- ^^^^^^^ the trait `Tuple` is not implemented for `&mut ()` + | -------- ^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `&mut ()` | | | required by a bound introduced by this call | diff --git a/tests/ui/typeck/issue-79040.stderr b/tests/ui/typeck/issue-79040.stderr deleted file mode 100644 index 4ab8df8f6c93..000000000000 --- a/tests/ui/typeck/issue-79040.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0369]: cannot add `{integer}` to `&str` - --> $DIR/issue-79040.rs:2:25 - | -LL | const FOO = "hello" + 1; - | ------- ^ - {integer} - | | - | &str - -error: missing type for `const` item - --> $DIR/issue-79040.rs:2:14 - | -LL | const FOO = "hello" + 1; - | ^ - | -help: provide a type for the item - | -LL | const FOO: = "hello" + 1; - | ++++++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/typeck/issue-81293.stderr b/tests/ui/typeck/issue-81293.stderr index 8318d31f0946..604f3cca5486 100644 --- a/tests/ui/typeck/issue-81293.stderr +++ b/tests/ui/typeck/issue-81293.stderr @@ -23,13 +23,19 @@ LL | a = c + b * 5; help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: `usize` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&usize` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&usize` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `usize` implements `Add<&usize>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `usize` implements `Add` + = note: `&usize` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/typeck/issue-83693.stderr b/tests/ui/typeck/issue-83693.stderr index 521288c43402..2f83e5daff97 100644 --- a/tests/ui/typeck/issue-83693.stderr +++ b/tests/ui/typeck/issue-83693.stderr @@ -2,11 +2,15 @@ error[E0425]: cannot find type `F` in this scope --> $DIR/issue-83693.rs:6:6 | LL | impl F { - | ^ help: a trait with a similar name exists: `Fn` + | ^ | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | = note: similarly named trait `Fn` defined here +help: a trait with a similar name exists + | +LL | impl Fn { + | + error[E0425]: cannot find type `TestResult` in this scope --> $DIR/issue-83693.rs:9:22 diff --git a/tests/ui/typeck/issue-86721-return-expr-ice.rs b/tests/ui/typeck/issue-86721-return-expr-ice.rs index ea3a2f2fbfe6..ed36164aea60 100644 --- a/tests/ui/typeck/issue-86721-return-expr-ice.rs +++ b/tests/ui/typeck/issue-86721-return-expr-ice.rs @@ -1,7 +1,7 @@ // Regression test for the ICE described in #86721. //@ revisions: rev1 rev2 -#![cfg_attr(any(), rev1, rev2)] +#![cfg_attr(false, rev1, rev2)] #![crate_type = "lib"] #[cfg(any(rev1))] diff --git a/tests/ui/typeck/issue-88844.stderr b/tests/ui/typeck/issue-88844.stderr index a5f4310c34dd..6d21317dfd7f 100644 --- a/tests/ui/typeck/issue-88844.stderr +++ b/tests/ui/typeck/issue-88844.stderr @@ -5,7 +5,12 @@ LL | struct Struct { value: i32 } | ------------- similarly named struct `Struct` defined here ... LL | impl Stuct { - | ^^^^^ help: a struct with a similar name exists: `Struct` + | ^^^^^ + | +help: a struct with a similar name exists + | +LL | impl Struct { + | + error: aborting due to 1 previous error diff --git a/tests/ui/typeck/missing-type-annotation.rs b/tests/ui/typeck/missing-type-annotation.rs new file mode 100644 index 000000000000..d13a7a8559e3 --- /dev/null +++ b/tests/ui/typeck/missing-type-annotation.rs @@ -0,0 +1,4 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/18159 +fn main() { + let x; //~ ERROR type annotations needed +} diff --git a/tests/ui/typeck/missing-type-annotation.stderr b/tests/ui/typeck/missing-type-annotation.stderr new file mode 100644 index 000000000000..88716e757a93 --- /dev/null +++ b/tests/ui/typeck/missing-type-annotation.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/missing-type-annotation.rs:3:9 + | +LL | let x; + | ^ + | +help: consider giving `x` an explicit type + | +LL | let x: /* Type */; + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/typeck/non-function-call-error.rs b/tests/ui/typeck/non-function-call-error.rs new file mode 100644 index 000000000000..c61cf93d138a --- /dev/null +++ b/tests/ui/typeck/non-function-call-error.rs @@ -0,0 +1,19 @@ +//! Regression test for issue #10969, #22468 + +fn main() { + let foo = "bar"; + let x = foo("baz"); + //~^ ERROR: expected function, found `&str` + + let i = 0i32; + i(); + //~^ ERROR expected function, found `i32` +} + +fn foo(file: &str) -> bool { + true +} + +fn func(i: i32) { + i(); //~ERROR expected function, found `i32` +} diff --git a/tests/ui/typeck/non-function-call-error.stderr b/tests/ui/typeck/non-function-call-error.stderr new file mode 100644 index 000000000000..f4797ac3d8b7 --- /dev/null +++ b/tests/ui/typeck/non-function-call-error.stderr @@ -0,0 +1,36 @@ +error[E0618]: expected function, found `&str` + --> $DIR/non-function-call-error.rs:5:13 + | +LL | let foo = "bar"; + | --- `foo` has type `&str` +LL | let x = foo("baz"); + | ^^^------- + | | + | call expression requires function +... +LL | fn foo(file: &str) -> bool { + | -------------------------- this function of the same name is available here, but it's shadowed by the local binding + +error[E0618]: expected function, found `i32` + --> $DIR/non-function-call-error.rs:9:5 + | +LL | let i = 0i32; + | - `i` has type `i32` +LL | i(); + | ^-- + | | + | call expression requires function + +error[E0618]: expected function, found `i32` + --> $DIR/non-function-call-error.rs:18:5 + | +LL | fn func(i: i32) { + | - `i` has type `i32` +LL | i(); + | ^-- + | | + | call expression requires function + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/typeck/osstring-str-equality.rs b/tests/ui/typeck/osstring-str-equality.rs new file mode 100644 index 000000000000..47d3dd632bdc --- /dev/null +++ b/tests/ui/typeck/osstring-str-equality.rs @@ -0,0 +1,10 @@ +//! regression test for https://github.com/rust-lang/rust/issues/49854 +//@ run-pass +use std::ffi::OsString; + +fn main() { + let os_str = OsString::from("Hello Rust!"); + + assert_eq!(os_str, "Hello Rust!"); + assert_eq!("Hello Rust!", os_str); +} diff --git a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.cargo-invoked.stderr b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.cargo-invoked.stderr index 8a3b87b0d11a..8ff61b21ad1f 100644 --- a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.cargo-invoked.stderr +++ b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.cargo-invoked.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `page_size` +error[E0433]: cannot find module or crate `page_size` in this scope --> $DIR/path-to-method-sugg-unresolved-expr.rs:5:21 | LL | let page_size = page_size::get(); diff --git a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.only-rustc.stderr b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.only-rustc.stderr index 34ed5c44d931..0cf3394cfedd 100644 --- a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.only-rustc.stderr +++ b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.only-rustc.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `page_size` +error[E0433]: cannot find module or crate `page_size` in this scope --> $DIR/path-to-method-sugg-unresolved-expr.rs:5:21 | LL | let page_size = page_size::get(); diff --git a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs index e095850879cd..035e7afb30d9 100644 --- a/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs +++ b/tests/ui/typeck/path-to-method-sugg-unresolved-expr.rs @@ -3,7 +3,7 @@ //@[cargo-invoked] rustc-env:CARGO_CRATE_NAME=foo fn main() { let page_size = page_size::get(); - //~^ ERROR failed to resolve: use of unresolved module or unlinked crate `page_size` + //~^ ERROR cannot find module or crate `page_size` //~| NOTE use of unresolved module or unlinked crate `page_size` //[cargo-invoked]~^^^ HELP if you wanted to use a crate named `page_size`, use `cargo add //[only-rustc]~^^^^ HELP you might be missing a crate named `page_size` diff --git a/tests/ui/typeck/question-mark-operator-suggestion-span.stderr b/tests/ui/typeck/question-mark-operator-suggestion-span.stderr index 089b3bcd1988..f567e553d8b7 100644 --- a/tests/ui/typeck/question-mark-operator-suggestion-span.stderr +++ b/tests/ui/typeck/question-mark-operator-suggestion-span.stderr @@ -12,7 +12,6 @@ LL | | } | = note: expected unit type `()` found enum `Result<(), std::fmt::Error>` - = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a semicolon here | LL | }; diff --git a/tests/ui/typeck/return-expression-invalid-callee.rs b/tests/ui/typeck/return-expression-invalid-callee.rs new file mode 100644 index 000000000000..1416f3e9ddfe --- /dev/null +++ b/tests/ui/typeck/return-expression-invalid-callee.rs @@ -0,0 +1,8 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/18532 +//! Test that overloaded call parameter checking does not ICE +//! when a type error or unconstrained type variable propagates +//! into it. + +fn main() { + (return)((), ()); //~ ERROR expected function, found `!` +} diff --git a/tests/ui/typeck/return-expression-invalid-callee.stderr b/tests/ui/typeck/return-expression-invalid-callee.stderr new file mode 100644 index 000000000000..5a36602af8bb --- /dev/null +++ b/tests/ui/typeck/return-expression-invalid-callee.stderr @@ -0,0 +1,11 @@ +error[E0618]: expected function, found `!` + --> $DIR/return-expression-invalid-callee.rs:7:5 + | +LL | (return)((), ()); + | ^^^^^^^^-------- + | | + | call expression requires function + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0618`. diff --git a/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr b/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr index d74372c665a4..c217672b0050 100644 --- a/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr +++ b/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr @@ -2,7 +2,12 @@ error[E0425]: cannot find type `Item` in this scope --> $DIR/sugg-swap-equality-in-macro-issue-139050.rs:29:5 | LL | Item: Eq + Debug, - | ^^^^ not found in this scope + | ^^^^ + | +help: you might have meant to use an associated type of the same name + | +LL | I::Item: Eq + Debug, + | +++ error[E0308]: mismatched types --> $DIR/sugg-swap-equality-in-macro-issue-139050.rs:31:5 diff --git a/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.stderr b/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.stderr index 59e56f672374..6785d48eca60 100644 --- a/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.stderr +++ b/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.stderr @@ -26,7 +26,6 @@ error[E0308]: mismatched types LL | let c: S = dbg!(field); | ^^^^^^^^^^^ expected `S`, found `&S` | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using clone here | LL | let c: S = dbg!(field).clone(); @@ -38,7 +37,6 @@ error[E0308]: mismatched types LL | let c: S = dbg!(dbg!(field)); | ^^^^^^^^^^^^^^^^^ expected `S`, found `&S` | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using clone here | LL | let c: S = dbg!(dbg!(field)).clone(); diff --git a/tests/ui/typeck/tuple-ref-order-distinct-impls.rs b/tests/ui/typeck/tuple-ref-order-distinct-impls.rs new file mode 100644 index 000000000000..fdede8a1d9c4 --- /dev/null +++ b/tests/ui/typeck/tuple-ref-order-distinct-impls.rs @@ -0,0 +1,12 @@ +//! regression test for +//@ check-pass + +trait Common { + fn dummy(&self) {} +} + +impl<'t, T> Common for (T, &'t T) {} + +impl<'t, T> Common for (&'t T, T) {} + +fn main() {} diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 0b70ac97fd43..2772d55f953a 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -684,13 +684,6 @@ error[E0015]: cannot call non-const method ` as Iterator>:: LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^^^^^^^^^ | -note: method `filter` is not const because trait `Iterator` is not const - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this trait is not const - ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this method is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const method `, {closure@$DIR/typeck_type_placeholder_item.rs:240:29: 240:32}> as Iterator>::map::` in constants @@ -699,13 +692,6 @@ error[E0015]: cannot call non-const method `, {closu LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); | ^^^^^^^^^^^^^^ | -note: method `map` is not const because trait `Iterator` is not const - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this trait is not const - ::: $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - | - = note: this method is not const = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to 83 previous errors diff --git a/tests/ui/ufcs/bad-builder.stderr b/tests/ui/ufcs/bad-builder.stderr index a3528cb1e7d8..2504a3d09253 100644 --- a/tests/ui/ufcs/bad-builder.stderr +++ b/tests/ui/ufcs/bad-builder.stderr @@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec` consider using one of the followi Vec::::with_capacity Vec::::try_with_capacity Vec::::from_raw_parts - and 6 others + and 7 others --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: there is an associated function `new` with a similar name | diff --git a/tests/ui/ufcs/ufcs-partially-resolved.stderr b/tests/ui/ufcs/ufcs-partially-resolved.stderr index a854ecb06222..e1df200feccf 100644 --- a/tests/ui/ufcs/ufcs-partially-resolved.stderr +++ b/tests/ui/ufcs/ufcs-partially-resolved.stderr @@ -5,17 +5,27 @@ LL | type Y = u16; | ------------- similarly named associated type `Y` defined here ... LL | let _: ::N; - | ^ help: an associated type with a similar name exists: `Y` + | ^ + | +help: an associated type with a similar name exists + | +LL - let _: ::N; +LL + let _: ::Y; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:20:19 | LL | let _: ::N; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::N; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:21:19 @@ -36,17 +46,27 @@ LL | fn Y() {} | ------ similarly named associated function `Y` defined here ... LL | ::N; - | ^ help: an associated function with a similar name exists: `Y` + | ^ + | +help: an associated function with a similar name exists + | +LL - ::N; +LL + ::Y; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:23:12 | LL | ::N; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::N; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:24:12 @@ -64,21 +84,29 @@ error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:26:19 | LL | let _: ::Y; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::Y; + | + error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:28:12 | LL | ::Y; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::Y; + | + error[E0576]: cannot find associated type `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:30:24 @@ -87,17 +115,27 @@ LL | type Y = u16; | ------------- similarly named associated type `Y` defined here ... LL | let _: ::N::NN; - | ^ help: an associated type with a similar name exists: `Y` + | ^ + | +help: an associated type with a similar name exists + | +LL - let _: ::N::NN; +LL + let _: ::Y::NN; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:31:19 | LL | let _: ::N::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::N::NN; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:32:19 @@ -118,17 +156,27 @@ LL | type Y = u16; | ------------- similarly named associated type `Y` defined here ... LL | ::N::NN; - | ^ help: an associated type with a similar name exists: `Y` + | ^ + | +help: an associated type with a similar name exists + | +LL - ::N::NN; +LL + ::Y::NN; + | error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:34:12 | LL | ::N::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::N::NN; + | + error[E0404]: expected trait, found type alias `A` --> $DIR/ufcs-partially-resolved.rs:35:12 @@ -146,21 +194,29 @@ error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:37:19 | LL | let _: ::Y::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | let _: ::Y::NN; + | + error[E0404]: expected trait, found enum `E` --> $DIR/ufcs-partially-resolved.rs:39:12 | LL | ::Y::NN; - | ^ help: a trait with a similar name exists: `Eq` + | ^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named trait `Eq` defined here +help: a trait with a similar name exists + | +LL | ::Y::NN; + | + error[E0405]: cannot find trait `N` in trait `Tr` --> $DIR/ufcs-partially-resolved.rs:41:23 @@ -229,9 +285,13 @@ LL | type X = u16; | ------------- similarly named associated type `X` defined here ... LL | let _: ::Z; - | ^^^^^^^^^^^^- - | | - | help: an associated type with a similar name exists: `X` + | ^^^^^^^^^^^^^ + | +help: an associated type with a similar name exists + | +LL - let _: ::Z; +LL + let _: ::X; + | error[E0575]: expected method or associated constant, found associated type `Dr::X` --> $DIR/ufcs-partially-resolved.rs:53:5 @@ -240,9 +300,13 @@ LL | fn Z() {} | ------ similarly named associated function `Z` defined here ... LL | ::X; - | ^^^^^^^^^^^^- - | | - | help: an associated function with a similar name exists: `Z` + | ^^^^^^^^^^^^^ + | +help: an associated function with a similar name exists + | +LL - ::X; +LL + ::Z; + | error[E0575]: expected associated type, found associated function `Dr::Z` --> $DIR/ufcs-partially-resolved.rs:54:12 @@ -251,9 +315,13 @@ LL | type X = u16; | ------------- similarly named associated type `X` defined here ... LL | let _: ::Z::N; - | ^^^^^^^^^^^^-^^^ - | | - | help: an associated type with a similar name exists: `X` + | ^^^^^^^^^^^^^^^^ + | +help: an associated type with a similar name exists + | +LL - let _: ::Z::N; +LL + let _: ::X::N; + | error[E0223]: ambiguous associated type --> $DIR/ufcs-partially-resolved.rs:36:12 diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr index 352638dd0118..dbbee54c185b 100644 --- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -8,13 +8,19 @@ LL | >::add(1, 2); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types @@ -73,13 +79,19 @@ LL | >::add(1, 2); help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: `i32` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Add<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Add` + = note: `&i32` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/tests/ui/ufcs/ufcs-trait-object-format.rs b/tests/ui/ufcs/ufcs-trait-object-format.rs new file mode 100644 index 000000000000..7d50a2444806 --- /dev/null +++ b/tests/ui/ufcs/ufcs-trait-object-format.rs @@ -0,0 +1,13 @@ +//@ run-pass +//! Regression test for . +//! Error was that we didn't support +//! UFCS-style calls to a method in `Trait` where `Self` was bound to a +//! trait object of type `Trait`. +//! See also . + +use std::fmt; + +fn main() { + let a: &dyn fmt::Debug = &1; + let _ = format!("{:?}", a); +} diff --git a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr index 0d4265ddf8bd..488dff646793 100644 --- a/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr +++ b/tests/ui/unboxed-closures/non-tupled-arg-mismatch.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple --> $DIR/non-tupled-arg-mismatch.rs:3:9 | LL | fn a>(f: F) {} - | ^^^^^^^^^ the trait `Tuple` is not implemented for `usize` + | ^^^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `usize` | note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL diff --git a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index 739182e120b4..6860b0b2f7ee 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -7,7 +7,7 @@ LL | let mut closure0 = None; LL | return c(); | - type must be known at this point | -help: consider giving `closure0` an explicit type, where the placeholders `_` are specified +help: consider giving `closure0` an explicit type, where the type for type parameter `T` is specified | LL | let mut closure0: Option = None; | +++++++++++ diff --git a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr index 5f22c781345f..7e295c1d54f9 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr @@ -8,7 +8,13 @@ error[E0425]: cannot find value `y` in this scope --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:26 | LL | closure(&mut p, &y); - | ^ help: a local variable with a similar name exists: `p` + | ^ + | +help: a local variable with a similar name exists + | +LL - closure(&mut p, &y); +LL + closure(&mut p, &p); + | error[E0308]: mismatched types --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:17 diff --git a/tests/ui/underscore-imports/issue-110164.ed2015.stderr b/tests/ui/underscore-imports/issue-110164.ed2015.stderr deleted file mode 100644 index f34b5ab5dde7..000000000000 --- a/tests/ui/underscore-imports/issue-110164.ed2015.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:8:5 - | -LL | use _::a; - | ^ expected identifier, found reserved identifier - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:10:5 - | -LL | use _::*; - | ^ expected identifier, found reserved identifier - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:14:9 - | -LL | use _::a; - | ^ expected identifier, found reserved identifier - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:16:9 - | -LL | use _::*; - | ^ expected identifier, found reserved identifier - -error[E0432]: unresolved import `self::*` - --> $DIR/issue-110164.rs:4:5 - | -LL | use self::*; - | ^^^^^^^ cannot glob-import a module into itself - -error[E0432]: unresolved import `crate::*` - --> $DIR/issue-110164.rs:6:5 - | -LL | use crate::*; - | ^^^^^^^^ cannot glob-import a module into itself - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/underscore-imports/issue-110164.ed2021.stderr b/tests/ui/underscore-imports/issue-110164.ed2021.stderr deleted file mode 100644 index f34b5ab5dde7..000000000000 --- a/tests/ui/underscore-imports/issue-110164.ed2021.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:8:5 - | -LL | use _::a; - | ^ expected identifier, found reserved identifier - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:10:5 - | -LL | use _::*; - | ^ expected identifier, found reserved identifier - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:14:9 - | -LL | use _::a; - | ^ expected identifier, found reserved identifier - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-110164.rs:16:9 - | -LL | use _::*; - | ^ expected identifier, found reserved identifier - -error[E0432]: unresolved import `self::*` - --> $DIR/issue-110164.rs:4:5 - | -LL | use self::*; - | ^^^^^^^ cannot glob-import a module into itself - -error[E0432]: unresolved import `crate::*` - --> $DIR/issue-110164.rs:6:5 - | -LL | use crate::*; - | ^^^^^^^^ cannot glob-import a module into itself - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/uninhabited/void-branch.stderr b/tests/ui/uninhabited/void-branch.stderr index ee5efb94ed21..15693fc85f4b 100644 --- a/tests/ui/uninhabited/void-branch.stderr +++ b/tests/ui/uninhabited/void-branch.stderr @@ -16,7 +16,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::format_args` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable expression --> $DIR/void-branch.rs:25:9 @@ -31,7 +30,6 @@ note: this expression has type `Infallible`, which is uninhabited | LL | infallible(); | ^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::format_args` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/union/union-derive-clone.stderr b/tests/ui/union/union-derive-clone.stderr index 679ab6a38e49..62ef35b76192 100644 --- a/tests/ui/union/union-derive-clone.stderr +++ b/tests/ui/union/union-derive-clone.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `U1: Copy` is not satisfied LL | #[derive(Clone)] | ^^^^^ the trait `Copy` is not implemented for `U1` | -note: required by a bound in `AssertParamIsCopy` +note: required by a bound in `std::clone::AssertParamIsCopy` --> $SRC_DIR/core/src/clone.rs:LL:COL help: consider annotating `U1` with `#[derive(Copy)]` | @@ -25,10 +25,13 @@ LL | let w = u.clone(); | ^^^^^ method cannot be called on `U5` due to unsatisfied trait bounds | note: trait bound `CloneNoCopy: Copy` was not satisfied - --> $DIR/union-derive-clone.rs:25:10 + --> $DIR/union-derive-clone.rs:26:10 | LL | #[derive(Clone, Copy)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ----- in this derive macro expansion +LL | union U5 { + | ^ type parameter would need to implement `Clone` + = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]` | LL + #[derive(Clone, Copy)] diff --git a/tests/ui/union/union-derive-eq.current.stderr b/tests/ui/union/union-derive-eq.current.stderr index a0339687dad4..df8e6db887bc 100644 --- a/tests/ui/union/union-derive-eq.current.stderr +++ b/tests/ui/union/union-derive-eq.current.stderr @@ -7,7 +7,7 @@ LL | union U2 { LL | a: PartialEqNotEq, | ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]` | diff --git a/tests/ui/union/union-derive-eq.next.stderr b/tests/ui/union/union-derive-eq.next.stderr index a0339687dad4..df8e6db887bc 100644 --- a/tests/ui/union/union-derive-eq.next.stderr +++ b/tests/ui/union/union-derive-eq.next.stderr @@ -7,7 +7,7 @@ LL | union U2 { LL | a: PartialEqNotEq, | ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `PartialEqNotEq` with `#[derive(Eq)]` | diff --git a/tests/ui/unpretty/bad-literal.stdout b/tests/ui/unpretty/bad-literal.stdout index 1f697aff27c9..711f3a9bdf87 100644 --- a/tests/ui/unpretty/bad-literal.stdout +++ b/tests/ui/unpretty/bad-literal.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir //@ check-fail diff --git a/tests/ui/unpretty/box.rs b/tests/ui/unpretty/box.rs deleted file mode 100644 index 83fdeff7a179..000000000000 --- a/tests/ui/unpretty/box.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ compile-flags: -Zunpretty=thir-tree -//@ check-pass - -#![feature(liballoc_internals)] - -fn main() { - let _ = std::boxed::box_new(1); -} diff --git a/tests/ui/unpretty/box.stdout b/tests/ui/unpretty/box.stdout deleted file mode 100644 index 54bd98c7a683..000000000000 --- a/tests/ui/unpretty/box.stdout +++ /dev/null @@ -1,90 +0,0 @@ -DefId(0:3 ~ box[efb9]::main): -params: [ -] -body: - Expr { - ty: () - temp_scope_id: 11 - span: $DIR/box.rs:6:11: 8:2 (#0) - kind: - Scope { - region_scope: Node(11) - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).11)) - value: - Expr { - ty: () - temp_scope_id: 11 - span: $DIR/box.rs:6:11: 8:2 (#0) - kind: - Block { - targeted_by_break: false - span: $DIR/box.rs:6:11: 8:2 (#0) - region_scope: Node(1) - safety_mode: Safe - stmts: [ - Stmt { - kind: Let { - remainder_scope: Remainder { block: 1, first_statement_index: 0} - init_scope: Node(2) - pattern: - Pat: { - ty: std::boxed::Box - span: $DIR/box.rs:7:9: 7:10 (#0) - kind: PatKind { - Wild - } - } - , - initializer: Some( - Expr { - ty: std::boxed::Box - temp_scope_id: 3 - span: $DIR/box.rs:7:13: 7:35 (#0) - kind: - Scope { - region_scope: Node(3) - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).3)) - value: - Expr { - ty: std::boxed::Box - temp_scope_id: 3 - span: $DIR/box.rs:7:13: 7:35 (#0) - kind: - Box { - Expr { - ty: i32 - temp_scope_id: 8 - span: $DIR/box.rs:7:33: 7:34 (#0) - kind: - Scope { - region_scope: Node(8) - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).8)) - value: - Expr { - ty: i32 - temp_scope_id: 8 - span: $DIR/box.rs:7:33: 7:34 (#0) - kind: - Literal( lit: Spanned { node: Int(Pu128(1), Unsuffixed), span: $DIR/box.rs:7:33: 7:34 (#0) }, neg: false) - - } - } - } - } - } - } - } - ) - else_block: None - lint_level: Explicit(HirId(DefId(0:3 ~ box[efb9]::main).9)) - span: $DIR/box.rs:7:5: 7:35 (#0) - } - } - ] - expr: [] - } - } - } - } - - diff --git a/tests/ui/unpretty/debug-fmt-hir.stdout b/tests/ui/unpretty/debug-fmt-hir.stdout index 9c79421e32ab..1f0a6e2e334f 100644 --- a/tests/ui/unpretty/debug-fmt-hir.stdout +++ b/tests/ui/unpretty/debug-fmt-hir.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir //@ check-pass diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout index 26cc74c11604..32d5cf06a3d6 100644 --- a/tests/ui/unpretty/deprecated-attr.stdout +++ b/tests/ui/unpretty/deprecated-attr.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir //@ check-pass @@ -10,19 +9,19 @@ use ::std::prelude::rust_2015::*; struct PlainDeprecated; #[attr = Deprecation {deprecation: Deprecation {since: Unspecified, -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct DirectNote; #[attr = Deprecation {deprecation: Deprecation {since: Unspecified, -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct ExplicitNote; #[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct SinceAndNote; #[attr = Deprecation {deprecation: Deprecation {since: NonStandard("1.2.3"), -note: "here's why this is deprecated"}}] +note: here's why this is deprecated#0}}] struct FlippedOrder; fn f() { diff --git a/tests/ui/unpretty/diagnostic-attr.stdout b/tests/ui/unpretty/diagnostic-attr.stdout index 4822cf4700b9..0b4b5f919343 100644 --- a/tests/ui/unpretty/diagnostic-attr.stdout +++ b/tests/ui/unpretty/diagnostic-attr.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir //@ check-pass @@ -11,5 +10,5 @@ use ::std::prelude::rust_2015::*; "My Label", note = "Note 1", note = "Note 2")] trait ImportantTrait { } -#[diagnostic::do_not_recommend] +#[attr = DoNotRecommend] impl ImportantTrait for T where T: Clone { } diff --git a/tests/ui/unpretty/exhaustive-asm.expanded.stdout b/tests/ui/unpretty/exhaustive-asm.expanded.stdout index 9a58e4c2877b..9b3c60b03ba7 100644 --- a/tests/ui/unpretty/exhaustive-asm.expanded.stdout +++ b/tests/ui/unpretty/exhaustive-asm.expanded.stdout @@ -1,5 +1,4 @@ #![feature(prelude_import)] -#[macro_use] extern crate std; #[prelude_import] use std::prelude::rust_2024::*; diff --git a/tests/ui/unpretty/exhaustive-asm.hir.stdout b/tests/ui/unpretty/exhaustive-asm.hir.stdout index b33b38c2caba..c44db0865396 100644 --- a/tests/ui/unpretty/exhaustive-asm.hir.stdout +++ b/tests/ui/unpretty/exhaustive-asm.hir.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use std::prelude::rust_2024::*; //@ revisions: expanded hir //@[expanded]compile-flags: -Zunpretty=expanded diff --git a/tests/ui/unpretty/exhaustive.expanded.stdout b/tests/ui/unpretty/exhaustive.expanded.stdout index 9e6797c727f0..f555904e5dd7 100644 --- a/tests/ui/unpretty/exhaustive.expanded.stdout +++ b/tests/ui/unpretty/exhaustive.expanded.stdout @@ -28,9 +28,9 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] -#[macro_use] extern crate std; #[prelude_import] use std::prelude::rust_2024::*; @@ -222,7 +222,12 @@ mod expressions { } /// ExprKind::TryBlock - fn expr_try_block() { try {} try { return; } } + fn expr_try_block() { + try {} + try { return; } + try bikeshed Option<_> {} + try bikeshed Option { None? } + } /// ExprKind::Assign fn expr_assign() { let expr; expr = true; } diff --git a/tests/ui/unpretty/exhaustive.hir.stderr b/tests/ui/unpretty/exhaustive.hir.stderr index eb5c186bd2c0..f6800fc9c1e6 100644 --- a/tests/ui/unpretty/exhaustive.hir.stderr +++ b/tests/ui/unpretty/exhaustive.hir.stderr @@ -1,17 +1,17 @@ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:210:9 + --> $DIR/exhaustive.rs:211:9 | LL | static || value; | ^^^^^^^^^ error[E0697]: closures cannot be static - --> $DIR/exhaustive.rs:211:9 + --> $DIR/exhaustive.rs:212:9 | LL | static move || value; | ^^^^^^^^^^^^^^ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/exhaustive.rs:240:13 + --> $DIR/exhaustive.rs:241:13 | LL | fn expr_await() { | --------------- this is not `async` @@ -20,19 +20,19 @@ LL | fut.await; | ^^^^^ only allowed inside `async` functions and blocks error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/exhaustive.rs:289:9 + --> $DIR/exhaustive.rs:292:9 | LL | _; | ^ `_` not allowed here error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:299:9 + --> $DIR/exhaustive.rs:302:9 | LL | x::(); | ^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:300:9 + --> $DIR/exhaustive.rs:303:9 | LL | x::(T, T) -> T; | ^^^^^^^^^^^^^^ only `Fn` traits may use parentheses @@ -44,31 +44,31 @@ LL + x:: -> T; | error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:301:9 + --> $DIR/exhaustive.rs:304:9 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:301:26 + --> $DIR/exhaustive.rs:304:26 | LL | crate::() -> ()::expressions::() -> ()::expr_path; | ^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:304:9 + --> $DIR/exhaustive.rs:307:9 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:304:19 + --> $DIR/exhaustive.rs:307:19 | LL | core::()::marker::()::PhantomData; | ^^^^^^^^^^ only `Fn` traits may use parentheses error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks - --> $DIR/exhaustive.rs:391:9 + --> $DIR/exhaustive.rs:394:9 | LL | yield; | ^^^^^ @@ -79,7 +79,7 @@ LL | #[coroutine] fn expr_yield() { | ++++++++++++ error[E0703]: invalid ABI: found `C++` - --> $DIR/exhaustive.rs:471:23 + --> $DIR/exhaustive.rs:474:23 | LL | unsafe extern "C++" {} | ^^^^^ invalid ABI @@ -87,7 +87,7 @@ LL | unsafe extern "C++" {} = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions error: `..` patterns are not allowed here - --> $DIR/exhaustive.rs:678:13 + --> $DIR/exhaustive.rs:681:13 | LL | let ..; | ^^ @@ -95,13 +95,13 @@ LL | let ..; = note: only allowed in tuple, tuple struct, and slice patterns error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/exhaustive.rs:793:16 + --> $DIR/exhaustive.rs:796:16 | LL | let _: T() -> !; | ^^^^^^^^ only `Fn` traits may use parentheses error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:807:16 + --> $DIR/exhaustive.rs:810:16 | LL | let _: impl Send; | ^^^^^^^^^ @@ -112,7 +112,7 @@ LL | let _: impl Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:808:16 + --> $DIR/exhaustive.rs:811:16 | LL | let _: impl Send + 'static; | ^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ LL | let _: impl Send + 'static; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:809:16 + --> $DIR/exhaustive.rs:812:16 | LL | let _: impl 'static + Send; | ^^^^^^^^^^^^^^^^^^^ @@ -134,7 +134,7 @@ LL | let _: impl 'static + Send; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:810:16 + --> $DIR/exhaustive.rs:813:16 | LL | let _: impl ?Sized; | ^^^^^^^^^^^ @@ -145,7 +145,7 @@ LL | let _: impl ?Sized; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:811:16 + --> $DIR/exhaustive.rs:814:16 | LL | let _: impl [const] Clone; | ^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ LL | let _: impl [const] Clone; = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0562]: `impl Trait` is not allowed in the type of variable bindings - --> $DIR/exhaustive.rs:812:16 + --> $DIR/exhaustive.rs:815:16 | LL | let _: impl for<'a> Send; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 873febbbd84d..7ee848491d6e 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -27,11 +27,11 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use std::prelude::rust_2024::*; mod prelude { @@ -46,7 +46,7 @@ mod prelude { } } -#[prelude_import] +#[attr = PreludeImport] use self::prelude::*; /// inner single-line doc comment @@ -253,7 +253,19 @@ mod expressions { } /// ExprKind::TryBlock - fn expr_try_block() { { from_output(()) } { return; from_output(()) } } + fn expr_try_block() { + { from_output(()) } + { return; from_output(()) } + type_ascribe!({ from_output(()) }, Option<_>); + type_ascribe!({ + from_output(match branch(None) { + Break { 0: residual } => #[allow(unreachable_code)] + break from_residual(residual), + Continue { 0: val } => #[allow(unreachable_code)] + val, + }) + }, Option) + } /// ExprKind::Assign fn expr_assign() { let expr; expr = true; } diff --git a/tests/ui/unpretty/exhaustive.rs b/tests/ui/unpretty/exhaustive.rs index 0983a0a7e437..0bbc87845695 100644 --- a/tests/ui/unpretty/exhaustive.rs +++ b/tests/ui/unpretty/exhaustive.rs @@ -27,6 +27,7 @@ #![feature(trace_macros)] #![feature(trait_alias)] #![feature(try_blocks)] +#![feature(try_blocks_heterogeneous)] #![feature(yeet_expr)] #![allow(incomplete_features)] @@ -244,6 +245,8 @@ mod expressions { fn expr_try_block() { try {} try { return; } + try bikeshed Option<_> { } + try bikeshed Option { None? } } /// ExprKind::Assign diff --git a/tests/ui/unpretty/flattened-format-args.stdout b/tests/ui/unpretty/flattened-format-args.stdout index 5c7866dcf39f..008d69c9b9ef 100644 --- a/tests/ui/unpretty/flattened-format-args.stdout +++ b/tests/ui/unpretty/flattened-format-args.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir -Zflatten-format-args=yes //@ check-pass diff --git a/tests/ui/unpretty/interpolation-expanded.stdout b/tests/ui/unpretty/interpolation-expanded.stdout index 7284a89e7a9b..d385a021ed57 100644 --- a/tests/ui/unpretty/interpolation-expanded.stdout +++ b/tests/ui/unpretty/interpolation-expanded.stdout @@ -10,7 +10,6 @@ // synthesizing parentheses indiscriminately; only where necessary. #![feature(if_let_guard)] -#[macro_use] extern crate std; #[prelude_import] use std::prelude::rust_2024::*; diff --git a/tests/ui/unpretty/let-else-hir.stdout b/tests/ui/unpretty/let-else-hir.stdout index 14270a572027..73d627ef997a 100644 --- a/tests/ui/unpretty/let-else-hir.stdout +++ b/tests/ui/unpretty/let-else-hir.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir //@ check-pass diff --git a/tests/ui/unpretty/self-hir.stdout b/tests/ui/unpretty/self-hir.stdout index b190565dcc47..b14c583f4f38 100644 --- a/tests/ui/unpretty/self-hir.stdout +++ b/tests/ui/unpretty/self-hir.stdout @@ -1,6 +1,5 @@ -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; //@ compile-flags: -Zunpretty=hir //@ check-pass diff --git a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs new file mode 100644 index 000000000000..5f2d6680efac --- /dev/null +++ b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.rs @@ -0,0 +1,33 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; + +struct Point(u32, u32); + +struct Point3(); + +struct Point1 { + a: u32, + b: u32, +} + +struct Point2 {} + +fn with_point() {} +fn with_point1() {} +fn with_point2() {} +fn with_point3() {} + +fn test() { + with_point::<{ Point(N, N) }>(); + with_point1::<{ Point1 { a: N, b: N } }>(); + with_point2::<{ Point2 {} }>(); + with_point3::<{ Point3() }>(); +} + +fn main() {} diff --git a/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout new file mode 100644 index 000000000000..c990837d2138 --- /dev/null +++ b/tests/ui/unpretty/struct-exprs-tuple-call-pretty-printing.stdout @@ -0,0 +1,38 @@ +//@ compile-flags: -Zunpretty=hir +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] +extern crate std; +#[attr = PreludeImport] +use ::std::prelude::rust_2015::*; + +use std::marker::ConstParamTy; + +struct Point(u32, u32); + +struct Point3(); + +struct Point1 { + a: u32, + b: u32, +} + +struct Point2 { +} + +fn with_point() { } +fn with_point1() { } +fn with_point2() { } +fn with_point3() { } + +fn test() { + with_point::(); + with_point1::(); + with_point2::(); + with_point3::(); +} + +fn main() { } diff --git a/tests/ui/unpretty/unpretty-expr-fn-arg.stdout b/tests/ui/unpretty/unpretty-expr-fn-arg.stdout index c04909a73613..19bfe92e3b27 100644 --- a/tests/ui/unpretty/unpretty-expr-fn-arg.stdout +++ b/tests/ui/unpretty/unpretty-expr-fn-arg.stdout @@ -8,9 +8,8 @@ //@ compile-flags: -Zunpretty=hir,typed //@ edition: 2015 #![allow(dead_code)] -#[attr = MacroUse {arguments: UseAll}] extern crate std; -#[prelude_import] +#[attr = PreludeImport] use ::std::prelude::rust_2015::*; fn main() ({ } as ()) diff --git a/tests/ui/unresolved/unresolved-candidates.stderr b/tests/ui/unresolved/unresolved-candidates.stderr index 55b9d8ec6e8f..7d8e894a5582 100644 --- a/tests/ui/unresolved/unresolved-candidates.stderr +++ b/tests/ui/unresolved/unresolved-candidates.stderr @@ -4,8 +4,10 @@ error[E0432]: unresolved import `Trait` LL | use Trait; | ^^^^^ no `Trait` in the root | -help: consider importing this trait instead +help: consider importing one of these items instead | +LL | use std::mem::type_info::Trait; + | +++++++++++++++++++++ LL | use a::Trait; | +++ diff --git a/tests/ui/unsized/enum-struct-optimization.rs b/tests/ui/unsized/enum-struct-optimization.rs new file mode 100644 index 000000000000..2e2bc64008a6 --- /dev/null +++ b/tests/ui/unsized/enum-struct-optimization.rs @@ -0,0 +1,15 @@ +//! regression test for +//@ run-pass +#![allow(dead_code)] +// Test that wrapping an unsized struct in an enum which gets optimised does +// not ICE. + + +struct Str { + f: [u8] +} + +fn main() { + let str: Option<&Str> = None; + let _ = str.is_some(); +} diff --git a/tests/ui/unsized/issue-71659.current.stderr b/tests/ui/unsized/issue-71659.current.stderr index f7de668ba3a5..22e43e07dbda 100644 --- a/tests/ui/unsized/issue-71659.current.stderr +++ b/tests/ui/unsized/issue-71659.current.stderr @@ -1,18 +1,22 @@ -error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied - --> $DIR/issue-71659.rs:34:15 +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/issue-71659.rs:33:17 | -LL | let x = x.cast::<[i32]>(); - | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo` +LL | let x: &dyn Foo = &[]; + | ^^^ `Foo` is not dyn compatible | -note: required by a bound in `Cast::cast` - --> $DIR/issue-71659.rs:23:15 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/marker.rs:LL:COL | -LL | fn cast(&self) -> &T - | ---- required by a bound in this associated function -LL | where -LL | Self: CastTo, - | ^^^^^^^^^ required by this bound in `Cast::cast` + = note: ...because it opted out of dyn-compatibility + | + ::: $DIR/issue-71659.rs:29:11 + | +LL | pub trait Foo: CastTo<[i32]> {} + | --- this trait is not dyn compatible... + = help: only type `[i32; 0]` implements `Foo` within this crate; consider using it directly instead. + = note: `Foo` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/unsized/issue-71659.next.stderr b/tests/ui/unsized/issue-71659.next.stderr index f7de668ba3a5..22e43e07dbda 100644 --- a/tests/ui/unsized/issue-71659.next.stderr +++ b/tests/ui/unsized/issue-71659.next.stderr @@ -1,18 +1,22 @@ -error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied - --> $DIR/issue-71659.rs:34:15 +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/issue-71659.rs:33:17 | -LL | let x = x.cast::<[i32]>(); - | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo` +LL | let x: &dyn Foo = &[]; + | ^^^ `Foo` is not dyn compatible | -note: required by a bound in `Cast::cast` - --> $DIR/issue-71659.rs:23:15 +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $SRC_DIR/core/src/marker.rs:LL:COL | -LL | fn cast(&self) -> &T - | ---- required by a bound in this associated function -LL | where -LL | Self: CastTo, - | ^^^^^^^^^ required by this bound in `Cast::cast` + = note: ...because it opted out of dyn-compatibility + | + ::: $DIR/issue-71659.rs:29:11 + | +LL | pub trait Foo: CastTo<[i32]> {} + | --- this trait is not dyn compatible... + = help: only type `[i32; 0]` implements `Foo` within this crate; consider using it directly instead. + = note: `Foo` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/unsized/issue-71659.rs b/tests/ui/unsized/issue-71659.rs index c463ed125bb6..9e1387fa8443 100644 --- a/tests/ui/unsized/issue-71659.rs +++ b/tests/ui/unsized/issue-71659.rs @@ -31,6 +31,6 @@ impl Foo for [i32; 0] {} fn main() { let x: &dyn Foo = &[]; + //~^ ERROR: the trait `Foo` is not dyn compatible let x = x.cast::<[i32]>(); - //~^ ERROR: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied } diff --git a/tests/ui/unsized/issue-91801.rs b/tests/ui/unsized/issue-91801.rs index d906a08a55a2..8b4a3d214d5e 100644 --- a/tests/ui/unsized/issue-91801.rs +++ b/tests/ui/unsized/issue-91801.rs @@ -6,7 +6,7 @@ pub static ALL_VALIDATORS: &[(&'static str, &'static Validator)] = &[("validate that credits and debits balance", &validate_something)]; fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { - //~^ ERROR return type cannot be a trait object without pointer indirection + //~^ ERROR E0277 return Box::new(move |something: &'_ Something| -> Result<(), ()> { first(something).or_else(|_| second(something)) }); diff --git a/tests/ui/unsized/issue-91801.stderr b/tests/ui/unsized/issue-91801.stderr index 28e10f9caa41..192cdc767dd9 100644 --- a/tests/ui/unsized/issue-91801.stderr +++ b/tests/ui/unsized/issue-91801.stderr @@ -1,18 +1,21 @@ -error[E0746]: return type cannot be a trait object without pointer indirection +error[E0277]: the size for values of type `(dyn Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a)` cannot be known at compilation time --> $DIR/issue-91801.rs:8:77 | LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Validator<'a> { | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | -help: consider returning an `impl Trait` instead of a `dyn Trait` + = help: the trait `Sized` is not implemented for `(dyn Fn(&'a Something) -> Result<(), ()> + Send + Sync + 'a)` +note: this type alias is unsized + --> $DIR/issue-91801.rs:3:1 | -LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> impl Validator<'a> { - | ++++ -help: alternatively, box the return type, and wrap all of the returned values in `Box::new` +LL | type Validator<'a> = dyn 'a + Send + Sync + Fn(&'a Something) -> Result<(), ()>; + | ^^^^^^^^^^^^^^^^^^ + = note: the return type of a function must have a statically known size +help: consider boxing the return type, and wrapping all of the returned values in `Box::new` | -LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box> { - | +++++++ + +LL | fn or<'a>(first: &'static Validator<'a>, second: &'static Validator<'a>) -> Box> { + | ++++ + error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0746`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr index 9f07e63e4544..e144b981f3cd 100644 --- a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr +++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr @@ -4,7 +4,7 @@ error: item annotated with `#[unstable_feature_bound]` should not be stable LL | fn bar() {} | ^^^^^^^^^^^ | - = help: If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` + = help: if this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]` error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr index afef024e1b9c..60bb2117df24 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy` +error[E0119]: conflicting implementations of trait `aux::Trait` for type `LocalTy` --> $DIR/unstable_impl_coherence.rs:14:1 | LL | impl aux::Trait for LocalTy {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `unstable_impl_coherence_aux`: - - impl Trait for T + - impl aux::Trait for T where feature(foo) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr index afef024e1b9c..60bb2117df24 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `Trait` for type `LocalTy` +error[E0119]: conflicting implementations of trait `aux::Trait` for type `LocalTy` --> $DIR/unstable_impl_coherence.rs:14:1 | LL | impl aux::Trait for LocalTy {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `unstable_impl_coherence_aux`: - - impl Trait for T + - impl aux::Trait for T where feature(foo) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs index 22100f85f715..c36316dc5fa1 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.rs @@ -12,6 +12,6 @@ use aux::Trait; struct LocalTy; impl aux::Trait for LocalTy {} -//~^ ERROR: conflicting implementations of trait `Trait` for type `LocalTy` +//~^ ERROR: conflicting implementations of trait `aux::Trait` for type `LocalTy` fn main(){} diff --git a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr index 840af730154d..b2e4eb730d84 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr @@ -4,9 +4,9 @@ error[E0283]: type annotations needed LL | vec![].foo(); | ^^^ cannot infer type for struct `Vec<_>` | - = note: multiple `impl`s satisfying `Vec<_>: Trait` found in the `unstable_impl_method_selection_aux` crate: - - impl Trait for Vec; - - impl Trait for Vec + = note: multiple `impl`s satisfying `Vec<_>: aux::Trait` found in the `unstable_impl_method_selection_aux` crate: + - impl aux::Trait for Vec; + - impl aux::Trait for Vec where feature(bar) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/use/issue-18986.stderr b/tests/ui/use/issue-18986.stderr index 350cb18f9527..084fa80c3b6d 100644 --- a/tests/ui/use/issue-18986.stderr +++ b/tests/ui/use/issue-18986.stderr @@ -3,6 +3,11 @@ error[E0574]: expected struct, variant or union type, found trait `Trait` | LL | Trait { x: 42 } => () | ^^^^^ not a struct, variant or union type + | +help: consider importing this struct instead + | +LL + use std::mem::type_info::Trait; + | error: aborting due to 1 previous error diff --git a/tests/ui/use/use-after-move-based-on-type.stderr b/tests/ui/use/use-after-move-based-on-type.stderr index 02a6ed599a92..1e72b3a1e95a 100644 --- a/tests/ui/use/use-after-move-based-on-type.stderr +++ b/tests/ui/use/use-after-move-based-on-type.stderr @@ -8,7 +8,6 @@ LL | let _y = x; LL | println!("{}", x); | ^ value borrowed here after move | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider cloning the value if the performance cost is acceptable | LL | let _y = x.clone(); diff --git a/tests/ui/use/use-path-segment-kw.rs b/tests/ui/use/use-path-segment-kw.rs index 680ecd3d03d4..fffc027ac6fd 100644 --- a/tests/ui/use/use-path-segment-kw.rs +++ b/tests/ui/use/use-path-segment-kw.rs @@ -9,43 +9,43 @@ macro_rules! macro_dollar_crate { use $crate; //~ ERROR `$crate` may not be imported pub use $crate as _dollar_crate; //~ ERROR `$crate` may not be imported - type A2 = ::$crate; //~ ERROR failed to resolve: global paths cannot start with `$crate` + type A2 = ::$crate; //~ ERROR global paths cannot start with `$crate` use ::$crate; //~ ERROR unresolved import `$crate` use ::$crate as _dollar_crate2; //~ ERROR unresolved import `$crate` use ::{$crate}; //~ ERROR unresolved import `$crate` use ::{$crate as _nested_dollar_crate2}; //~ ERROR unresolved import `$crate` - type A3 = foobar::$crate; //~ ERROR failed to resolve: `$crate` in paths can only be used in start position + type A3 = foobar::$crate; //~ ERROR `$crate` in paths can only be used in start position use foobar::$crate; //~ ERROR unresolved import `foobar::$crate` use foobar::$crate as _dollar_crate3; //~ ERROR unresolved import `foobar::$crate` use foobar::{$crate}; //~ ERROR unresolved import `foobar::$crate` use foobar::{$crate as _nested_dollar_crate3}; //~ ERROR unresolved import `foobar::$crate` - type A4 = crate::$crate; //~ ERROR failed to resolve: `$crate` in paths can only be used in start position + type A4 = crate::$crate; //~ ERROR `$crate` in paths can only be used in start position use crate::$crate; //~ ERROR unresolved import `crate::$crate` use crate::$crate as _dollar_crate4; //~ ERROR unresolved import `crate::$crate` use crate::{$crate}; //~ ERROR unresolved import `crate::$crate` use crate::{$crate as _nested_dollar_crate4}; //~ ERROR unresolved import `crate::$crate` - type A5 = super::$crate; //~ ERROR failed to resolve: `$crate` in paths can only be used in start position + type A5 = super::$crate; //~ ERROR `$crate` in paths can only be used in start position use super::$crate; //~ ERROR unresolved import `super::$crate` use super::$crate as _dollar_crate5; //~ ERROR unresolved import `super::$crate` use super::{$crate}; //~ ERROR unresolved import `super::$crate` use super::{$crate as _nested_dollar_crate5}; //~ ERROR unresolved import `super::$crate` - type A6 = self::$crate; //~ ERROR failed to resolve: `$crate` in paths can only be used in start position + type A6 = self::$crate; //~ ERROR `$crate` in paths can only be used in start position use self::$crate; use self::$crate as _dollar_crate6; use self::{$crate}; use self::{$crate as _nested_dollar_crate6}; - type A7 = $crate::$crate; //~ ERROR failed to resolve: `$crate` in paths can only be used in start position + type A7 = $crate::$crate; //~ ERROR `$crate` in paths can only be used in start position use $crate::$crate; //~ ERROR unresolved import `$crate::$crate` use $crate::$crate as _dollar_crate7; //~ ERROR unresolved import `$crate::$crate` use $crate::{$crate}; //~ ERROR unresolved import `$crate::$crate` use $crate::{$crate as _nested_dollar_crate7}; //~ ERROR unresolved import `$crate::$crate` - type A8 = $crate::crate; //~ ERROR failed to resolve: `crate` in paths can only be used in start position + type A8 = $crate::crate; //~ ERROR `crate` in paths can only be used in start position use $crate::crate; //~ ERROR unresolved import `$crate::crate` //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use $crate::crate as _m_crate8; //~ ERROR unresolved import `$crate::crate` @@ -53,13 +53,13 @@ macro_rules! macro_dollar_crate { //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use $crate::{crate as _m_nested_crate8}; //~ ERROR unresolved import `$crate::crate` - type A9 = $crate::super; //~ ERROR failed to resolve: `super` in paths can only be used in start position + type A9 = $crate::super; //~ ERROR `super` in paths can only be used in start position use $crate::super; //~ ERROR unresolved import `$crate::super` use $crate::super as _m_super8; //~ ERROR unresolved import `$crate::super` use $crate::{super}; //~ ERROR unresolved import `$crate::super` use $crate::{super as _m_nested_super8}; //~ ERROR unresolved import `$crate::super` - type A10 = $crate::self; //~ ERROR failed to resolve: `self` in paths can only be used in start position + type A10 = $crate::self; //~ ERROR `self` in paths can only be used in start position use $crate::self; //~ ERROR `$crate` may not be imported //~^ ERROR `self` imports are only allowed within a { } list //~^^ ERROR the name `` is defined multiple times @@ -98,7 +98,7 @@ mod foo { use crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;` pub use crate as _crate; // Good - type B2 = ::crate; //~ ERROR failed to resolve: global paths cannot start with `crate` + type B2 = ::crate; //~ ERROR `crate` use ::crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;` //~^ ERROR unresolved import `crate` use ::crate as _crate2; //~ ERROR unresolved import `crate` @@ -106,7 +106,7 @@ mod foo { //~^ ERROR unresolved import `crate` use ::{crate as _nested_crate2}; //~ ERROR unresolved import `crate` - type B3 = foobar::crate; //~ ERROR failed to resolve: `crate` in paths can only be used in start position + type B3 = foobar::crate; //~ ERROR `crate` in paths can only be used in start position use foobar::crate; //~ ERROR unresolved import `foobar::crate` //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use foobar::crate as _crate3; //~ ERROR unresolved import `foobar::crate` @@ -114,7 +114,7 @@ mod foo { //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use foobar::{crate as _nested_crate3}; //~ ERROR unresolved import `foobar::crate` - type B4 = crate::crate; //~ ERROR failed to resolve: `crate` in paths can only be used in start position + type B4 = crate::crate; //~ ERROR `crate` in paths can only be used in start position use crate::crate; //~ ERROR unresolved import `crate::crate` //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use crate::crate as _crate4; //~ ERROR unresolved import `crate::crate` @@ -122,7 +122,7 @@ mod foo { //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use crate::{crate as _nested_crate4}; //~ ERROR unresolved import `crate::crate` - type B5 = super::crate; //~ ERROR failed to resolve: `crate` in paths can only be used in start position + type B5 = super::crate; //~ ERROR `crate` in paths can only be used in start position use super::crate; //~ ERROR unresolved import `super::crate` //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use super::crate as _crate5; //~ ERROR unresolved import `super::crate` @@ -130,7 +130,7 @@ mod foo { //~^ ERROR crate root imports need to be explicitly named: `use crate as name;` use super::{crate as _nested_crate5}; //~ ERROR unresolved import `super::crate` - type B6 = self::crate; //~ ERROR failed to resolve: `crate` in paths can only be used in start position + type B6 = self::crate; //~ ERROR `crate` in paths can only be used in start position use self::crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;` //~^ ERROR the name `crate` is defined multiple times use self::crate as _crate6; @@ -146,19 +146,19 @@ mod foo { use super; //~ ERROR unresolved import `super` pub use super as _super; //~ ERROR unresolved import `super` - type C2 = ::super; //~ ERROR failed to resolve: global paths cannot start with `super` + type C2 = ::super; //~ ERROR global paths cannot start with `super` use ::super; //~ ERROR unresolved import `super` use ::super as _super2; //~ ERROR unresolved import `super` use ::{super}; //~ ERROR unresolved import `super` use ::{super as _nested_super2}; //~ ERROR unresolved import `super` - type C3 = foobar::super; //~ ERROR failed to resolve: `super` in paths can only be used in start position + type C3 = foobar::super; //~ ERROR `super` in paths can only be used in start position use foobar::super; //~ ERROR unresolved import `foobar::super` use foobar::super as _super3; //~ ERROR unresolved import `foobar::super` use foobar::{super}; //~ ERROR unresolved import `foobar::super` use foobar::{super as _nested_super3}; //~ ERROR unresolved import `foobar::super` - type C4 = crate::super; //~ ERROR failed to resolve: `super` in paths can only be used in start position + type C4 = crate::super; //~ ERROR `super` in paths can only be used in start position use crate::super; //~ ERROR unresolved import `crate::super` use crate::super as _super4; //~ ERROR unresolved import `crate::super` use crate::{super}; //~ ERROR unresolved import `crate::super` @@ -184,7 +184,7 @@ mod foo { use self; //~ ERROR `self` imports are only allowed within a { } list pub use self as _self; //~ ERROR `self` imports are only allowed within a { } list - type D2 = ::self; //~ ERROR failed to resolve: global paths cannot start with `self` + type D2 = ::self; //~ ERROR global paths cannot start with `self` use ::self; //~ ERROR `self` imports are only allowed within a { } list //~^ ERROR unresolved import `{{root}}` use ::self as _self2; //~ ERROR `self` imports are only allowed within a { } list @@ -192,13 +192,13 @@ mod foo { use ::{self}; //~ ERROR `self` import can only appear in an import list with a non-empty prefix use ::{self as _nested_self2}; //~ ERROR `self` import can only appear in an import list with a non-empty prefix - type D3 = foobar::self; //~ ERROR failed to resolve: `self` in paths can only be used in start position + type D3 = foobar::self; //~ ERROR `self` in paths can only be used in start position pub use foobar::qux::self; //~ ERROR `self` imports are only allowed within a { } list pub use foobar::self as _self3; //~ ERROR `self` imports are only allowed within a { } list pub use foobar::baz::{self}; // Good pub use foobar::{self as _nested_self3}; // Good - type D4 = crate::self; //~ ERROR failed to resolve: `self` in paths can only be used in start position + type D4 = crate::self; //~ ERROR `self` in paths can only be used in start position use crate::self; //~ ERROR crate root imports need to be explicitly named: `use crate as name;` //~^ ERROR `self` imports are only allowed within a { } list //~^^ ERROR the name `crate` is defined multiple times @@ -207,7 +207,7 @@ mod foo { //~^ ERROR the name `crate` is defined multiple times pub use crate::{self as _nested_self4}; // Good - type D5 = super::self; //~ ERROR failed to resolve: `self` in paths can only be used in start position + type D5 = super::self; //~ ERROR `self` in paths can only be used in start position use super::self; //~ ERROR unresolved import `super` //~^ ERROR `self` imports are only allowed within a { } list pub use super::self as _self5; //~ ERROR `self` imports are only allowed within a { } list @@ -215,7 +215,7 @@ mod foo { use super::{self}; //~ ERROR unresolved import `super` pub use super::{self as _nested_self5}; //~ ERROR unresolved import `super` - type D6 = self::self; //~ ERROR failed to resolve: `self` in paths can only be used in start position + type D6 = self::self; //~ ERROR `self` in paths can only be used in start position use self::self; //~ ERROR `self` imports are only allowed within a { } list pub use self::self as _self6; //~ ERROR `self` imports are only allowed within a { } list use self::{self}; //~ ERROR unresolved import `self` diff --git a/tests/ui/use/use-path-segment-kw.stderr b/tests/ui/use/use-path-segment-kw.stderr index 407e99059b2a..a5cfa47df3b2 100644 --- a/tests/ui/use/use-path-segment-kw.stderr +++ b/tests/ui/use/use-path-segment-kw.stderr @@ -1062,182 +1062,182 @@ error[E0573]: expected type, found module `self` LL | type D1 = self; | ^^^^ not a type -error[E0433]: failed to resolve: global paths cannot start with `$crate` +error[E0433]: global paths cannot start with `$crate` --> $DIR/use-path-segment-kw.rs:12:21 | LL | type A2 = ::$crate; - | ^^^^^^ global paths cannot start with `$crate` + | ^^^^^^ cannot start with this ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position +error[E0433]: `$crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:18:27 | LL | type A3 = foobar::$crate; - | ^^^^^^ `$crate` in paths can only be used in start position + | ^^^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position +error[E0433]: `$crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:24:26 | LL | type A4 = crate::$crate; - | ^^^^^^ `$crate` in paths can only be used in start position + | ^^^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position +error[E0433]: `$crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:30:26 | LL | type A5 = super::$crate; - | ^^^^^^ `$crate` in paths can only be used in start position + | ^^^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position +error[E0433]: `$crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:36:25 | LL | type A6 = self::$crate; - | ^^^^^^ `$crate` in paths can only be used in start position + | ^^^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position +error[E0433]: `$crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:42:27 | LL | type A7 = $crate::$crate; - | ^^^^^^ `$crate` in paths can only be used in start position + | ^^^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: `crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:48:27 | LL | type A8 = $crate::crate; - | ^^^^^ `crate` in paths can only be used in start position + | ^^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `super` in paths can only be used in start position +error[E0433]: `super` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:56:27 | LL | type A9 = $crate::super; - | ^^^^^ `super` in paths can only be used in start position + | ^^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `self` in paths can only be used in start position +error[E0433]: `self` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:62:28 | LL | type A10 = $crate::self; - | ^^^^ `self` in paths can only be used in start position + | ^^^^ can only be used in path start position ... LL | macro_dollar_crate!(); | --------------------- in this macro invocation | = note: this error originates in the macro `macro_dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: global paths cannot start with `crate` +error[E0433]: global paths cannot start with `crate` --> $DIR/use-path-segment-kw.rs:101:21 | LL | type B2 = ::crate; - | ^^^^^ global paths cannot start with `crate` + | ^^^^^ cannot start with this -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: `crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:109:27 | LL | type B3 = foobar::crate; - | ^^^^^ `crate` in paths can only be used in start position + | ^^^^^ can only be used in path start position -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: `crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:117:26 | LL | type B4 = crate::crate; - | ^^^^^ `crate` in paths can only be used in start position + | ^^^^^ can only be used in path start position -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: `crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:125:26 | LL | type B5 = super::crate; - | ^^^^^ `crate` in paths can only be used in start position + | ^^^^^ can only be used in path start position -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: `crate` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:133:25 | LL | type B6 = self::crate; - | ^^^^^ `crate` in paths can only be used in start position + | ^^^^^ can only be used in path start position -error[E0433]: failed to resolve: global paths cannot start with `super` +error[E0433]: global paths cannot start with `super` --> $DIR/use-path-segment-kw.rs:149:21 | LL | type C2 = ::super; - | ^^^^^ global paths cannot start with `super` + | ^^^^^ cannot start with this -error[E0433]: failed to resolve: `super` in paths can only be used in start position +error[E0433]: `super` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:155:27 | LL | type C3 = foobar::super; - | ^^^^^ `super` in paths can only be used in start position + | ^^^^^ can only be used in path start position -error[E0433]: failed to resolve: `super` in paths can only be used in start position +error[E0433]: `super` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:161:26 | LL | type C4 = crate::super; - | ^^^^^ `super` in paths can only be used in start position + | ^^^^^ can only be used in path start position -error[E0433]: failed to resolve: global paths cannot start with `self` +error[E0433]: global paths cannot start with `self` --> $DIR/use-path-segment-kw.rs:187:21 | LL | type D2 = ::self; - | ^^^^ global paths cannot start with `self` + | ^^^^ cannot start with this -error[E0433]: failed to resolve: `self` in paths can only be used in start position +error[E0433]: `self` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:195:27 | LL | type D3 = foobar::self; - | ^^^^ `self` in paths can only be used in start position + | ^^^^ can only be used in path start position -error[E0433]: failed to resolve: `self` in paths can only be used in start position +error[E0433]: `self` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:201:26 | LL | type D4 = crate::self; - | ^^^^ `self` in paths can only be used in start position + | ^^^^ can only be used in path start position -error[E0433]: failed to resolve: `self` in paths can only be used in start position +error[E0433]: `self` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:210:26 | LL | type D5 = super::self; - | ^^^^ `self` in paths can only be used in start position + | ^^^^ can only be used in path start position -error[E0433]: failed to resolve: `self` in paths can only be used in start position +error[E0433]: `self` in paths can only be used in start position --> $DIR/use-path-segment-kw.rs:218:25 | LL | type D6 = self::self; - | ^^^^ `self` in paths can only be used in start position + | ^^^^ can only be used in path start position error: aborting due to 141 previous errors diff --git a/tests/ui/use/use-self-type.rs b/tests/ui/use/use-self-type.rs index 3b4ce4297019..4453049acff0 100644 --- a/tests/ui/use/use-self-type.rs +++ b/tests/ui/use/use-self-type.rs @@ -4,7 +4,7 @@ impl S { fn f() {} fn g() { use Self::f; //~ ERROR unresolved import - pub(in Self::f) struct Z; //~ ERROR failed to resolve: `Self` + pub(in Self::f) struct Z; //~ ERROR cannot find `Self` } } diff --git a/tests/ui/use/use-self-type.stderr b/tests/ui/use/use-self-type.stderr index 498df34fe325..086b7a4d8222 100644 --- a/tests/ui/use/use-self-type.stderr +++ b/tests/ui/use/use-self-type.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `Self` cannot be used in imports +error[E0433]: cannot find `Self` in this scope --> $DIR/use-self-type.rs:7:16 | LL | pub(in Self::f) struct Z; diff --git a/tests/ui/use/use-super-global-path.rs b/tests/ui/use/use-super-global-path.rs index 64bfd14b7e7d..d00c6964dea1 100644 --- a/tests/ui/use/use-super-global-path.rs +++ b/tests/ui/use/use-super-global-path.rs @@ -4,11 +4,12 @@ struct S; struct Z; mod foo { - use ::super::{S, Z}; //~ ERROR global paths cannot start with `super` - //~| ERROR global paths cannot start with `super` + use ::super::{S, Z}; + //~^ ERROR: global paths cannot start with `super` + //~| ERROR: global paths cannot start with `super` pub fn g() { - use ::super::main; //~ ERROR global paths cannot start with `super` + use ::super::main; //~ ERROR: global paths cannot start with `super` main(); } } diff --git a/tests/ui/use/use-super-global-path.stderr b/tests/ui/use/use-super-global-path.stderr index 00d172f4799a..dd853aab4830 100644 --- a/tests/ui/use/use-super-global-path.stderr +++ b/tests/ui/use/use-super-global-path.stderr @@ -1,22 +1,22 @@ -error[E0433]: failed to resolve: global paths cannot start with `super` +error[E0433]: global paths cannot start with `super` --> $DIR/use-super-global-path.rs:7:11 | LL | use ::super::{S, Z}; - | ^^^^^ global paths cannot start with `super` + | ^^^^^ cannot start with this -error[E0433]: failed to resolve: global paths cannot start with `super` +error[E0433]: global paths cannot start with `super` --> $DIR/use-super-global-path.rs:7:11 | LL | use ::super::{S, Z}; - | ^^^^^ global paths cannot start with `super` + | ^^^^^ cannot start with this | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0433]: failed to resolve: global paths cannot start with `super` - --> $DIR/use-super-global-path.rs:11:15 +error[E0433]: global paths cannot start with `super` + --> $DIR/use-super-global-path.rs:12:15 | LL | use ::super::main; - | ^^^^^ global paths cannot start with `super` + | ^^^^^ cannot start with this error: aborting due to 3 previous errors diff --git a/tests/ui/use/use.rs b/tests/ui/use/use.rs index 25b8e529c432..c6b6724ef7c1 100644 --- a/tests/ui/use/use.rs +++ b/tests/ui/use/use.rs @@ -1,9 +1,7 @@ //@ run-pass -#![allow(stable_features)] - #![allow(unused_imports)] -#![feature(no_core, core)] +#![feature(no_core)] #![no_core] extern crate std; diff --git a/tests/ui/wasm/wasm-import-module.stderr b/tests/ui/wasm/wasm-import-module.stderr index f5ea449839bb..6171f04f862c 100644 --- a/tests/ui/wasm/wasm-import-module.stderr +++ b/tests/ui/wasm/wasm-import-module.stderr @@ -7,21 +7,6 @@ LL | #[link(name = "...", wasm_import_module)] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module)] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/wasm-import-module.rs:6:1 @@ -32,21 +17,6 @@ LL | #[link(name = "...", wasm_import_module(x))] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module(x))] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/wasm-import-module.rs:9:1 @@ -57,21 +27,6 @@ LL | #[link(name = "...", wasm_import_module())] | expected this to be of the form `wasm_import_module = "..."` | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...")] - | -LL - #[link(name = "...", wasm_import_module())] -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | - = and 1 other candidate error: `wasm_import_module` is incompatible with other arguments in `#[link]` attributes --> $DIR/wasm-import-module.rs:12:8 diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs index 519e913480ec..13d7a800c51f 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs @@ -4,12 +4,13 @@ trait Foo> { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| ERROR cycle detected when computing type of `Foo::N` - //~| ERROR cycle detected when computing type of `Foo::N` + //~| ERROR `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter fn func() {} } trait Bar> {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! +//~| ERROR `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr index 0ecb3e74eb57..f9a855d3b93b 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr @@ -44,26 +44,22 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error[E0391]: cycle detected when computing type of `Foo::N` - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:11 +error: `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:20 | LL | trait Foo> { - | ^^^^^^^^^^^^^^^ + | ^^^^^^ | -note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 + = note: the only supported types are integers, `bool`, and `char` + +error: `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20 | LL | trait Bar> {} - | ^^^^^^^^^^^^^^^ - = note: ...which again requires computing type of `Foo::N`, completing the cycle -note: cycle used when checking that `Foo` is well-formed - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:3:1 + | ^^^^^^ | -LL | trait Foo> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + = note: the only supported types are integers, `bool`, and `char` -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/wf/issue-87495.stderr b/tests/ui/wf/issue-87495.stderr index bf79535df116..49651e8d6c05 100644 --- a/tests/ui/wf/issue-87495.stderr +++ b/tests/ui/wf/issue-87495.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `T` is not dyn compatible - --> $DIR/issue-87495.rs:4:25 + --> $DIR/issue-87495.rs:4:29 | LL | const CONST: (bool, dyn T); - | ^^^^^ `T` is not dyn compatible + | ^ `T` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit @@ -11,13 +11,8 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait T { | - this trait is not dyn compatible... LL | const CONST: (bool, dyn T); - | ^^^^^ ...because it contains this associated `const` + | ^^^^^ ...because it contains associated const `CONST` = help: consider moving `CONST` to another trait -help: you might have meant to use `Self` to refer to the implementing type - | -LL - const CONST: (bool, dyn T); -LL + const CONST: (bool, Self); - | error: aborting due to 1 previous error diff --git a/tests/ui/wf/wf-where-clauses-pre-normalization.rs b/tests/ui/wf/wf-where-clauses-pre-normalization.rs new file mode 100644 index 000000000000..16c102f1faef --- /dev/null +++ b/tests/ui/wf/wf-where-clauses-pre-normalization.rs @@ -0,0 +1,20 @@ +// This is a test, extracted from `modcholesky`, that used to pass wfcheck because we checked +// well-formedness of where-clauses *after* normalization. We generally want to move to always check +// WF pre-normalization. + +pub struct View(A); +pub trait Data { + type Elem; +} +impl<'a, A> Data for View<&'a A> { + type Elem = A; +} + +pub fn repro<'a, T>() +where + as Data>::Elem: Sized, + //~^ ERROR: the parameter type `T` may not live long enough +{ +} + +fn main() {} diff --git a/tests/ui/wf/wf-where-clauses-pre-normalization.stderr b/tests/ui/wf/wf-where-clauses-pre-normalization.stderr new file mode 100644 index 000000000000..a7836cae5db2 --- /dev/null +++ b/tests/ui/wf/wf-where-clauses-pre-normalization.stderr @@ -0,0 +1,17 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/wf-where-clauses-pre-normalization.rs:15:34 + | +LL | pub fn repro<'a, T>() + | -- the parameter type `T` must be valid for the lifetime `'a` as defined here... +LL | where +LL | as Data>::Elem: Sized, + | ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound + | +LL | pub fn repro<'a, T: 'a>() + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/where-clauses/projection-bound-unsatisfied-item-bounds-mit-opt-ice.rs b/tests/ui/where-clauses/projection-bound-unsatisfied-item-bounds-mit-opt-ice.rs index 80eec709eecb..9448c8a2f911 100644 --- a/tests/ui/where-clauses/projection-bound-unsatisfied-item-bounds-mit-opt-ice.rs +++ b/tests/ui/where-clauses/projection-bound-unsatisfied-item-bounds-mit-opt-ice.rs @@ -2,7 +2,7 @@ //@ build-pass // A regression test for #149081. The environment of `size` and `align` -// currently means that the item bound of`T::Assoc` doesn't hold. This can +// currently means that the item bound of `T::Assoc` doesn't hold. This can // result in normalization failures and ICE during MIR optimizations. // // This will no longer be an issue once #149283 is implemented. diff --git a/tests/ui/where-clauses/unsupported_attribute.stderr b/tests/ui/where-clauses/unsupported_attribute.stderr index 9ebc14c40a14..e69eff976c3f 100644 --- a/tests/ui/where-clauses/unsupported_attribute.stderr +++ b/tests/ui/where-clauses/unsupported_attribute.stderr @@ -64,7 +64,7 @@ error: `#[deprecated]` attribute cannot be used on where predicates LL | #[deprecated] T: Trait, | ^^^^^^^^^^^^^ | - = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements error: `#[deprecated]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:25:5 @@ -72,7 +72,7 @@ error: `#[deprecated]` attribute cannot be used on where predicates LL | #[deprecated] 'a: 'static, | ^^^^^^^^^^^^^ | - = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements error: `#[automatically_derived]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:26:5 diff --git a/triagebot.toml b/triagebot.toml index 6ad8dd6b4c88..6c6daac9cf3b 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -76,9 +76,9 @@ add-labels = ["beta-nominated"] [ping.windows] message = """\ -Hey Windows Group! This bug has been identified as a good "Windows candidate". +Hey Windows Group! This issue has been identified as a good "Windows candidate". In case it's useful, here are some [instructions] for tackling these sorts of -bugs. Maybe take a look? +issues. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/windows.html @@ -87,20 +87,31 @@ label = "O-windows" [ping.arm] message = """\ -Hey ARM Group! This bug has been identified as a good "ARM candidate". +Hey ARM Group! This issue has been identified as a good "ARM candidate". In case it's useful, here are some [instructions] for tackling these sorts of -bugs. Maybe take a look? +issues. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/arm.html """ label = "O-ARM" +[ping.loongarch] +message = """\ +Hey LoongArch Group! This issue has been identified as a good "LoongArch candidate". +In case it's useful, here are some [instructions] for tackling these sorts of +issues. Maybe take a look? +Thanks! <3 + +[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/loongarch.html +""" +label = "O-loongarch" + [ping.risc-v] message = """\ -Hey RISC-V Group! This bug has been identified as a good "RISC-V candidate". +Hey RISC-V Group! This issue has been identified as a good "RISC-V candidate". In case it's useful, here are some [instructions] for tackling these sorts of -bugs. Maybe take a look? +issues. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/risc-v.html @@ -218,6 +229,7 @@ exclude_labels = [ "T-infra", "T-release", "requires-nightly", + "F-*", ] [autolabel."T-rustdoc"] @@ -228,7 +240,7 @@ trigger_files = [ "src/rustdoc-json-types", # Tests - "tests/rustdoc", + "tests/rustdoc-html", "tests/rustdoc-ui", "tests/rustdoc-gui", "tests/rustdoc-js/", @@ -303,7 +315,7 @@ trigger_labels = [ ] trigger_files = [ "src/librustdoc/html/", - "tests/rustdoc/", + "tests/rustdoc-html/", "tests/rustdoc-gui/", "tests/rustdoc-js/", "tests/rustdoc-js-std/", @@ -320,6 +332,14 @@ trigger_labels = [ "A-type-based-search", ] +[autolabel."A-rustdoc-js"] +trigger_files = [ + "src/librustdoc/html/static/js/", + "src/librustdoc/html/static/css/", + "tests/rustdoc-js/", + "tests/rustdoc-js-std/", +] + [autolabel."T-compiler"] trigger_files = [ # Source code @@ -455,8 +475,7 @@ trigger_files = [ [autolabel."O-wasi"] trigger_files = [ - "library/std/src/sys/pal/wasip1", - "library/std/src/sys/pal/wasip2", + "library/std/src/sys/pal/wasi", "library/std/src/os/wasi" ] @@ -480,6 +499,7 @@ trigger_files = [ "bootstrap.example.toml", "src/bootstrap", "src/build_helper", + "src/tools/build-manifest", "src/tools/rust-installer", "src/tools/x", "src/stage0", @@ -520,7 +540,6 @@ trigger_files = [ [autolabel."A-query-system"] trigger_files = [ - "compiler/rustc_query_system", "compiler/rustc_query_impl", "compiler/rustc_macros/src/query.rs" ] @@ -775,7 +794,8 @@ zulip_stream = 474880 # #t-compiler/backports topic = "#{number}: stable-nominated" message_on_add = [ """\ -@**channel** PR #{number} "{title}" has been nominated for stable backport. +PR #{number} "{title}" fixes a regression and has been nominated for backport. +{recipients}, what do you think about it? """, """\ /poll Approve stable backport of #{number}? @@ -943,15 +963,15 @@ cc = ["@lcnr"] [mentions."compiler/rustc_middle/src/ty/relate.rs"] message = "changes to the core type system" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_infer/src/infer/relate"] message = "changes to the core type system" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"] message = "changes to `inspect_obligations.rs`" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_middle/src/mir/interpret"] message = "Some changes occurred to the CTFE / Miri interpreter" @@ -963,7 +983,7 @@ cc = ["@rust-lang/wg-mir-opt"] [mentions."compiler/rustc_trait_selection/src/traits/wf.rs"] message = "changes to the core type system" -cc = ["@compiler-errors", "@lcnr"] +cc = ["@lcnr"] [mentions."compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"] message = "Some changes occurred in `const_evaluatable.rs`" @@ -986,12 +1006,19 @@ message = """ Some changes occurred in engine.rs, potentially modifying the public API \ of `ObligationCtxt`. """ -cc = ["@lcnr", "@compiler-errors"] +cc = ["@lcnr"] [mentions."compiler/rustc_hir_analysis/src/hir_ty_lowering"] message = "HIR ty lowering was modified" cc = ["@fmease"] +[mentions."library/core/src/mem/type_info.rs"] +message = """ +The reflection data structures are tied exactly to the implementation +in the compiler. Make sure to also adjust `rustc_const_eval/src/const_eval/type_info.rs` +""" +cc = ["@oli-obk"] + [mentions."compiler/rustc_error_codes/src/lib.rs"] message = "Some changes occurred in diagnostic error codes" cc = ["@GuillaumeGomez"] @@ -1048,6 +1075,14 @@ gets adapted for the changes, if necessary. """ cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"] +[mentions."library/core/src/num/{dec2flt,flt2dec}"] +message = "Some changes occurred in float parsing" +cc = ["@tgross35"] + +[mentions."library/core/src/fmt/num.rs"] +message = "Some changes occurred in integer formatting" +cc = ["@tgross35"] + [mentions."library/portable-simd"] message = """ Portable SIMD is developed in its own repository. If possible, consider \ @@ -1135,7 +1170,7 @@ cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@vakaras"] [mentions."compiler/rustc_error_messages"] message = "`rustc_error_messages` was changed" -cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] +cc = ["@davidtwco", "@TaKO8Ki"] [mentions."compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs"] message = "`rustc_errors::annotate_snippet_emitter_writer` was changed" @@ -1147,15 +1182,15 @@ cc = ["@Muscraft"] [mentions."compiler/rustc_errors/src/translation.rs"] message = "`rustc_errors::translation` was changed" -cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] +cc = ["@davidtwco", "@TaKO8Ki", "@JonathanBrouwer"] [mentions."compiler/rustc_macros/src/diagnostics"] message = "`rustc_macros::diagnostics` was changed" -cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"] +cc = ["@davidtwco", "@TaKO8Ki", "@JonathanBrouwer"] [mentions."compiler/rustc_public"] message = "This PR changes rustc_public" -cc = ["@oli-obk", "@celinval", "@ouz-a"] +cc = ["@oli-obk", "@celinval", "@ouz-a", "@makai410"] [mentions."compiler/rustc_target/src/spec"] message = """ @@ -1339,11 +1374,11 @@ message = "The rustc-dev-guide subtree was changed. If this PR *only* touches th cc = ["@BoxyUwU", "@jieyouxu", "@kobzol", "@tshepang"] [mentions."compiler/rustc_passes/src/check_attr.rs"] -cc = ["@jdonszelmann"] +cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."compiler/rustc_attr_parsing"] -cc = ["@jdonszelmann"] +cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."compiler/rustc_hir/src/attrs"] -cc = ["@jdonszelmann"] +cc = ["@jdonszelmann", "@JonathanBrouwer"] [mentions."src/tools/enzyme"] cc = ["@ZuseZ4"] @@ -1413,29 +1448,6 @@ compiler_leads = [ "@davidtwco", "@wesleywiser", ] -compiler = [ - "@BoxyUwU", - "@chenyukang", - "@compiler-errors", - "@davidtwco", - "@eholk", - "@fee1-dead", - "@fmease", - "@jackh726", - "@jieyouxu", - "@jdonszelmann", - "@JonathanBrouwer", - "@lcnr", - "@madsmtm", - "@mati865", - "@Nadrieril", - "@nnethercote", - "@oli-obk", - "@petrochenkov", - "@SparrowLii", - "@WaffleLapkin", - "@wesleywiser", -] libs = [ "@Mark-Simulacrum", "@workingjubilee", @@ -1452,11 +1464,6 @@ infra-ci = [ "@jdno", "@jieyouxu", ] -rustdoc = [ - "@GuillaumeGomez", - "@notriddle", - "@fmease", -] docs = [ "@ehuss", "@GuillaumeGomez", @@ -1475,13 +1482,12 @@ incremental = [ "@wesleywiser", ] diagnostics = [ - "@compiler-errors", "@davidtwco", "@oli-obk", "@chenyukang", + "@TaKO8Ki" ] parser = [ - "@compiler-errors", "@davidtwco", "@nnethercote", "@petrochenkov", @@ -1506,48 +1512,25 @@ mir-opt = [ "@wesleywiser", "@saethlin", ] -types = [ - "@compiler-errors", - "@jackh726", - "@lcnr", - "@oli-obk", - "@spastorino", - "@BoxyUwU", -] borrowck = [ "@davidtwco", "@matthewjasper" ] ast_lowering = [ - "@compiler-errors", "@spastorino", ] debuginfo = [ "@davidtwco" ] fallback = [ - "@Mark-Simulacrum" + "@Mark-Simulacrum", + "@jieyouxu", ] style-team = [ "@calebcartwright", "@joshtriplett", "@traviscross", ] -project-const-traits = [ - "@compiler-errors", - "@fee1-dead", - "@fmease", - "@oli-obk", -] -project-stable-mir = [ - "@celinval", - "@oli-obk", - "@scottmcm", -] -project-exploit-mitigations = [ - "@cuviper", - "@rcvalle", -] compiletest = [ "@jieyouxu", ] @@ -1572,8 +1555,11 @@ dep-bumps = [ "/compiler/rustc_llvm" = ["@cuviper"] "/compiler/rustc_codegen_llvm/src/debuginfo" = ["compiler", "debuginfo"] "/compiler/rustc_codegen_ssa" = ["compiler", "codegen"] +"/compiler/rustc_middle/src/dep_graph" = ["compiler", "incremental", "query-system"] +"/compiler/rustc_middle/src/ich" = ["compiler", "incremental", "query-system"] "/compiler/rustc_middle/src/mir" = ["compiler", "mir"] "/compiler/rustc_middle/src/traits" = ["compiler", "types"] +"/compiler/rustc_middle/src/query" = ["compiler", "query-system"] "/compiler/rustc_middle/src/ty" = ["compiler", "types"] "/compiler/rustc_const_eval/src/interpret" = ["compiler", "mir"] "/compiler/rustc_mir_build/src/builder" = ["compiler", "mir"] @@ -1582,9 +1568,6 @@ dep-bumps = [ "/compiler/rustc_parse" = ["compiler", "parser"] "/compiler/rustc_parse/src/lexer" = ["compiler", "lexer"] "/compiler/rustc_query_impl" = ["compiler", "query-system"] -"/compiler/rustc_query_system" = ["compiler", "query-system"] -"/compiler/rustc_query_system/src/dep_graph" = ["compiler", "incremental", "query-system"] -"/compiler/rustc_query_system/src/ich" = ["compiler", "incremental", "query-system"] "/compiler/rustc_trait_selection" = ["compiler", "types"] "/compiler/rustc_traits" = ["compiler", "types"] "/compiler/rustc_type_ir" = ["compiler", "types"] @@ -1617,17 +1600,18 @@ dep-bumps = [ "/src/llvm-project" = ["@cuviper"] "/src/rustdoc-json-types" = ["rustdoc"] "/src/stage0" = ["bootstrap"] -"/tests/run-make" = ["@jieyouxu"] -"/tests/run-make-cargo" = ["@jieyouxu"] -"/tests/rustdoc" = ["rustdoc"] +"/tests/run-make" = ["compiler"] +"/tests/run-make-cargo" = ["compiler"] +"/tests/rustdoc-html" = ["rustdoc"] "/tests/rustdoc-gui" = ["rustdoc"] "/tests/rustdoc-js-std" = ["rustdoc"] "/tests/rustdoc-js/" = ["rustdoc"] "/tests/rustdoc-json" = ["@aDotInTheVoid"] "/tests/rustdoc-ui" = ["rustdoc"] "/tests/ui" = ["compiler"] +"/src/tools/build-manifest" = ["bootstrap"] "/src/tools/cargo" = ["@ehuss"] -"/src/tools/compiletest" = ["bootstrap", "@wesleywiser", "@oli-obk", "@compiler-errors", "@jieyouxu"] +"/src/tools/compiletest" = ["bootstrap", "@wesleywiser", "@oli-obk", "@jieyouxu"] "/src/tools/linkchecker" = ["@ehuss"] "/src/tools/opt-dist" = ["@kobzol"] "/src/tools/run-make-support" = ["@jieyouxu"] @@ -1680,12 +1664,6 @@ days-threshold = 28 # Documentation at: https://forge.rust-lang.org/triagebot/issue-links.html [issue-links] -# Prevents mentions in commits to avoid users being spammed -# Documentation at: https://forge.rust-lang.org/triagebot/no-mentions.html -[no-mentions] -# Subtree update authors can't fix it, no point in warning. -exclude-titles = ["subtree update"] - # Allow members to formally register concerns (`@rustbot concern my concern`) # Documentation at: https://forge.rust-lang.org/triagebot/concern.html [concern] diff --git a/typos.toml b/typos.toml index 758239ffe751..3c95a45d572d 100644 --- a/typos.toml +++ b/typos.toml @@ -1,3 +1,6 @@ +# Config for the `typos` crate, used by `./x test tidy --extra-checks=spellcheck`. +# See also: https://github.com/crate-ci/typos/blob/v1.28.2/docs/reference.md + [files] extend-exclude = [ # exclude git (sub)modules and generated content @@ -13,54 +16,67 @@ extend-exclude = [ ] [default.extend-words] -# Add exclusions here, lines should be like `x = "x"`, where `x` is excluded word. +# Allowlist for words that look like typos but are not, or aren't worth fixing +# right now. Entries should look like `mipsel = "mipsel"`. # -# Also see docs: https://github.com/crate-ci/typos/blob/v1.28.2/docs/reference.md -arange = "arange" +# tidy-alphabetical-start +arange = "arange" # short for A-range childs = "childs" clonable = "clonable" -Datas = "Datas" -filetimes = "filetimes" +filetimes = "filetimes" # short for "file times", not a typo for "lifetimes" leafs = "leafs" -makro = "makro" +makro = "makro" # deliberate misspelling to avoid `macro` keyword misformed = "misformed" moreso = "moreso" -optin = "optin" +numer = "numer" # short for numerator, not a typo for "number" +optin = "optin" # short for opt-in publically = "publically" -rplace = "rplace" -smove = "smove" +rplace = "rplace" # short for R-place splitted = "splitted" -taits = "taits" +taits = "taits" # lowercase for TAITs (type alias impl trait) targetting = "targetting" unparseable = "unparseable" unstability = "unstability" -unstalled = "unstalled" +unstalled = "unstalled" # short for un-stalled +# tidy-alphabetical-end -# this can be valid word, depends on dictionary edition -#matcheable = "matcheable" +# Denylist to forbid misspelled words that aren't detected by the built-in +# dictionary. Entries should look like `mipsel = ""` or `mipsel = "misspell"`; +# the non-empty form can be automatically fixed by `--bless`. +# +# tidy-alphabetical-start +definitinon = "definition" +dependy = "" +similarlty = "similarity" +# tidy-alphabetical-end [default.extend-identifiers] -# An entry goes here if the typo is part of some existing ident -# where you want to keep it, but don't want to allow -# such typos everywhere. +# Allowlist for specific identifiers that should be permitted even though they +# appear to contain typos that would be forbidden in other identifiers. # -# I.e. you don't want (or can't) fix some constant name, like -# `DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME` but actually -# want to see `INVAILD` typo fixed in other places. -debug_aranges = "debug_aranges" +# For example, you might want to allow a specific constant like +# `DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME`, but still want to forbid +# the typo `INVAILD` in other places. +# +# tidy-alphabetical-start DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME = "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME" -EnzymeTypeTreeShiftIndiciesEq = "EnzymeTypeTreeShiftIndiciesEq" ERRNO_ACCES = "ERRNO_ACCES" ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS = "ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS" ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC = "ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC" ERROR_FILENAME_EXCED_RANGE = "ERROR_FILENAME_EXCED_RANGE" ERROR_MCA_OCCURED = "ERROR_MCA_OCCURED" ERROR_REQ_NOT_ACCEP = "ERROR_REQ_NOT_ACCEP" -Oppen = "Oppen" +EnzymeTypeTreeShiftIndiciesEq = "EnzymeTypeTreeShiftIndiciesEq" +EnzymeTypeTreeShiftIndiciesEqFn = "EnzymeTypeTreeShiftIndiciesEqFn" +Oppen = "Oppen" # Derek C. Oppen, author of "Pretty Printing" (1979) # typos treats this as two different camelcase words (`SETTIN` and `Gs`) # Tracked in: https://github.com/crate-ci/typos/issues/745 SETTINGs = "SETTINGs" -tolen = "tolen" +debug_aranges = "debug_aranges" # debug A-ranges +key_smove = "key_smove" # shifted move key, used by terminfo +shift_indicies_eq = "shift_indicies_eq" +tolen = "tolen" # length of "to" buffer, used by `sendto` in Windows sockets +# tidy-alphabetical-end [default] extend-ignore-words-re = [ diff --git a/x b/x index 4fce0be219e7..a8acbd4d5ac6 100755 --- a/x +++ b/x @@ -29,16 +29,19 @@ xpy=$(dirname "$(realpath "$0")")/x.py # On MacOS, `py` tries to install "Developer command line tools". Try `python3` first. # NOTE: running `bash -c ./x` from Windows doesn't set OSTYPE. case ${OSTYPE:-} in - cygwin*|msys*) SEARCH="py python3 python python2";; - *) SEARCH="python3 python py python2";; + cygwin*|msys*) SEARCH="py python3 python python2 uv";; + *) SEARCH="python3 python py python2 uv";; esac for SEARCH_PYTHON in $SEARCH; do if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then - if [ $SEARCH_PYTHON = py ]; then - extra_arg="-3" - else - extra_arg="" - fi + case $SEARCH_PYTHON in + py) + extra_arg="-3";; + uv) + extra_arg="run";; + *) + extra_arg="";; + esac exec "$python" $extra_arg "$xpy" "$@" fi done

` (where P is one of the previous types except `Self`) error[E0038]: the trait `Foo` is not dyn compatible - --> $DIR/inference_var_self_argument.rs:5:5 + --> $DIR/inference_var_self_argument.rs:5:33 | LL | async fn foo(self: &dyn Foo) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible + | ^ `Foo` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit diff --git a/tests/ui/async-await/issue-61076.rs b/tests/ui/async-await/issue-61076.rs index 0a679a95970a..6fe7846ea8d9 100644 --- a/tests/ui/async-await/issue-61076.rs +++ b/tests/ui/async-await/issue-61076.rs @@ -4,7 +4,7 @@ use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; -struct T; //~ HELP the trait `Try` is not implemented for `T` +struct T; //~ HELP the nightly-only, unstable trait `Try` is not implemented for `T` struct Tuple(i32); @@ -41,7 +41,7 @@ async fn foo() -> Result<(), ()> { async fn bar() -> Result<(), ()> { foo()?; //~ ERROR the `?` operator can only be applied to values that implement `Try` //~^ NOTE the `?` operator cannot be applied to type `impl Future>` - //~| HELP the trait `Try` is not implemented for `impl Future>` + //~| HELP the nightly-only, unstable trait `Try` is not implemented for `impl Future>` //~| HELP consider `await`ing on the `Future` //~| NOTE in this expansion of desugaring of operator `?` //~| NOTE in this expansion of desugaring of operator `?` diff --git a/tests/ui/async-await/issue-61076.stderr b/tests/ui/async-await/issue-61076.stderr index 7d46abe4a66b..dd49d00246cd 100644 --- a/tests/ui/async-await/issue-61076.stderr +++ b/tests/ui/async-await/issue-61076.stderr @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | foo()?; | ^^^^^^ the `?` operator cannot be applied to type `impl Future>` | - = help: the trait `Try` is not implemented for `impl Future>` + = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>` help: consider `await`ing on the `Future` | LL | foo().await?; @@ -16,7 +16,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | t?; | ^^ the `?` operator cannot be applied to type `T` | -help: the trait `Try` is not implemented for `T` +help: the nightly-only, unstable trait `Try` is not implemented for `T` --> $DIR/issue-61076.rs:7:1 | LL | struct T; diff --git a/tests/ui/async-await/issue-64130-3-other.stderr b/tests/ui/async-await/issue-64130-3-other.stderr index d683366ed473..531a7028f7e0 100644 --- a/tests/ui/async-await/issue-64130-3-other.stderr +++ b/tests/ui/async-await/issue-64130-3-other.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future $DIR/issue-64130-3-other.rs:25:12 | LL | async fn bar() { - | -------------- within this `impl Future` + | - within this `impl Future` ... LL | is_qux(bar()); | ^^^^^ unsatisfied trait bound diff --git a/tests/ui/async-await/issue-70818.rs b/tests/ui/async-await/issue-70818.rs index c11332fe7d84..af9f33d9050b 100644 --- a/tests/ui/async-await/issue-70818.rs +++ b/tests/ui/async-await/issue-70818.rs @@ -2,9 +2,8 @@ use std::future::Future; fn foo(ty: T, ty1: U) -> impl Future + Send { - //~^ ERROR future cannot be sent between threads safely + //~^ ERROR: future cannot be sent between threads safely async { (ty, ty1) } - //~^ ERROR future cannot be sent between threads safely } fn main() {} diff --git a/tests/ui/async-await/issue-70818.stderr b/tests/ui/async-await/issue-70818.stderr index 07fd20cdd77e..8de6a825042b 100644 --- a/tests/ui/async-await/issue-70818.stderr +++ b/tests/ui/async-await/issue-70818.stderr @@ -1,24 +1,3 @@ -error: future cannot be sent between threads safely - --> $DIR/issue-70818.rs:6:5 - | -LL | async { (ty, ty1) } - | ^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` - | -note: captured value is not `Send` - --> $DIR/issue-70818.rs:6:18 - | -LL | async { (ty, ty1) } - | ^^^ has type `U` which is not `Send` -note: required by a bound in an opaque type - --> $DIR/issue-70818.rs:4:69 - | -LL | fn foo(ty: T, ty1: U) -> impl Future + Send { - | ^^^^ -help: consider restricting type parameter `U` with trait `Send` - | -LL | fn foo(ty: T, ty1: U) -> impl Future + Send { - | +++++++++++++++++++ - error: future cannot be sent between threads safely --> $DIR/issue-70818.rs:4:38 | @@ -35,5 +14,5 @@ help: consider restricting type parameter `U` with trait `Send` LL | fn foo(ty: T, ty1: U) -> impl Future + Send { | +++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/async-await/issue-70935-complex-spans.rs b/tests/ui/async-await/issue-70935-complex-spans.rs index 2851637ae78f..27826f79dcd9 100644 --- a/tests/ui/async-await/issue-70935-complex-spans.rs +++ b/tests/ui/async-await/issue-70935-complex-spans.rs @@ -15,7 +15,6 @@ async fn baz(_c: impl FnMut() -> T) where T: Future { fn foo(x: NotSync) -> impl Future + Send { //~^ ERROR `*mut ()` cannot be shared between threads safely async move { - //~^ ERROR `*mut ()` cannot be shared between threads safely baz(|| async { foo(x.clone()); }).await; diff --git a/tests/ui/async-await/issue-70935-complex-spans.stderr b/tests/ui/async-await/issue-70935-complex-spans.stderr index 31d15c459217..b9180c620b0d 100644 --- a/tests/ui/async-await/issue-70935-complex-spans.stderr +++ b/tests/ui/async-await/issue-70935-complex-spans.stderr @@ -1,46 +1,3 @@ -error[E0277]: `*mut ()` cannot be shared between threads safely - --> $DIR/issue-70935-complex-spans.rs:17:5 - | -LL | / async move { -LL | | -LL | | baz(|| async { -LL | | foo(x.clone()); -LL | | }).await; -LL | | } - | |_____^ `*mut ()` cannot be shared between threads safely - | - = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()` -note: required because it appears within the type `PhantomData<*mut ()>` - --> $SRC_DIR/core/src/marker.rs:LL:COL -note: required because it appears within the type `NotSync` - --> $DIR/issue-70935-complex-spans.rs:9:8 - | -LL | struct NotSync(PhantomData<*mut ()>); - | ^^^^^^^ - = note: required for `&NotSync` to implement `Send` -note: required because it's used within this closure - --> $DIR/issue-70935-complex-spans.rs:19:13 - | -LL | baz(|| async { - | ^^ -note: required because it's used within this `async` fn body - --> $DIR/issue-70935-complex-spans.rs:12:67 - | -LL | async fn baz(_c: impl FnMut() -> T) where T: Future { - | ___________________________________________________________________^ -LL | | } - | |_^ -note: required because it's used within this `async` block - --> $DIR/issue-70935-complex-spans.rs:17:5 - | -LL | async move { - | ^^^^^^^^^^ -note: required by a bound in an opaque type - --> $DIR/issue-70935-complex-spans.rs:15:37 - | -LL | fn foo(x: NotSync) -> impl Future + Send { - | ^^^^ - error[E0277]: `*mut ()` cannot be shared between threads safely --> $DIR/issue-70935-complex-spans.rs:15:23 | @@ -57,7 +14,7 @@ LL | struct NotSync(PhantomData<*mut ()>); | ^^^^^^^ = note: required for `&NotSync` to implement `Send` note: required because it's used within this closure - --> $DIR/issue-70935-complex-spans.rs:19:13 + --> $DIR/issue-70935-complex-spans.rs:18:13 | LL | baz(|| async { | ^^ @@ -74,6 +31,6 @@ note: required because it's used within this `async` block LL | async move { | ^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/async-await/issue-84841.stderr b/tests/ui/async-await/issue-84841.stderr index 0d008477310a..6c714ce7828c 100644 --- a/tests/ui/async-await/issue-84841.stderr +++ b/tests/ui/async-await/issue-84841.stderr @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | test()?; | ^^^^^^^ the `?` operator cannot be applied to type `impl Future` | - = help: the trait `Try` is not implemented for `impl Future` + = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future` error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/issue-84841.rs:9:11 diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr index 34f28dd53c7b..610ed60bc8fd 100644 --- a/tests/ui/async-await/issues/issue-67893.stderr +++ b/tests/ui/async-await/issues/issue-67893.stderr @@ -6,10 +6,10 @@ LL | g(issue_67893::run()) | | | required by a bound introduced by this call | - ::: $DIR/auxiliary/issue_67893.rs:9:1 + ::: $DIR/auxiliary/issue_67893.rs:9:19 | LL | pub async fn run() { - | ------------------ within this `impl Future` + | - within this `impl Future` | = help: within `impl Future`, the trait `Send` is not implemented for `std::sync::MutexGuard<'_, ()>` note: required because it's used within this `async` fn body diff --git a/tests/ui/async-await/missing-return-in-async-block.stderr b/tests/ui/async-await/missing-return-in-async-block.stderr index 5ea76e5f7bf9..a7d72ab5f33c 100644 --- a/tests/ui/async-await/missing-return-in-async-block.stderr +++ b/tests/ui/async-await/missing-return-in-async-block.stderr @@ -5,7 +5,7 @@ LL | / if true { LL | | Ok(S) | | ^^^^^ expected `()`, found `Result` LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result` @@ -21,7 +21,7 @@ LL | / if true { LL | | Ok(S) | | ^^^^^ expected `()`, found `Result` LL | | } - | |_________- expected this to be `()` + | |_________- `if` expressions without `else` arms expect their inner expression to be `()` | = note: expected unit type `()` found enum `Result` diff --git a/tests/ui/async-await/partial-drop-partial-reinit.stderr b/tests/ui/async-await/partial-drop-partial-reinit.stderr index cef835f7aed8..cf4b408ad12b 100644 --- a/tests/ui/async-await/partial-drop-partial-reinit.stderr +++ b/tests/ui/async-await/partial-drop-partial-reinit.stderr @@ -7,7 +7,7 @@ LL | gimme_send(foo()); | required by a bound introduced by this call ... LL | async fn foo() { - | -------------- within this `impl Future` + | - within this `impl Future` | help: within `impl Future`, the trait `Send` is not implemented for `NotSend` --> $DIR/partial-drop-partial-reinit.rs:19:1 diff --git a/tests/ui/async-await/try-in-sync.stderr b/tests/ui/async-await/try-in-sync.stderr index bc7a6bd01512..0957339a4dc5 100644 --- a/tests/ui/async-await/try-in-sync.stderr +++ b/tests/ui/async-await/try-in-sync.stderr @@ -4,7 +4,7 @@ error[E0277]: the `?` operator can only be applied to values that implement `Try LL | foo()?; | ^^^^^^ the `?` operator cannot be applied to type `impl Future>` | - = help: the trait `Try` is not implemented for `impl Future>` + = help: the nightly-only, unstable trait `Try` is not implemented for `impl Future>` note: this implements `Future` and its output type supports `?`, but the future cannot be awaited in a synchronous function --> $DIR/try-in-sync.rs:6:10 | diff --git a/tests/ui/async-await/unreachable-lint-2.stderr b/tests/ui/async-await/unreachable-lint-2.stderr index cbebc9951f32..5e7b328cf523 100644 --- a/tests/ui/async-await/unreachable-lint-2.stderr +++ b/tests/ui/async-await/unreachable-lint-2.stderr @@ -11,7 +11,6 @@ note: the lint level is defined here | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/attributes/align-on-fields-143987.stderr b/tests/ui/attributes/align-on-fields-143987.stderr index c95543a74c1a..1ffbf4a37cb9 100644 --- a/tests/ui/attributes/align-on-fields-143987.stderr +++ b/tests/ui/attributes/align-on-fields-143987.stderr @@ -2,7 +2,13 @@ error[E0425]: cannot find type `usize8` in this scope --> $DIR/align-on-fields-143987.rs:17:8 | LL | x: usize8, - | ^^^^^^ help: a builtin type with a similar name exists: `usize` + | ^^^^^^ + | +help: a builtin type with a similar name exists + | +LL - x: usize8, +LL + x: usize, + | error: `#[rustc_align]` attribute cannot be used on struct fields --> $DIR/align-on-fields-143987.rs:10:5 diff --git a/tests/ui/attributes/ambiguous_derive_helpers.rs b/tests/ui/attributes/ambiguous_derive_helpers.rs new file mode 100644 index 000000000000..aee498a7067a --- /dev/null +++ b/tests/ui/attributes/ambiguous_derive_helpers.rs @@ -0,0 +1,15 @@ +//@ force-host +//@ no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(ambiguous_derive_helpers)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Trait, attributes(ignore))] //~ ERROR there exists a built-in attribute with the same name +//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +pub fn deriving(input: TokenStream) -> TokenStream { + TokenStream::new() +} diff --git a/tests/ui/attributes/ambiguous_derive_helpers.stderr b/tests/ui/attributes/ambiguous_derive_helpers.stderr new file mode 100644 index 000000000000..a1eb8d172c25 --- /dev/null +++ b/tests/ui/attributes/ambiguous_derive_helpers.stderr @@ -0,0 +1,16 @@ +error: there exists a built-in attribute with the same name + --> $DIR/ambiguous_derive_helpers.rs:11:39 + | +LL | #[proc_macro_derive(Trait, attributes(ignore))] + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #151276 +note: the lint level is defined here + --> $DIR/ambiguous_derive_helpers.rs:5:9 + | +LL | #![deny(ambiguous_derive_helpers)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/attr-on-mac-call.stderr b/tests/ui/attributes/attr-on-mac-call.stderr index 1aeec463c71c..3bb50f2d6f65 100644 --- a/tests/ui/attributes/attr-on-mac-call.stderr +++ b/tests/ui/attributes/attr-on-mac-call.stderr @@ -55,7 +55,7 @@ LL | #[deprecated] | ^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements warning: `#[inline]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:24:5 @@ -136,7 +136,7 @@ LL | #[deprecated] | ^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements warning: `#[automatically_derived]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:51:5 @@ -163,7 +163,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[no_implicit_prelude]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:60:5 diff --git a/tests/ui/attributes/builtin-attribute-prefix.rs b/tests/ui/attributes/builtin-attribute-prefix.rs index d184c6d008df..02af7f536f86 100644 --- a/tests/ui/attributes/builtin-attribute-prefix.rs +++ b/tests/ui/attributes/builtin-attribute-prefix.rs @@ -1,8 +1,8 @@ // Regression test for https://github.com/rust-lang/rust/issues/143789 #[must_use::skip] -//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `must_use` +//~^ ERROR: cannot find module or crate `must_use` fn main() { } // Regression test for https://github.com/rust-lang/rust/issues/137590 struct S(#[stable::skip] u8, u16, u32); -//~^ ERROR failed to resolve: use of unresolved module or unlinked crate `stable` +//~^ ERROR: cannot find module or crate `stable` diff --git a/tests/ui/attributes/builtin-attribute-prefix.stderr b/tests/ui/attributes/builtin-attribute-prefix.stderr index a16080c003fb..a3e6c2e0172b 100644 --- a/tests/ui/attributes/builtin-attribute-prefix.stderr +++ b/tests/ui/attributes/builtin-attribute-prefix.stderr @@ -1,10 +1,10 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `stable` +error[E0433]: cannot find module or crate `stable` in this scope --> $DIR/builtin-attribute-prefix.rs:7:12 | LL | struct S(#[stable::skip] u8, u16, u32); | ^^^^^^ use of unresolved module or unlinked crate `stable` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `must_use` +error[E0433]: cannot find module or crate `must_use` in this scope --> $DIR/builtin-attribute-prefix.rs:2:3 | LL | #[must_use::skip] diff --git a/tests/ui/attributes/check-builtin-attr-ice.rs b/tests/ui/attributes/check-builtin-attr-ice.rs index 811210e2ccaf..bf4e3492f709 100644 --- a/tests/ui/attributes/check-builtin-attr-ice.rs +++ b/tests/ui/attributes/check-builtin-attr-ice.rs @@ -43,11 +43,11 @@ struct Foo { #[should_panic::skip] - //~^ ERROR failed to resolve + //~^ ERROR cannot find pub field: u8, #[should_panic::a::b::c] - //~^ ERROR failed to resolve + //~^ ERROR cannot find pub field2: u8, } @@ -55,6 +55,6 @@ fn foo() {} fn main() { #[deny::skip] - //~^ ERROR failed to resolve + //~^ ERROR cannot find foo(); } diff --git a/tests/ui/attributes/check-builtin-attr-ice.stderr b/tests/ui/attributes/check-builtin-attr-ice.stderr index 07bbe01898a7..35c97a05918e 100644 --- a/tests/ui/attributes/check-builtin-attr-ice.stderr +++ b/tests/ui/attributes/check-builtin-attr-ice.stderr @@ -1,16 +1,16 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `should_panic` +error[E0433]: cannot find module or crate `should_panic` in this scope --> $DIR/check-builtin-attr-ice.rs:45:7 | LL | #[should_panic::skip] | ^^^^^^^^^^^^ use of unresolved module or unlinked crate `should_panic` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `should_panic` +error[E0433]: cannot find module or crate `should_panic` in this scope --> $DIR/check-builtin-attr-ice.rs:49:7 | LL | #[should_panic::a::b::c] | ^^^^^^^^^^^^ use of unresolved module or unlinked crate `should_panic` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `deny` +error[E0433]: cannot find module or crate `deny` in this scope --> $DIR/check-builtin-attr-ice.rs:57:7 | LL | #[deny::skip] diff --git a/tests/ui/attributes/check-cfg_attr-ice.rs b/tests/ui/attributes/check-cfg_attr-ice.rs index 5bf8baab1414..5fb3f2798ba7 100644 --- a/tests/ui/attributes/check-cfg_attr-ice.rs +++ b/tests/ui/attributes/check-cfg_attr-ice.rs @@ -10,27 +10,27 @@ #![crate_type = "lib"] #[cfg_attr::no_such_thing] -//~^ ERROR failed to resolve +//~^ ERROR cannot find mod we_are_no_strangers_to_love {} #[cfg_attr::no_such_thing] -//~^ ERROR failed to resolve +//~^ ERROR cannot find struct YouKnowTheRules { #[cfg_attr::no_such_thing] - //~^ ERROR failed to resolve + //~^ ERROR cannot find and_so_do_i: u8, } #[cfg_attr::no_such_thing] -//~^ ERROR failed to resolve +//~^ ERROR cannot find fn a_full_commitment() { #[cfg_attr::no_such_thing] - //~^ ERROR failed to resolve + //~^ ERROR cannot find let is_what_i_am_thinking_of = (); } #[cfg_attr::no_such_thing] -//~^ ERROR failed to resolve +//~^ ERROR cannot find union AnyOtherGuy { owo: () } @@ -39,30 +39,30 @@ struct This; #[cfg_attr(FALSE, doc = "you wouldn't get this")] impl From for This { #[cfg_attr::no_such_thing] - //~^ ERROR failed to resolve + //~^ ERROR cannot find fn from(#[cfg_attr::no_such_thing] any_other_guy: AnyOtherGuy) -> This { - //~^ ERROR failed to resolve + //~^ ERROR cannot find #[cfg_attr::no_such_thing] //~^ ERROR attributes on expressions are experimental - //~| ERROR failed to resolve + //~| ERROR cannot find unreachable!() } } #[cfg_attr::no_such_thing] -//~^ ERROR failed to resolve +//~^ ERROR cannot find enum NeverGonna { #[cfg_attr::no_such_thing] - //~^ ERROR failed to resolve + //~^ ERROR cannot find GiveYouUp(#[cfg_attr::no_such_thing] u8), - //~^ ERROR failed to resolve + //~^ ERROR cannot find LetYouDown { #![cfg_attr::no_such_thing] //~^ ERROR an inner attribute is not permitted in this context never_gonna: (), round_around: (), #[cfg_attr::no_such_thing] - //~^ ERROR failed to resolve + //~^ ERROR cannot find and_desert_you: (), }, } diff --git a/tests/ui/attributes/check-cfg_attr-ice.stderr b/tests/ui/attributes/check-cfg_attr-ice.stderr index bed3150bdc2f..65476e2f76b6 100644 --- a/tests/ui/attributes/check-cfg_attr-ice.stderr +++ b/tests/ui/attributes/check-cfg_attr-ice.stderr @@ -17,79 +17,79 @@ LL | #[cfg_attr::no_such_thing] = help: add `#![feature(stmt_expr_attributes)]` 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[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:52:3 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:55:7 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:57:17 | LL | GiveYouUp(#[cfg_attr::no_such_thing] u8), | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:64:11 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:41:7 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:43:15 | LL | fn from(#[cfg_attr::no_such_thing] any_other_guy: AnyOtherGuy) -> This { | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:45:11 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:32:3 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:24:3 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:27:7 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:16:3 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:19:7 | LL | #[cfg_attr::no_such_thing] | ^^^^^^^^ use of unresolved module or unlinked crate `cfg_attr` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `cfg_attr` +error[E0433]: cannot find module or crate `cfg_attr` in this scope --> $DIR/check-cfg_attr-ice.rs:12:3 | LL | #[cfg_attr::no_such_thing] diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.rs b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs new file mode 100644 index 000000000000..6301a5a8ebf7 --- /dev/null +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.rs @@ -0,0 +1,24 @@ +#![deny(unused_attributes)] +#![feature(linkage)] +#![feature(fn_align)] + +trait Test { + #[cold] + //~^ ERROR cannot be used on required trait methods [unused_attributes] + //~| WARN previously accepted + fn method1(&self); + #[link_section = ".text"] + //~^ ERROR cannot be used on required trait methods [unused_attributes] + //~| WARN previously accepted + fn method2(&self); + #[linkage = "common"] + //~^ ERROR cannot be used on required trait methods [unused_attributes] + //~| WARN previously accepted + fn method3(&self); + #[track_caller] + fn method4(&self); + #[rustc_align(1)] + fn method5(&self); +} + +fn main() {} diff --git a/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr new file mode 100644 index 000000000000..0770ccae4146 --- /dev/null +++ b/tests/ui/attributes/codegen_attr_on_required_trait_method.stderr @@ -0,0 +1,34 @@ +error: `#[cold]` attribute cannot be used on required trait methods + --> $DIR/codegen_attr_on_required_trait_method.rs:6:5 + | +LL | #[cold] + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[cold]` can be applied to closures, foreign functions, functions, inherent methods, provided trait methods, and trait methods in impl blocks +note: the lint level is defined here + --> $DIR/codegen_attr_on_required_trait_method.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: `#[link_section]` attribute cannot be used on required trait methods + --> $DIR/codegen_attr_on_required_trait_method.rs:10:5 + | +LL | #[link_section = ".text"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks + +error: `#[linkage]` attribute cannot be used on required trait methods + --> $DIR/codegen_attr_on_required_trait_method.rs:14:5 + | +LL | #[linkage = "common"] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[linkage]` can be applied to foreign functions, foreign statics, functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks + +error: aborting due to 3 previous errors + diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.rs b/tests/ui/attributes/collapse-debuginfo-invalid.rs index ccf11df2eb0d..e467c72f52c0 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.rs +++ b/tests/ui/attributes/collapse-debuginfo-invalid.rs @@ -5,80 +5,80 @@ // Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions. #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on extern crate std; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on use std::collections::HashMap; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on static FOO: u32 = 3; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on const BAR: u32 = 3; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on fn foo() { let _ = #[collapse_debuginfo(yes)] || { }; - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on let _ = 3; let _ = #[collapse_debuginfo(yes)] 3; - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on match (3, 4) { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on _ => (), } } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on mod bar { } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type Map = HashMap; #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on enum Foo { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on Variant, } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on struct Bar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on field: u32, } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on union Qux { a: u32, b: u16 } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on trait Foobar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type Bar; } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on type AFoobar = impl Foobar; impl Foobar for Bar { @@ -91,14 +91,14 @@ fn constraining() -> AFoobar { } #[collapse_debuginfo(yes)] -//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +//~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on impl Bar { #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on const FOO: u32 = 3; #[collapse_debuginfo(yes)] - //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + //~^ ERROR `#[collapse_debuginfo]` attribute cannot be used on fn bar(&self) {} } diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr index 081e4445a869..d66e334c993c 100644 --- a/tests/ui/attributes/collapse-debuginfo-invalid.stderr +++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr @@ -1,221 +1,178 @@ -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on extern crates --> $DIR/collapse-debuginfo-invalid.rs:7:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | extern crate std; - | ----------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on use statements --> $DIR/collapse-debuginfo-invalid.rs:11:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | use std::collections::HashMap; - | ------------------------------ not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on statics --> $DIR/collapse-debuginfo-invalid.rs:15:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | static FOO: u32 = 3; - | -------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on constants --> $DIR/collapse-debuginfo-invalid.rs:19:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | const BAR: u32 = 3; - | ------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on functions --> $DIR/collapse-debuginfo-invalid.rs:23:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / fn foo() { -LL | | let _ = #[collapse_debuginfo(yes)] || { }; -LL | | -LL | | #[collapse_debuginfo(yes)] -... | -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on closures --> $DIR/collapse-debuginfo-invalid.rs:26:13 | LL | let _ = #[collapse_debuginfo(yes)] || { }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on statements --> $DIR/collapse-debuginfo-invalid.rs:28:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | let _ = 3; - | ---------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on expressions --> $DIR/collapse-debuginfo-invalid.rs:31:13 | LL | let _ = #[collapse_debuginfo(yes)] 3; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - not a macro definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on match arms --> $DIR/collapse-debuginfo-invalid.rs:34:9 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | _ => (), - | ------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on modules --> $DIR/collapse-debuginfo-invalid.rs:40:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / mod bar { -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on type aliases --> $DIR/collapse-debuginfo-invalid.rs:45:1 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type Map = HashMap; - | ----------------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on enums --> $DIR/collapse-debuginfo-invalid.rs:49:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / enum Foo { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | Variant, -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on enum variants --> $DIR/collapse-debuginfo-invalid.rs:52:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | Variant, - | ------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on structs --> $DIR/collapse-debuginfo-invalid.rs:57:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / struct Bar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | field: u32, -LL | | } - | |_- not a macro definition +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on struct fields --> $DIR/collapse-debuginfo-invalid.rs:60:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | field: u32, - | ---------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on unions --> $DIR/collapse-debuginfo-invalid.rs:65:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / union Qux { -LL | | a: u32, -LL | | b: u16 -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:72:1 - | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / trait Foobar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | type Bar; -LL | | } - | |_- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:80:1 - | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type AFoobar = impl Foobar; - | --------------------------- not a macro definition - -error: `collapse_debuginfo` attribute should be applied to macro definitions - --> $DIR/collapse-debuginfo-invalid.rs:93:1 | -LL | #[collapse_debuginfo(yes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | / impl Bar { -LL | | #[collapse_debuginfo(yes)] -LL | | -LL | | const FOO: u32 = 3; -... | -LL | | fn bar(&self) {} -LL | | } - | |_- not a macro definition + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on traits + --> $DIR/collapse-debuginfo-invalid.rs:72:1 + | +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on associated types --> $DIR/collapse-debuginfo-invalid.rs:75:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | type Bar; - | --------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on type aliases + --> $DIR/collapse-debuginfo-invalid.rs:80:1 + | +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on inherent impl blocks + --> $DIR/collapse-debuginfo-invalid.rs:93:1 + | +LL | #[collapse_debuginfo(yes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs + +error: `#[collapse_debuginfo]` attribute cannot be used on associated consts --> $DIR/collapse-debuginfo-invalid.rs:96:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | const FOO: u32 = 3; - | ------------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs -error: `collapse_debuginfo` attribute should be applied to macro definitions +error: `#[collapse_debuginfo]` attribute cannot be used on inherent methods --> $DIR/collapse-debuginfo-invalid.rs:100:5 | LL | #[collapse_debuginfo(yes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | fn bar(&self) {} - | ---------------- not a macro definition + | + = help: `#[collapse_debuginfo]` can only be applied to macro defs error: aborting due to 22 previous errors diff --git a/tests/ui/attributes/const-stability-on-macro.rs b/tests/ui/attributes/const-stability-on-macro.rs index af268ccd5366..4336370430d4 100644 --- a/tests/ui/attributes/const-stability-on-macro.rs +++ b/tests/ui/attributes/const-stability-on-macro.rs @@ -2,13 +2,13 @@ #![stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "foo", since = "3.3.3")] -//~^ ERROR macros cannot have const stability attributes +//~^ ERROR attribute cannot be used on macro defs macro_rules! foo { () => {}; } -#[rustc_const_unstable(feature = "bar", issue="none")] -//~^ ERROR macros cannot have const stability attributes +#[rustc_const_unstable(feature = "bar", issue = "none")] +//~^ ERROR attribute cannot be used on macro defs macro_rules! bar { () => {}; } diff --git a/tests/ui/attributes/const-stability-on-macro.stderr b/tests/ui/attributes/const-stability-on-macro.stderr index 28f31e3d4f61..a8b56edfa59d 100644 --- a/tests/ui/attributes/const-stability-on-macro.stderr +++ b/tests/ui/attributes/const-stability-on-macro.stderr @@ -1,20 +1,18 @@ -error: macros cannot have const stability attributes +error: `#[rustc_const_stable]` attribute cannot be used on macro defs --> $DIR/const-stability-on-macro.rs:4:1 | LL | #[rustc_const_stable(feature = "foo", since = "3.3.3")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute -LL | -LL | macro_rules! foo { - | ---------------- const stability attribute affects this macro + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_const_stable]` can be applied to associated consts, constants, crates, functions, impl blocks, statics, traits, and use statements -error: macros cannot have const stability attributes +error: `#[rustc_const_unstable]` attribute cannot be used on macro defs --> $DIR/const-stability-on-macro.rs:10:1 | -LL | #[rustc_const_unstable(feature = "bar", issue="none")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid const stability attribute -LL | -LL | macro_rules! bar { - | ---------------- const stability attribute affects this macro +LL | #[rustc_const_unstable(feature = "bar", issue = "none")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[rustc_const_unstable]` can be applied to associated consts, constants, crates, functions, impl blocks, statics, traits, and use statements error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/crate-only-as-outer.stderr b/tests/ui/attributes/crate-only-as-outer.stderr index 270f02af9873..c1787a73d290 100644 --- a/tests/ui/attributes/crate-only-as-outer.stderr +++ b/tests/ui/attributes/crate-only-as-outer.stderr @@ -4,7 +4,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[crate_name = "owo"] | ^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/crate-only-as-outer.rs:5:1 | LL | fn main() {} diff --git a/tests/ui/attributes/crate-type-delimited.stderr b/tests/ui/attributes/crate-type-delimited.stderr index 7f080f748386..a31d8dadc66e 100644 --- a/tests/ui/attributes/crate-type-delimited.stderr +++ b/tests/ui/attributes/crate-type-delimited.stderr @@ -1,25 +1,11 @@ -error: malformed `crate_type` attribute input +error[E0539]: malformed `crate_type` attribute input --> $DIR/crate-type-delimited.rs:2:1 | LL | #![crate_type(lib)] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "crate type"]` | = note: for more information, visit -help: the following are the possible correct uses - | -LL - #![crate_type(lib)] -LL + #![crate_type = "bin"] - | -LL - #![crate_type(lib)] -LL + #![crate_type = "cdylib"] - | -LL - #![crate_type(lib)] -LL + #![crate_type = "dylib"] - | -LL - #![crate_type(lib)] -LL + #![crate_type = "lib"] - | - = and 4 other candidates error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/crate-type-empty.stderr b/tests/ui/attributes/crate-type-empty.stderr index f50bb33d6bb0..bc085b8c7c07 100644 --- a/tests/ui/attributes/crate-type-empty.stderr +++ b/tests/ui/attributes/crate-type-empty.stderr @@ -1,21 +1,11 @@ -error: malformed `crate_type` attribute input +error[E0539]: malformed `crate_type` attribute input --> $DIR/crate-type-empty.rs:2:1 | LL | #![crate_type] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "crate type"]` | = note: for more information, visit -help: the following are the possible correct uses - | -LL | #![crate_type = "bin"] - | +++++++ -LL | #![crate_type = "cdylib"] - | ++++++++++ -LL | #![crate_type = "dylib"] - | +++++++++ -LL | #![crate_type = "lib"] - | +++++++ - = and 4 other candidates error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/crate-type-macro-call.rs b/tests/ui/attributes/crate-type-macro-call.rs index 9ba5e79ba947..0d074422d951 100644 --- a/tests/ui/attributes/crate-type-macro-call.rs +++ b/tests/ui/attributes/crate-type-macro-call.rs @@ -1,4 +1,5 @@ -#![crate_type = foo!()] //~ ERROR malformed `crate_type` attribute +#![crate_type = foo!()] +//~^ ERROR attribute value must be a literal macro_rules! foo { () => {"rlib"}; diff --git a/tests/ui/attributes/crate-type-macro-call.stderr b/tests/ui/attributes/crate-type-macro-call.stderr index 97938f7af24e..690f09984710 100644 --- a/tests/ui/attributes/crate-type-macro-call.stderr +++ b/tests/ui/attributes/crate-type-macro-call.stderr @@ -1,25 +1,8 @@ -error: malformed `crate_type` attribute input - --> $DIR/crate-type-macro-call.rs:1:1 +error: attribute value must be a literal + --> $DIR/crate-type-macro-call.rs:1:17 | LL | #![crate_type = foo!()] - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, visit -help: the following are the possible correct uses - | -LL - #![crate_type = foo!()] -LL + #![crate_type = "bin"] - | -LL - #![crate_type = foo!()] -LL + #![crate_type = "cdylib"] - | -LL - #![crate_type = foo!()] -LL + #![crate_type = "dylib"] - | -LL - #![crate_type = foo!()] -LL + #![crate_type = "lib"] - | - = and 4 other candidates + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-macro-empty.rs b/tests/ui/attributes/crate-type-macro-empty.rs index cfc71e6b938f..d55074ed686c 100644 --- a/tests/ui/attributes/crate-type-macro-empty.rs +++ b/tests/ui/attributes/crate-type-macro-empty.rs @@ -1,7 +1,7 @@ // Tests for the issue in #137589 #[crate_type = foo!()] //~^ ERROR cannot find macro `foo` in this scope -//~| WARN crate-level attribute should be an inner attribute +//~| ERROR attribute value must be a literal macro_rules! foo {} //~ ERROR macros must contain at least one rule diff --git a/tests/ui/attributes/crate-type-macro-empty.stderr b/tests/ui/attributes/crate-type-macro-empty.stderr index 0c2c4cf2a9b2..2e24a9972287 100644 --- a/tests/ui/attributes/crate-type-macro-empty.stderr +++ b/tests/ui/attributes/crate-type-macro-empty.stderr @@ -16,17 +16,11 @@ note: a macro with the same name exists, but it appears later LL | macro_rules! foo {} | ^^^ -warning: crate-level attribute should be an inner attribute - --> $DIR/crate-type-macro-empty.rs:2:1 +error: attribute value must be a literal + --> $DIR/crate-type-macro-empty.rs:2:16 | LL | #[crate_type = foo!()] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: requested on the command line with `-W unused-attributes` -help: add a `!` - | -LL | #![crate_type = foo!()] - | + + | ^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/crate-type-macro-not-found.rs b/tests/ui/attributes/crate-type-macro-not-found.rs index b9f05fa7caa1..eac780944572 100644 --- a/tests/ui/attributes/crate-type-macro-not-found.rs +++ b/tests/ui/attributes/crate-type-macro-not-found.rs @@ -1,6 +1,7 @@ // Tests for the issue in #137589 -#[crate_type = foo!()] //~ ERROR cannot find macro `foo` in this scope -//~| WARN crate-level attribute should be an inner attribute +#[crate_type = foo!()] +//~^ ERROR cannot find macro `foo` in this scope +//~| ERROR attribute value must be a literal macro_rules! foo { ($x:expr) => {"rlib"} diff --git a/tests/ui/attributes/crate-type-macro-not-found.stderr b/tests/ui/attributes/crate-type-macro-not-found.stderr index 7b8c6a808349..9db7f7f6ec0b 100644 --- a/tests/ui/attributes/crate-type-macro-not-found.stderr +++ b/tests/ui/attributes/crate-type-macro-not-found.stderr @@ -5,22 +5,16 @@ LL | #[crate_type = foo!()] | ^^^ consider moving the definition of `foo` before this call | note: a macro with the same name exists, but it appears later - --> $DIR/crate-type-macro-not-found.rs:5:14 + --> $DIR/crate-type-macro-not-found.rs:6:14 | LL | macro_rules! foo { | ^^^ -warning: crate-level attribute should be an inner attribute - --> $DIR/crate-type-macro-not-found.rs:2:1 +error: attribute value must be a literal + --> $DIR/crate-type-macro-not-found.rs:2:16 | LL | #[crate_type = foo!()] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: requested on the command line with `-W unused-attributes` -help: add a `!` - | -LL | #![crate_type = foo!()] - | + + | ^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/crate-type-non-crate.rs b/tests/ui/attributes/crate-type-non-crate.rs new file mode 100644 index 000000000000..bd667b4b0a45 --- /dev/null +++ b/tests/ui/attributes/crate-type-non-crate.rs @@ -0,0 +1,19 @@ +//! Test the behavior of various malformed `crate_type` attributes applied to a non-crate target. +#![allow(unused_attributes)] + +// No arguments +#[crate_type] //~ ERROR malformed `crate_type` attribute input +// List/NameValue with/without strings +#[crate_type(lib)] //~ ERROR malformed `crate_type` attribute input +#[crate_type("lib")] //~ ERROR malformed `crate_type` attribute input +#[crate_type = lib] //~ ERROR attribute value must be a literal +#[crate_type = "lib"] // OK +// Same as above but with invalid names +#[crate_type(foo)] //~ ERROR malformed `crate_type` attribute input +#[crate_type("foo")] //~ ERROR malformed `crate_type` attribute input +#[crate_type = foo] //~ ERROR attribute value must be a literal +#[crate_type = "foo"] // OK - we don't report errors on invalid crate types here +// Non-string literals +#[crate_type(1)] //~ ERROR malformed `crate_type` attribute input +#[crate_type = 1] //~ ERROR malformed `crate_type` attribute input +fn main() {} diff --git a/tests/ui/attributes/crate-type-non-crate.stderr b/tests/ui/attributes/crate-type-non-crate.stderr new file mode 100644 index 000000000000..03bafeaf5ebd --- /dev/null +++ b/tests/ui/attributes/crate-type-non-crate.stderr @@ -0,0 +1,74 @@ +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:5:1 + | +LL | #[crate_type] + | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:7:1 + | +LL | #[crate_type(lib)] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:8:1 + | +LL | #[crate_type("lib")] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error: attribute value must be a literal + --> $DIR/crate-type-non-crate.rs:9:16 + | +LL | #[crate_type = lib] + | ^^^ + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:12:1 + | +LL | #[crate_type(foo)] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:13:1 + | +LL | #[crate_type("foo")] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error: attribute value must be a literal + --> $DIR/crate-type-non-crate.rs:14:16 + | +LL | #[crate_type = foo] + | ^^^ + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:17:1 + | +LL | #[crate_type(1)] + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:18:1 + | +LL | #[crate_type = 1] + | ^^^^^^^^^^^^^^^-^ + | | | + | | expected a string literal here + | help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/custom_attr_multisegment_error.rs b/tests/ui/attributes/custom_attr_multisegment_error.rs index 1045282c3a33..f42c35ffea13 100644 --- a/tests/ui/attributes/custom_attr_multisegment_error.rs +++ b/tests/ui/attributes/custom_attr_multisegment_error.rs @@ -2,5 +2,5 @@ mod existent {} -#[existent::nonexistent] //~ ERROR failed to resolve: could not find `nonexistent` in `existent` +#[existent::nonexistent] //~ ERROR cannot find `nonexistent` in `existent` fn main() {} diff --git a/tests/ui/attributes/custom_attr_multisegment_error.stderr b/tests/ui/attributes/custom_attr_multisegment_error.stderr index 02bed225d53e..8066fc74de4b 100644 --- a/tests/ui/attributes/custom_attr_multisegment_error.stderr +++ b/tests/ui/attributes/custom_attr_multisegment_error.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `nonexistent` in `existent` +error[E0433]: cannot find `nonexistent` in `existent` --> $DIR/custom_attr_multisegment_error.rs:5:13 | LL | #[existent::nonexistent] diff --git a/tests/ui/attributes/doc-attr.rs b/tests/ui/attributes/doc-attr.rs index 666aeb55cbec..8c81bc18d6ae 100644 --- a/tests/ui/attributes/doc-attr.rs +++ b/tests/ui/attributes/doc-attr.rs @@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![crate_type = "lib"] #![doc(as_ptr)] //~^ ERROR unknown `doc` attribute @@ -7,10 +8,13 @@ pub fn foo() {} #[doc(123)] -//~^ ERROR invalid `doc` attribute +//~^ ERROR +//~| WARN #[doc("hello", "bar")] -//~^ ERROR invalid `doc` attribute -//~| ERROR invalid `doc` attribute +//~^ ERROR +//~| ERROR +//~| WARN +//~| WARN #[doc(foo::bar, crate::bar::baz = "bye")] //~^ ERROR unknown `doc` attribute //~| ERROR unknown `doc` attribute diff --git a/tests/ui/attributes/doc-attr.stderr b/tests/ui/attributes/doc-attr.stderr index 091ffc20d465..79d9fb5bea7e 100644 --- a/tests/ui/attributes/doc-attr.stderr +++ b/tests/ui/attributes/doc-attr.stderr @@ -1,43 +1,53 @@ error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:5:7 + --> $DIR/doc-attr.rs:6:7 | LL | #[doc(as_ptr)] | ^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/doc-attr.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:9:7 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:10:7 | LL | #[doc(123)] | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:7 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:13:7 | LL | #[doc("hello", "bar")] | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: invalid `doc` attribute - --> $DIR/doc-attr.rs:11:16 +error: expected this to be of the form `... = "..."` + --> $DIR/doc-attr.rs:13:16 | LL | #[doc("hello", "bar")] | ^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unknown `doc` attribute `foo::bar` - --> $DIR/doc-attr.rs:14:7 + --> $DIR/doc-attr.rs:18:7 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] | ^^^^^^^^ error: unknown `doc` attribute `crate::bar::baz` - --> $DIR/doc-attr.rs:14:17 + --> $DIR/doc-attr.rs:18:17 | LL | #[doc(foo::bar, crate::bar::baz = "bye")] - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: unknown `doc` attribute `as_ptr` - --> $DIR/doc-attr.rs:2:8 + --> $DIR/doc-attr.rs:3:8 | LL | #![doc(as_ptr)] | ^^^^^^ diff --git a/tests/ui/attributes/doc-test-literal.rs b/tests/ui/attributes/doc-test-literal.rs index 92fe7846f14c..ceb8967ea229 100644 --- a/tests/ui/attributes/doc-test-literal.rs +++ b/tests/ui/attributes/doc-test-literal.rs @@ -1,4 +1,7 @@ +#![deny(invalid_doc_attributes)] + #![doc(test(""))] -//~^ ERROR `#![doc(test(...)]` does not take a literal +//~^ ERROR +//~| WARN fn main() {} diff --git a/tests/ui/attributes/doc-test-literal.stderr b/tests/ui/attributes/doc-test-literal.stderr index 39e109a76ce5..c26aa94ec1af 100644 --- a/tests/ui/attributes/doc-test-literal.stderr +++ b/tests/ui/attributes/doc-test-literal.stderr @@ -1,10 +1,15 @@ -error: `#![doc(test(...)]` does not take a literal - --> $DIR/doc-test-literal.rs:1:13 +error: malformed `doc` attribute input + --> $DIR/doc-test-literal.rs:3:13 | LL | #![doc(test(""))] | ^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/doc-test-literal.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/attributes/extented-attribute-macro-error.rs b/tests/ui/attributes/extented-attribute-macro-error.rs index 83060024dac9..f85a28ad706e 100644 --- a/tests/ui/attributes/extented-attribute-macro-error.rs +++ b/tests/ui/attributes/extented-attribute-macro-error.rs @@ -3,5 +3,6 @@ #![doc = include_str!("../not_existing_file.md")] struct Documented {} //~^^ ERROR couldn't read +//~| ERROR attribute value must be a literal fn main() {} diff --git a/tests/ui/attributes/extented-attribute-macro-error.stderr b/tests/ui/attributes/extented-attribute-macro-error.stderr index 7b93b98f64cd..ed46cba3d040 100644 --- a/tests/ui/attributes/extented-attribute-macro-error.stderr +++ b/tests/ui/attributes/extented-attribute-macro-error.stderr @@ -4,5 +4,11 @@ error: couldn't read the file LL | #![doc = include_str!("../not_existing_file.md")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error: attribute value must be a literal + --> $DIR/extented-attribute-macro-error.rs:3:10 + | +LL | #![doc = include_str!("../not_existing_file.md")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/field-attributes-vis-unresolved.rs b/tests/ui/attributes/field-attributes-vis-unresolved.rs index be710a3cd744..bcdabe42fcc2 100644 --- a/tests/ui/attributes/field-attributes-vis-unresolved.rs +++ b/tests/ui/attributes/field-attributes-vis-unresolved.rs @@ -15,12 +15,12 @@ mod internal { struct S { #[rustfmt::skip] - pub(in nonexistent) field: u8 //~ ERROR failed to resolve + pub(in nonexistent) field: u8 //~ ERROR cannot find } struct Z( #[rustfmt::skip] - pub(in nonexistent) u8 //~ ERROR failed to resolve + pub(in nonexistent) u8 //~ ERROR cannot find ); fn main() {} diff --git a/tests/ui/attributes/field-attributes-vis-unresolved.stderr b/tests/ui/attributes/field-attributes-vis-unresolved.stderr index 1ebfde4cd67e..f1148385d8a1 100644 --- a/tests/ui/attributes/field-attributes-vis-unresolved.stderr +++ b/tests/ui/attributes/field-attributes-vis-unresolved.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nonexistent` +error[E0433]: cannot find module or crate `nonexistent` in the crate root --> $DIR/field-attributes-vis-unresolved.rs:18:12 | LL | pub(in nonexistent) field: u8 @@ -9,7 +9,7 @@ help: you might be missing a crate named `nonexistent`, add it to your project a LL + extern crate nonexistent; | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nonexistent` +error[E0433]: cannot find module or crate `nonexistent` in the crate root --> $DIR/field-attributes-vis-unresolved.rs:23:12 | LL | pub(in nonexistent) u8 diff --git a/tests/ui/attributes/illegal-macro-use.rs b/tests/ui/attributes/illegal-macro-use.rs index 5a567107a6e2..e16a223c75ff 100644 --- a/tests/ui/attributes/illegal-macro-use.rs +++ b/tests/ui/attributes/illegal-macro-use.rs @@ -1,15 +1,15 @@ // issue#140255 -#[macro_use::a] //~ ERROR failed to resolve: use of unresolved module or unlinked crate `macro_use` +#[macro_use::a] //~ ERROR cannot find fn f0() {} -#[macro_use::a::b] //~ ERROR failed to resolve: use of unresolved module or unlinked crate `macro_use` +#[macro_use::a::b] //~ ERROR cannot find fn f1() {} -#[macro_escape::a] //~ ERROR failed to resolve: use of unresolved module or unlinked crate `macro_escape` +#[macro_escape::a] //~ ERROR cannot find fn f2() {} -#[macro_escape::a::b] //~ ERROR failed to resolve: use of unresolved module or unlinked crate `macro_escape` +#[macro_escape::a::b] //~ ERROR cannot find fn f3() {} fn main() {} diff --git a/tests/ui/attributes/illegal-macro-use.stderr b/tests/ui/attributes/illegal-macro-use.stderr index fa6bb83d588a..13c9f05ccd66 100644 --- a/tests/ui/attributes/illegal-macro-use.stderr +++ b/tests/ui/attributes/illegal-macro-use.stderr @@ -1,22 +1,22 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `macro_escape` +error[E0433]: cannot find module or crate `macro_escape` in this scope --> $DIR/illegal-macro-use.rs:12:3 | LL | #[macro_escape::a::b] | ^^^^^^^^^^^^ use of unresolved module or unlinked crate `macro_escape` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `macro_escape` +error[E0433]: cannot find module or crate `macro_escape` in this scope --> $DIR/illegal-macro-use.rs:9:3 | LL | #[macro_escape::a] | ^^^^^^^^^^^^ use of unresolved module or unlinked crate `macro_escape` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `macro_use` +error[E0433]: cannot find module or crate `macro_use` in this scope --> $DIR/illegal-macro-use.rs:6:3 | LL | #[macro_use::a::b] | ^^^^^^^^^ use of unresolved module or unlinked crate `macro_use` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `macro_use` +error[E0433]: cannot find module or crate `macro_use` in this scope --> $DIR/illegal-macro-use.rs:3:3 | LL | #[macro_use::a] diff --git a/tests/ui/attributes/instruction-set.rs b/tests/ui/attributes/instruction-set.rs new file mode 100644 index 000000000000..dafa907cb568 --- /dev/null +++ b/tests/ui/attributes/instruction-set.rs @@ -0,0 +1,111 @@ +//@ add-minicore +//@ compile-flags: --target armv5te-none-eabi +//@ needs-llvm-components: arm +//@ ignore-backends: gcc +//@ edition: 2024 + +#![crate_type = "lib"] +#![feature(no_core, lang_items,)] +#![no_core] + +extern crate minicore; +use minicore::*; + + + + +#[instruction_set(arm::a32)] +fn foo() { +} + +#[instruction_set(arm)] +//~^ ERROR malformed `instruction_set` attribute input [E0539] +fn bar() { +} + +#[instruction_set(arm::)] +//~^ ERROR expected identifier, found `` +fn bazz() { +} + +#[instruction_set(arm::magic)] +//~^ ERROR malformed `instruction_set` attribute input [E0539] +fn bazzer() { + +} + +fn all_instruction_set_cases() { + #[instruction_set(arm::a32)] + || { + 0 + }; + #[instruction_set(arm::t32)] + async || { + 0 + }; +} + +struct Fooer; + +impl Fooer { + #[instruction_set(arm::a32)] + fn fooest() { + + } +} + +trait Bazzest { + fn bazz(); + + #[instruction_set(arm::a32)] + fn bazziest() { + + } +} +impl Bazzest for Fooer { + #[instruction_set(arm::t32)] + fn bazz() {} +} + + +// The following lang items need to be defined for the async closure to work +#[lang = "ResumeTy"] +pub struct ResumeTy(NonNull>); + +#[lang = "future_trait"] +pub trait Future { + /// The type of value produced on completion. + #[lang = "future_output"] + type Output; + + // NOTE: misses the `poll` method. +} + +#[lang = "async_drop"] +pub trait AsyncDrop { + // NOTE: misses the `drop` method. +} + +#[lang = "Poll"] +pub enum Poll { + #[lang = "Ready"] + Ready(T), + + #[lang = "Pending"] + Pending, +} + +#[lang = "Context"] +pub struct Context<'a> { + // NOTE: misses a bunch of fields. + _marker: PhantomData &'a ()>, +} + +#[lang = "get_context"] +pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { + // NOTE: the actual implementation looks different. + unsafe {mem::transmute(cx.0)} +} + +#[lang = "pin"] +pub struct Pin(T); diff --git a/tests/ui/attributes/instruction-set.stderr b/tests/ui/attributes/instruction-set.stderr new file mode 100644 index 000000000000..c5aea396b53e --- /dev/null +++ b/tests/ui/attributes/instruction-set.stderr @@ -0,0 +1,31 @@ +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/instruction-set.rs:21:1 + | +LL | #[instruction_set(arm)] + | ^^^^^^^^^^^^^^^^^^---^^ + | | | + | | valid arguments are `arm::a32` or `arm::t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + +error: expected identifier, found `` + --> $DIR/instruction-set.rs:26:22 + | +LL | #[instruction_set(arm::)] + | ^^ expected identifier + +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/instruction-set.rs:31:1 + | +LL | #[instruction_set(arm::magic)] + | ^^^^^^^^^^^^^^^^^^^^^^^-----^^ + | | | + | | valid arguments are `a32` or `t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/invalid-instruction-set-target.rs b/tests/ui/attributes/invalid-instruction-set-target.rs new file mode 100644 index 000000000000..08b261c1b309 --- /dev/null +++ b/tests/ui/attributes/invalid-instruction-set-target.rs @@ -0,0 +1,6 @@ +//@ only-x86_64-unknown-linux-gnu + +#[instruction_set(arm::a32)] +//~^ ERROR target `x86_64-unknown-linux-gnu` does not support `#[instruction_set(arm::*)]` +fn main() { +} diff --git a/tests/ui/attributes/invalid-instruction-set-target.stderr b/tests/ui/attributes/invalid-instruction-set-target.stderr new file mode 100644 index 000000000000..d99fbd369a0e --- /dev/null +++ b/tests/ui/attributes/invalid-instruction-set-target.stderr @@ -0,0 +1,8 @@ +error: target `x86_64-unknown-linux-gnu` does not support `#[instruction_set(arm::*)]` + --> $DIR/invalid-instruction-set-target.rs:3:1 + | +LL | #[instruction_set(arm::a32)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/attributes/invalid-macro-use.rs b/tests/ui/attributes/invalid-macro-use.rs index 52e4608303f0..4d05e933647b 100644 --- a/tests/ui/attributes/invalid-macro-use.rs +++ b/tests/ui/attributes/invalid-macro-use.rs @@ -2,7 +2,9 @@ //~^ NOTE the lint level is defined here #[macro_use = 5] -//~^ ERROR valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +//~^ ERROR malformed `macro_use` attribute input +//~| NOTE expected a list or no arguments here +//~| NOTE for more information, visit extern crate std as s1; #[macro_use(5)] diff --git a/tests/ui/attributes/invalid-macro-use.stderr b/tests/ui/attributes/invalid-macro-use.stderr index ff3ed6196d3d..fe235ab209f3 100644 --- a/tests/ui/attributes/invalid-macro-use.stderr +++ b/tests/ui/attributes/invalid-macro-use.stderr @@ -1,23 +1,35 @@ error[E0469]: imported macro not found - --> $DIR/invalid-macro-use.rs:51:13 + --> $DIR/invalid-macro-use.rs:53:13 | LL | #[macro_use(a)] | ^ error[E0469]: imported macro not found - --> $DIR/invalid-macro-use.rs:53:13 + --> $DIR/invalid-macro-use.rs:55:13 | LL | #[macro_use(b)] | ^ -error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +error[E0539]: malformed `macro_use` attribute input --> $DIR/invalid-macro-use.rs:4:1 | LL | #[macro_use = 5] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^---^ + | | + | expected a list or no arguments here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_use = 5] +LL + #[macro_use(name1, name2, ...)] + | +LL - #[macro_use = 5] +LL + #[macro_use] + | error[E0539]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:8:1 + --> $DIR/invalid-macro-use.rs:10:1 | LL | #[macro_use(5)] | ^^^^^^^^^^^^-^^ @@ -35,7 +47,7 @@ LL + #[macro_use] | error[E0565]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:14:1 + --> $DIR/invalid-macro-use.rs:16:1 | LL | #[macro_use(a = "b")] | ^^^^^^^^^^^^^^-----^^ @@ -53,7 +65,7 @@ LL + #[macro_use] | error[E0565]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:20:1 + --> $DIR/invalid-macro-use.rs:22:1 | LL | #[macro_use(a(b))] | ^^^^^^^^^^^^^---^^ @@ -71,7 +83,7 @@ LL + #[macro_use] | error[E0539]: malformed `macro_use` attribute input - --> $DIR/invalid-macro-use.rs:26:1 + --> $DIR/invalid-macro-use.rs:28:1 | LL | #[macro_use(a::b)] | ^^^^^^^^^^^^----^^ @@ -89,13 +101,13 @@ LL + #[macro_use] | error: unused attribute - --> $DIR/invalid-macro-use.rs:32:1 + --> $DIR/invalid-macro-use.rs:34:1 | LL | #[macro_use(a)] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-macro-use.rs:34:1 + --> $DIR/invalid-macro-use.rs:36:1 | LL | #[macro_use] | ^^^^^^^^^^^^ @@ -106,25 +118,25 @@ LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/invalid-macro-use.rs:40:1 + --> $DIR/invalid-macro-use.rs:42:1 | LL | #[macro_use(a)] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-macro-use.rs:38:1 + --> $DIR/invalid-macro-use.rs:40:1 | LL | #[macro_use] | ^^^^^^^^^^^^ error: unused attribute - --> $DIR/invalid-macro-use.rs:46:1 + --> $DIR/invalid-macro-use.rs:48:1 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/invalid-macro-use.rs:44:1 + --> $DIR/invalid-macro-use.rs:46:1 | LL | #[macro_use] | ^^^^^^^^^^^^ diff --git a/tests/ui/attributes/key-value-expansion-scope.rs b/tests/ui/attributes/key-value-expansion-scope.rs index 6688d698f9ea..b30da2eda24a 100644 --- a/tests/ui/attributes/key-value-expansion-scope.rs +++ b/tests/ui/attributes/key-value-expansion-scope.rs @@ -1,19 +1,29 @@ #![doc = in_root!()] //~ ERROR cannot find macro `in_root` //~| WARN this was previously accepted by the compiler #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` //~| WARN this was previously accepted by the compiler #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal #[doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope + //~| ERROR attribute value must be a literal #[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #[doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope + //~| ERROR attribute value must be a literal #[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal fn before() { #![doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope + //~| ERROR attribute value must be a literal #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal } macro_rules! in_root { () => { "" } } @@ -48,8 +58,10 @@ mod macros_escape { } #[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal fn block() { #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal macro_rules! in_block { () => { "" } } @@ -61,13 +73,17 @@ fn block() { #[doc = in_root!()] // OK #[doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #[doc = in_mod_escape!()] // OK #[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal fn after() { #![doc = in_root!()] // OK #![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope + //~| ERROR attribute value must be a literal #![doc = in_mod_escape!()] // OK #![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope + //~| ERROR attribute value must be a literal } fn main() {} diff --git a/tests/ui/attributes/key-value-expansion-scope.stderr b/tests/ui/attributes/key-value-expansion-scope.stderr index 71a83d80617a..1ebed6b8b6fc 100644 --- a/tests/ui/attributes/key-value-expansion-scope.stderr +++ b/tests/ui/attributes/key-value-expansion-scope.stderr @@ -7,7 +7,7 @@ LL | #![doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:6:10 + --> $DIR/key-value-expansion-scope.rs:7:10 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -15,7 +15,7 @@ LL | #![doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_root` in this scope - --> $DIR/key-value-expansion-scope.rs:8:9 + --> $DIR/key-value-expansion-scope.rs:10:9 | LL | #[doc = in_root!()] | ^^^^^^^ @@ -23,7 +23,7 @@ LL | #[doc = in_root!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:9:9 + --> $DIR/key-value-expansion-scope.rs:12:9 | LL | #[doc = in_mod!()] | ^^^^^^ @@ -31,7 +31,7 @@ LL | #[doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod_escape` in this scope - --> $DIR/key-value-expansion-scope.rs:10:9 + --> $DIR/key-value-expansion-scope.rs:14:9 | LL | #[doc = in_mod_escape!()] | ^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | #[doc = in_mod_escape!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:11:9 + --> $DIR/key-value-expansion-scope.rs:16:9 | LL | #[doc = in_block!()] | ^^^^^^^^ @@ -47,7 +47,7 @@ LL | #[doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_root` in this scope - --> $DIR/key-value-expansion-scope.rs:13:14 + --> $DIR/key-value-expansion-scope.rs:19:14 | LL | #![doc = in_root!()] | ^^^^^^^ @@ -55,7 +55,7 @@ LL | #![doc = in_root!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:14:14 + --> $DIR/key-value-expansion-scope.rs:21:14 | LL | #![doc = in_mod!()] | ^^^^^^ @@ -63,7 +63,7 @@ LL | #![doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod_escape` in this scope - --> $DIR/key-value-expansion-scope.rs:15:14 + --> $DIR/key-value-expansion-scope.rs:23:14 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | #![doc = in_mod_escape!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:16:14 + --> $DIR/key-value-expansion-scope.rs:25:14 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -79,7 +79,7 @@ LL | #![doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:50:9 + --> $DIR/key-value-expansion-scope.rs:60:9 | LL | #[doc = in_block!()] | ^^^^^^^^ @@ -87,7 +87,7 @@ LL | #[doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:52:14 + --> $DIR/key-value-expansion-scope.rs:63:14 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -95,7 +95,7 @@ LL | #![doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:63:9 + --> $DIR/key-value-expansion-scope.rs:75:9 | LL | #[doc = in_mod!()] | ^^^^^^ @@ -103,7 +103,7 @@ LL | #[doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:65:9 + --> $DIR/key-value-expansion-scope.rs:78:9 | LL | #[doc = in_block!()] | ^^^^^^^^ @@ -111,7 +111,7 @@ LL | #[doc = in_block!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_mod` in this scope - --> $DIR/key-value-expansion-scope.rs:68:14 + --> $DIR/key-value-expansion-scope.rs:82:14 | LL | #![doc = in_mod!()] | ^^^^^^ @@ -119,7 +119,7 @@ LL | #![doc = in_mod!()] = help: have you added the `#[macro_use]` on the module/import? error: cannot find macro `in_block` in this scope - --> $DIR/key-value-expansion-scope.rs:70:14 + --> $DIR/key-value-expansion-scope.rs:85:14 | LL | #![doc = in_block!()] | ^^^^^^^^ @@ -138,7 +138,7 @@ LL | #![doc = in_root!()] = note: `#[deny(out_of_scope_macro_calls)]` (part of `#[deny(future_incompatible)]`) on by default error: cannot find macro `in_mod_escape` in the current scope when looking from the crate root - --> $DIR/key-value-expansion-scope.rs:4:10 + --> $DIR/key-value-expansion-scope.rs:5:10 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from the crate root @@ -148,7 +148,7 @@ LL | #![doc = in_mod_escape!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:21:9 + --> $DIR/key-value-expansion-scope.rs:31:9 | LL | #[doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -158,7 +158,7 @@ LL | #[doc = in_mod!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:24:14 + --> $DIR/key-value-expansion-scope.rs:34:14 | LL | #![doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -168,7 +168,7 @@ LL | #![doc = in_mod!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:36:9 + --> $DIR/key-value-expansion-scope.rs:46:9 | LL | #[doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` @@ -178,7 +178,7 @@ LL | #[doc = in_mod_escape!()] = help: import `macro_rules` with `use` to make it callable above its definition error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:39:14 + --> $DIR/key-value-expansion-scope.rs:49:14 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` @@ -187,7 +187,103 @@ LL | #![doc = in_mod_escape!()] = note: for more information, see issue #124535 = help: import `macro_rules` with `use` to make it callable above its definition -error: aborting due to 22 previous errors +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:3:10 + | +LL | #![doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:7:10 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:10:9 + | +LL | #[doc = in_root!()] + | ^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:12:9 + | +LL | #[doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:14:9 + | +LL | #[doc = in_mod_escape!()] + | ^^^^^^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:16:9 + | +LL | #[doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:19:14 + | +LL | #![doc = in_root!()] + | ^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:21:14 + | +LL | #![doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:23:14 + | +LL | #![doc = in_mod_escape!()] + | ^^^^^^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:25:14 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:60:9 + | +LL | #[doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:63:14 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:75:9 + | +LL | #[doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:78:9 + | +LL | #[doc = in_block!()] + | ^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:82:14 + | +LL | #![doc = in_mod!()] + | ^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/key-value-expansion-scope.rs:85:14 + | +LL | #![doc = in_block!()] + | ^^^^^^^^^^^ + +error: aborting due to 38 previous errors Future incompatibility report: Future breakage diagnostic: error: cannot find macro `in_root` in the current scope when looking from the crate root @@ -203,7 +299,7 @@ LL | #![doc = in_root!()] Future breakage diagnostic: error: cannot find macro `in_mod_escape` in the current scope when looking from the crate root - --> $DIR/key-value-expansion-scope.rs:4:10 + --> $DIR/key-value-expansion-scope.rs:5:10 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from the crate root @@ -215,7 +311,7 @@ LL | #![doc = in_mod_escape!()] Future breakage diagnostic: error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:21:9 + --> $DIR/key-value-expansion-scope.rs:31:9 | LL | #[doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -227,7 +323,7 @@ LL | #[doc = in_mod!()] Future breakage diagnostic: error: cannot find macro `in_mod` in the current scope when looking from module `macros_stay` - --> $DIR/key-value-expansion-scope.rs:24:14 + --> $DIR/key-value-expansion-scope.rs:34:14 | LL | #![doc = in_mod!()] | ^^^^^^ not found from module `macros_stay` @@ -239,7 +335,7 @@ LL | #![doc = in_mod!()] Future breakage diagnostic: error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:36:9 + --> $DIR/key-value-expansion-scope.rs:46:9 | LL | #[doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` @@ -251,7 +347,7 @@ LL | #[doc = in_mod_escape!()] Future breakage diagnostic: error: cannot find macro `in_mod_escape` in the current scope when looking from module `macros_escape` - --> $DIR/key-value-expansion-scope.rs:39:14 + --> $DIR/key-value-expansion-scope.rs:49:14 | LL | #![doc = in_mod_escape!()] | ^^^^^^^^^^^^^ not found from module `macros_escape` diff --git a/tests/ui/attributes/key-value-expansion.stderr b/tests/ui/attributes/key-value-expansion.stderr index d785bf978196..54d79c5bebb7 100644 --- a/tests/ui/attributes/key-value-expansion.stderr +++ b/tests/ui/attributes/key-value-expansion.stderr @@ -1,3 +1,9 @@ +error: attribute value must be a literal + --> $DIR/key-value-expansion.rs:21:6 + | +LL | bug!((column!())); + | ^^^^^^^^^^^ + error: attribute value must be a literal --> $DIR/key-value-expansion.rs:27:14 | @@ -20,11 +26,5 @@ LL | some_macro!(u8); | = note: this error originates in the macro `some_macro` (in Nightly builds, run with -Z macro-backtrace for more info) -error: attribute value must be a literal - --> $DIR/key-value-expansion.rs:21:6 - | -LL | bug!((column!())); - | ^^^^^^^^^^^ - error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 26ee89dd7b3b..6193a101918b 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -1,7 +1,7 @@ // This file contains a bunch of malformed attributes. // We enable a bunch of features to not get feature-gate errs in this test. +#![deny(invalid_doc_attributes)] #![feature(rustc_attrs)] -#![feature(rustc_allow_const_fn_unstable)] #![feature(allow_internal_unstable)] // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity #![feature(fn_align)] @@ -39,8 +39,7 @@ #[deprecated = 5] //~^ ERROR malformed #[doc] -//~^ ERROR valid forms for the attribute are -//~| WARN this was previously accepted by the compiler +//~^ ERROR #[rustc_macro_transparency] //~^ ERROR malformed //~| ERROR attribute cannot be used on @@ -59,7 +58,7 @@ #[cold = 1] //~^ ERROR malformed #[must_use()] -//~^ ERROR valid forms for the attribute are +//~^ ERROR malformed #[no_mangle = 1] //~^ ERROR malformed #[unsafe(naked())] @@ -75,8 +74,7 @@ //~^ ERROR malformed //~| WARN crate-level attribute should be an inner attribute #[doc] -//~^ ERROR valid forms for the attribute are -//~| WARN this was previously accepted by the compiler +//~^ ERROR #[target_feature] //~^ ERROR malformed #[export_stable = 1] @@ -137,7 +135,7 @@ pub fn test3() {} //~^ ERROR malformed #[must_not_suspend()] //~^ ERROR malformed -#[cfi_encoding] +#[cfi_encoding = ""] //~^ ERROR malformed struct Test; @@ -146,8 +144,6 @@ struct Test; #[diagnostic::on_unimplemented = 1] //~^ WARN malformed trait Hey { - #[type_const = 1] - //~^ ERROR malformed const HEY: usize = 5; } @@ -214,12 +210,12 @@ static mut TLS: u8 = 42; #[no_link()] //~^ ERROR malformed #[macro_use = 1] -//~^ ERROR valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +//~^ ERROR malformed extern crate wloop; //~^ ERROR can't find crate for `wloop` [E0463] #[macro_export = 18] -//~^ ERROR valid forms for the attribute are +//~^ ERROR malformed #[allow_internal_unsafe = 1] //~^ ERROR malformed //~| ERROR allow_internal_unsafe side-steps the unsafe_code lint diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 0ef62d70a15c..01e70adf4ee9 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `cfg` attribute input - --> $DIR/malformed-attrs.rs:108:1 + --> $DIR/malformed-attrs.rs:106:1 | LL | #[cfg] | ^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg] = note: for more information, visit error[E0539]: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:110:1 + --> $DIR/malformed-attrs.rs:108:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ @@ -21,48 +21,13 @@ LL | #[cfg_attr] = note: for more information, visit error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:218:1 + --> $DIR/malformed-attrs.rs:214:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate -error: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:112:1 - | -LL | #[instruction_set] - | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` - | - = note: for more information, visit - -error: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:114:1 - | -LL | #[patchable_function_entry] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` - -error: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:138:1 - | -LL | #[must_not_suspend()] - | ^^^^^^^^^^^^^^^^^^^^^ - | -help: the following are the possible correct uses - | -LL - #[must_not_suspend()] -LL + #[must_not_suspend = "reason"] - | -LL - #[must_not_suspend()] -LL + #[must_not_suspend] - | - -error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:140:1 - | -LL | #[cfi_encoding] - | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` - error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:184:1 + --> $DIR/malformed-attrs.rs:180:1 | LL | #[allow] | ^^^^^^^^ @@ -78,7 +43,7 @@ LL | #[allow(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:186:1 + --> $DIR/malformed-attrs.rs:182:1 | LL | #[expect] | ^^^^^^^^^ @@ -94,7 +59,7 @@ LL | #[expect(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:188:1 + --> $DIR/malformed-attrs.rs:184:1 | LL | #[warn] | ^^^^^^^ @@ -110,7 +75,7 @@ LL | #[warn(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:190:1 + --> $DIR/malformed-attrs.rs:186:1 | LL | #[deny] | ^^^^^^^ @@ -126,7 +91,7 @@ LL | #[deny(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:192:1 + --> $DIR/malformed-attrs.rs:188:1 | LL | #[forbid] | ^^^^^^^^^ @@ -141,40 +106,26 @@ LL | #[forbid(lint1, lint2, ...)] LL | #[forbid(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ -error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:210:1 - | -LL | #[thread_local()] - | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` - -error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:214:1 - | -LL | #[no_link()] - | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` - | - = note: for more information, visit - error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:103:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:120:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:127:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:223:1 + --> $DIR/malformed-attrs.rs:219:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,27 +133,6 @@ LL | #[allow_internal_unsafe = 1] = help: add `#![feature(allow_internal_unsafe)]` 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: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:41:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:77:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - error[E0539]: malformed `windows_subsystem` attribute input --> $DIR/malformed-attrs.rs:26:1 | @@ -261,25 +191,9 @@ LL | #[deprecated = 5] | ^^^^^^^^^^^^^^^-^ | | | expected a string literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated = 5] -LL + #[deprecated = "reason"] - | -LL - #[deprecated = 5] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated = 5] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated = 5] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `rustc_macro_transparency` attribute input - --> $DIR/malformed-attrs.rs:44:1 + --> $DIR/malformed-attrs.rs:43:1 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -288,13 +202,13 @@ help: try changing it to one of the following valid forms of the attribute | LL | #[rustc_macro_transparency = "opaque"] | ++++++++++ -LL | #[rustc_macro_transparency = "semitransparent"] - | +++++++++++++++++++ +LL | #[rustc_macro_transparency = "semiopaque"] + | ++++++++++++++ LL | #[rustc_macro_transparency = "transparent"] | +++++++++++++++ error: `#[rustc_macro_transparency]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:44:1 + --> $DIR/malformed-attrs.rs:43:1 | LL | #[rustc_macro_transparency] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -302,26 +216,15 @@ LL | #[rustc_macro_transparency] = help: `#[rustc_macro_transparency]` can only be applied to macro defs error[E0539]: malformed `repr` attribute input - --> $DIR/malformed-attrs.rs:47:1 + --> $DIR/malformed-attrs.rs:46:1 | LL | #[repr] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[repr()] - | ++++++++++++++++ -LL | #[repr(C)] - | +++ -LL | #[repr(Rust)] - | ++++++ -LL | #[repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0565]: malformed `rustc_as_ptr` attribute input - --> $DIR/malformed-attrs.rs:50:1 + --> $DIR/malformed-attrs.rs:49:1 | LL | #[rustc_as_ptr = 5] | ^^^^^^^^^^^^^^^---^ @@ -330,7 +233,7 @@ LL | #[rustc_as_ptr = 5] | help: must be of the form: `#[rustc_as_ptr]` error[E0539]: malformed `rustc_align` attribute input - --> $DIR/malformed-attrs.rs:55:1 + --> $DIR/malformed-attrs.rs:54:1 | LL | #[rustc_align] | ^^^^^^^^^^^^^^ @@ -339,7 +242,7 @@ LL | #[rustc_align] | help: must be of the form: `#[rustc_align()]` error[E0539]: malformed `optimize` attribute input - --> $DIR/malformed-attrs.rs:57:1 + --> $DIR/malformed-attrs.rs:56:1 | LL | #[optimize] | ^^^^^^^^^^^ expected this to be a list @@ -354,7 +257,7 @@ LL | #[optimize(speed)] | +++++++ error[E0565]: malformed `cold` attribute input - --> $DIR/malformed-attrs.rs:59:1 + --> $DIR/malformed-attrs.rs:58:1 | LL | #[cold = 1] | ^^^^^^^---^ @@ -362,14 +265,26 @@ LL | #[cold = 1] | | didn't expect any arguments here | help: must be of the form: `#[cold]` -error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` - --> $DIR/malformed-attrs.rs:61:1 +error[E0539]: malformed `must_use` attribute input + --> $DIR/malformed-attrs.rs:60:1 | LL | #[must_use()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^--^ + | | + | didn't expect a list here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use()] +LL + #[must_use = "reason"] + | +LL - #[must_use()] +LL + #[must_use] + | error[E0565]: malformed `no_mangle` attribute input - --> $DIR/malformed-attrs.rs:63:1 + --> $DIR/malformed-attrs.rs:62:1 | LL | #[no_mangle = 1] | ^^^^^^^^^^^^---^ @@ -378,7 +293,7 @@ LL | #[no_mangle = 1] | help: must be of the form: `#[no_mangle]` error[E0565]: malformed `naked` attribute input - --> $DIR/malformed-attrs.rs:65:1 + --> $DIR/malformed-attrs.rs:64:1 | LL | #[unsafe(naked())] | ^^^^^^^^^^^^^^--^^ @@ -387,7 +302,7 @@ LL | #[unsafe(naked())] | help: must be of the form: `#[naked]` error[E0565]: malformed `track_caller` attribute input - --> $DIR/malformed-attrs.rs:67:1 + --> $DIR/malformed-attrs.rs:66:1 | LL | #[track_caller()] | ^^^^^^^^^^^^^^--^ @@ -396,13 +311,13 @@ LL | #[track_caller()] | help: must be of the form: `#[track_caller]` error[E0539]: malformed `export_name` attribute input - --> $DIR/malformed-attrs.rs:69:1 + --> $DIR/malformed-attrs.rs:68:1 | LL | #[export_name()] | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_name = "name"]` error[E0805]: malformed `used` attribute input - --> $DIR/malformed-attrs.rs:71:1 + --> $DIR/malformed-attrs.rs:70:1 | LL | #[used()] | ^^^^^^--^ @@ -420,7 +335,7 @@ LL + #[used] | error: `#[used]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:71:1 + --> $DIR/malformed-attrs.rs:70:1 | LL | #[used()] | ^^^^^^^^^ @@ -428,13 +343,13 @@ LL | #[used()] = help: `#[used]` can only be applied to statics error[E0539]: malformed `crate_name` attribute input - --> $DIR/malformed-attrs.rs:74:1 + --> $DIR/malformed-attrs.rs:73:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error[E0539]: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:80:1 + --> $DIR/malformed-attrs.rs:78:1 | LL | #[target_feature] | ^^^^^^^^^^^^^^^^^ @@ -443,7 +358,7 @@ LL | #[target_feature] | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` error[E0565]: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:82:1 + --> $DIR/malformed-attrs.rs:80:1 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^---^ @@ -452,26 +367,15 @@ LL | #[export_stable = 1] | help: must be of the form: `#[export_stable]` error[E0539]: malformed `link` attribute input - --> $DIR/malformed-attrs.rs:84:1 + --> $DIR/malformed-attrs.rs:82:1 | LL | #[link] | ^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #[link(name = "...")] - | ++++++++++++++ -LL | #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] - | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...")] - | +++++++++++++++++++++++++++++++++++++++++ -LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] - | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - = and 1 other candidate error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:88:1 + --> $DIR/malformed-attrs.rs:86:1 | LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` @@ -479,7 +383,7 @@ LL | #[link_name] = note: for more information, visit error[E0539]: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:92:1 + --> $DIR/malformed-attrs.rs:90:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` @@ -487,7 +391,7 @@ LL | #[link_section] = note: for more information, visit error[E0539]: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:94:1 + --> $DIR/malformed-attrs.rs:92:1 | LL | #[coverage] | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument @@ -500,25 +404,13 @@ LL | #[coverage(on)] | ++++ error[E0539]: malformed `sanitize` attribute input - --> $DIR/malformed-attrs.rs:96:1 + --> $DIR/malformed-attrs.rs:94:1 | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list - | -help: try changing it to one of the following valid forms of the attribute - | -LL | #[sanitize(address = "on|off")] - | ++++++++++++++++++++ -LL | #[sanitize(cfi = "on|off")] - | ++++++++++++++++ -LL | #[sanitize(hwaddress = "on|off")] - | ++++++++++++++++++++++ -LL | #[sanitize(kcfi = "on|off")] - | +++++++++++++++++ - = and 6 other candidates error[E0565]: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:101:1 + --> $DIR/malformed-attrs.rs:99:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^----^ @@ -527,7 +419,7 @@ LL | #[no_implicit_prelude = 23] | help: must be of the form: `#[no_implicit_prelude]` error[E0565]: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:103:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^----^ @@ -535,8 +427,28 @@ LL | #[proc_macro = 18] | | didn't expect any arguments here | help: must be of the form: `#[proc_macro]` +error[E0539]: malformed `instruction_set` attribute input + --> $DIR/malformed-attrs.rs:110:1 + | +LL | #[instruction_set] + | ^^^^^^^^^^^^^^^^^^ + | | + | valid arguments are `arm::a32` or `arm::t32` + | help: must be of the form: `#[instruction_set(set)]` + | + = note: for more information, visit + +error[E0539]: malformed `patchable_function_entry` attribute input + --> $DIR/malformed-attrs.rs:112:1 + | +LL | #[patchable_function_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` + error[E0565]: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:117:5 + --> $DIR/malformed-attrs.rs:115:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^----^ @@ -545,7 +457,7 @@ LL | #[coroutine = 63] || {} | help: must be of the form: `#[coroutine]` error[E0565]: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:120:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -554,7 +466,7 @@ LL | #[proc_macro_attribute = 19] | help: must be of the form: `#[proc_macro_attribute]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:125:1 + --> $DIR/malformed-attrs.rs:123:1 | LL | #[must_use = 1] | ^^^^^^^^^^^^^-^ @@ -572,7 +484,7 @@ LL + #[must_use] | error[E0539]: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:127:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ expected this to be a list @@ -586,7 +498,7 @@ LL | #[proc_macro_derive(TraitName, attributes(name1, name2, ...))] | ++++++++++++++++++++++++++++++++++++++++++ error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:134:1 + --> $DIR/malformed-attrs.rs:132:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -595,7 +507,7 @@ LL | #[rustc_layout_scalar_valid_range_start] | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:136:1 + --> $DIR/malformed-attrs.rs:134:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -603,8 +515,33 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0539]: malformed `must_not_suspend` attribute input + --> $DIR/malformed-attrs.rs:136:1 + | +LL | #[must_not_suspend()] + | ^^^^^^^^^^^^^^^^^^--^ + | | + | didn't expect a list here + | +help: try changing it to one of the following valid forms of the attribute + | +LL | #[must_not_suspend(count)] + | +++++ +LL - #[must_not_suspend()] +LL + #[must_not_suspend] + | + +error[E0539]: malformed `cfi_encoding` attribute input + --> $DIR/malformed-attrs.rs:138:1 + | +LL | #[cfi_encoding = ""] + | ^^^^^^^^^^^^^^^^^--^ + | | | + | | string is not allowed to be empty + | help: must be of the form: `#[cfi_encoding = "encoding"]` + error[E0565]: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:161:1 + --> $DIR/malformed-attrs.rs:157:1 | LL | #[marker = 3] | ^^^^^^^^^---^ @@ -613,7 +550,7 @@ LL | #[marker = 3] | help: must be of the form: `#[marker]` error[E0565]: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:163:1 + --> $DIR/malformed-attrs.rs:159:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^--^ @@ -622,7 +559,7 @@ LL | #[fundamental()] | help: must be of the form: `#[fundamental]` error[E0565]: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:171:5 + --> $DIR/malformed-attrs.rs:167:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^---^^ @@ -631,7 +568,7 @@ LL | #[unsafe(ffi_pure = 1)] | help: must be of the form: `#[ffi_pure]` error[E0539]: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:173:5 + --> $DIR/malformed-attrs.rs:169:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ @@ -642,7 +579,7 @@ LL | #[link_ordinal] = note: for more information, visit error[E0565]: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:177:5 + --> $DIR/malformed-attrs.rs:173:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^---^^ @@ -651,25 +588,13 @@ LL | #[unsafe(ffi_const = 1)] | help: must be of the form: `#[ffi_const]` error[E0539]: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:179:5 + --> $DIR/malformed-attrs.rs:175:5 | LL | #[linkage] | ^^^^^^^^^^ expected this to be of the form `linkage = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL | #[linkage = "available_externally"] - | ++++++++++++++++++++++++ -LL | #[linkage = "common"] - | ++++++++++ -LL | #[linkage = "extern_weak"] - | +++++++++++++++ -LL | #[linkage = "external"] - | ++++++++++++ - = and 5 other candidates error[E0539]: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:194:1 + --> $DIR/malformed-attrs.rs:190:1 | LL | #[debugger_visualizer] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -680,7 +605,7 @@ LL | #[debugger_visualizer] = note: for more information, visit error[E0565]: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:192:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -689,7 +614,7 @@ LL | #[automatically_derived = 18] | help: must be of the form: `#[automatically_derived]` error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:204:1 + --> $DIR/malformed-attrs.rs:200:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^---^ @@ -697,20 +622,61 @@ LL | #[non_exhaustive = 1] | | didn't expect any arguments here | help: must be of the form: `#[non_exhaustive]` -error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` - --> $DIR/malformed-attrs.rs:216:1 +error[E0565]: malformed `thread_local` attribute input + --> $DIR/malformed-attrs.rs:206:1 + | +LL | #[thread_local()] + | ^^^^^^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[thread_local]` + +error[E0565]: malformed `no_link` attribute input + --> $DIR/malformed-attrs.rs:210:1 + | +LL | #[no_link()] + | ^^^^^^^^^--^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[no_link]` + +error[E0539]: malformed `macro_use` attribute input + --> $DIR/malformed-attrs.rs:212:1 | LL | #[macro_use = 1] - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^---^ + | | + | expected a list or no arguments here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_use = 1] +LL + #[macro_use(name1, name2, ...)] + | +LL - #[macro_use = 1] +LL + #[macro_use] + | -error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` - --> $DIR/malformed-attrs.rs:221:1 +error[E0539]: malformed `macro_export` attribute input + --> $DIR/malformed-attrs.rs:217:1 | LL | #[macro_export = 18] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^----^ + | | + | expected a list or no arguments here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_export = 18] +LL + #[macro_export(local_inner_macros)] + | +LL - #[macro_export = 18] +LL + #[macro_export] + | error[E0565]: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:223:1 + --> $DIR/malformed-attrs.rs:219:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^---^ @@ -718,15 +684,6 @@ LL | #[allow_internal_unsafe = 1] | | didn't expect any arguments here | help: must be of the form: `#[allow_internal_unsafe]` -error[E0565]: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:149:5 - | -LL | #[type_const = 1] - | ^^^^^^^^^^^^^---^ - | | | - | | didn't expect any arguments here - | help: must be of the form: `#[type_const]` - error: attribute should be applied to `const fn` --> $DIR/malformed-attrs.rs:31:1 | @@ -740,7 +697,7 @@ LL | | } | |_- not a `const fn` warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/malformed-attrs.rs:84:1 + --> $DIR/malformed-attrs.rs:82:1 | LL | #[link] | ^^^^^^^ @@ -755,58 +712,64 @@ LL | | } = note: requested on the command line with `-W unused-attributes` error: `#[repr(align(...))]` is not supported on functions - --> $DIR/malformed-attrs.rs:47:1 + --> $DIR/malformed-attrs.rs:46:1 | LL | #[repr] | ^^^^^^^ | help: use `#[rustc_align(...)]` instead - --> $DIR/malformed-attrs.rs:47:1 + --> $DIR/malformed-attrs.rs:46:1 | LL | #[repr] | ^^^^^^^ -warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:155:1 - | -LL | #[diagnostic::do_not_recommend()] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default - warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:144:1 + --> $DIR/malformed-attrs.rs:142:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: at least one of the `message`, `note` and `label` options are expected + = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:146:1 + --> $DIR/malformed-attrs.rs:144:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here | = help: only `message`, `note` and `label` are allowed as options +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` + --> $DIR/malformed-attrs.rs:41:1 + | +LL | #[doc] + | ^^^^^^ + | +note: the lint level is defined here + --> $DIR/malformed-attrs.rs:3:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-attrs.rs:52:1 + --> $DIR/malformed-attrs.rs:51:1 | LL | #[inline = 5] | ^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/malformed-attrs.rs:74:1 + --> $DIR/malformed-attrs.rs:73:1 | LL | #[crate_name] | ^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/malformed-attrs.rs:116:1 +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/malformed-attrs.rs:114:1 | LL | / fn test() { LL | | #[coroutine = 63] || {} @@ -814,8 +777,14 @@ LL | | #[coroutine = 63] || {} LL | | } | |_^ +error: valid forms for the attribute are `#[doc = "string"]`, `#[doc(alias)]`, `#[doc(attribute)]`, `#[doc(auto_cfg)]`, `#[doc(cfg)]`, `#[doc(fake_variadic)]`, `#[doc(hidden)]`, `#[doc(html_favicon_url)]`, `#[doc(html_logo_url)]`, `#[doc(html_no_source)]`, `#[doc(html_playground_url)]`, `#[doc(html_root_url)]`, `#[doc(include)]`, `#[doc(inline)]`, `#[doc(issue_tracker_base_url)]`, `#[doc(keyword)]`, `#[doc(masked)]`, `#[doc(no_default_passes)]`, `#[doc(no_inline)]`, `#[doc(notable_trait)]`, `#[doc(passes)]`, `#[doc(plugins)]`, `#[doc(rust_logo)]`, `#[doc(search_unbox)]`, `#[doc(spotlight)]`, and `#[doc(test)]` + --> $DIR/malformed-attrs.rs:76:1 + | +LL | #[doc] + | ^^^^^^ + warning: `#[link_name]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:88:1 + --> $DIR/malformed-attrs.rs:86:1 | LL | #[link_name] | ^^^^^^^^^^^^ @@ -824,7 +793,7 @@ LL | #[link_name] = help: `#[link_name]` can be applied to foreign functions and foreign statics error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:96:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -833,7 +802,7 @@ LL | #[ignore()] = note: for more information, see issue #57571 warning: `#[no_implicit_prelude]` attribute cannot be used on functions - --> $DIR/malformed-attrs.rs:101:1 + --> $DIR/malformed-attrs.rs:99:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -841,8 +810,14 @@ LL | #[no_implicit_prelude = 23] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_implicit_prelude]` can be applied to crates and modules +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/malformed-attrs.rs:151:1 + | +LL | #[diagnostic::do_not_recommend()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + warning: `#[automatically_derived]` attribute cannot be used on modules - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:192:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -851,7 +826,7 @@ LL | #[automatically_derived = 18] = help: `#[automatically_derived]` can only be applied to trait impl blocks error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:230:1 + --> $DIR/malformed-attrs.rs:226:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ @@ -860,7 +835,7 @@ LL | #[ignore = 1] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:117:23 + --> $DIR/malformed-attrs.rs:115:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -868,39 +843,15 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:117:23: 117:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:115:23: 115:25}` -error: aborting due to 76 previous errors; 8 warnings emitted +error: aborting due to 75 previous errors; 8 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. Future incompatibility report: Future breakage diagnostic: -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:41:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: -error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:77:1 - | -LL | #[doc] - | ^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #57571 - = note: for more information, visit - = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default - -Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/malformed-attrs.rs:52:1 + --> $DIR/malformed-attrs.rs:51:1 | LL | #[inline = 5] | ^^^^^^^^^^^^^ @@ -911,7 +862,7 @@ LL | #[inline = 5] Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:96:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -922,7 +873,7 @@ LL | #[ignore()] Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:230:1 + --> $DIR/malformed-attrs.rs:226:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ diff --git a/tests/ui/attributes/malformed-fn-align.rs b/tests/ui/attributes/malformed-fn-align.rs index c76eda65a75b..219218f03479 100644 --- a/tests/ui/attributes/malformed-fn-align.rs +++ b/tests/ui/attributes/malformed-fn-align.rs @@ -26,7 +26,7 @@ fn f3() {} #[repr(align(16))] //~ ERROR `#[repr(align(...))]` is not supported on functions fn f4() {} -#[rustc_align(-1)] //~ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +#[rustc_align(-1)] //~ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found fn f5() {} #[rustc_align(3)] //~ ERROR invalid alignment value: not a power of two diff --git a/tests/ui/attributes/malformed-fn-align.stderr b/tests/ui/attributes/malformed-fn-align.stderr index 33f789b62695..ad01457d063b 100644 --- a/tests/ui/attributes/malformed-fn-align.stderr +++ b/tests/ui/attributes/malformed-fn-align.stderr @@ -20,9 +20,9 @@ error[E0539]: malformed `rustc_align` attribute input --> $DIR/malformed-fn-align.rs:17:1 | LL | #[rustc_align = 16] - | ^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^----^ + | | | + | | expected this to be a list | help: must be of the form: `#[rustc_align()]` error[E0589]: invalid alignment value: not an unsuffixed integer @@ -37,11 +37,11 @@ error[E0589]: invalid alignment value: not a power of two LL | #[rustc_align(0)] | ^ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/malformed-fn-align.rs:29:15 | LL | #[rustc_align(-1)] - | ^ + | ^^ expressions are not allowed here | help: negative numbers are not literals, try removing the `-` sign | diff --git a/tests/ui/attributes/malformed-must_use.rs b/tests/ui/attributes/malformed-must_use.rs index 4b98affa8abd..79a1c369f838 100644 --- a/tests/ui/attributes/malformed-must_use.rs +++ b/tests/ui/attributes/malformed-must_use.rs @@ -1,4 +1,4 @@ -#[must_use()] //~ ERROR valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` +#[must_use()] //~ ERROR malformed struct Test; fn main() {} diff --git a/tests/ui/attributes/malformed-must_use.stderr b/tests/ui/attributes/malformed-must_use.stderr index c948ba677444..d4797baa1b0b 100644 --- a/tests/ui/attributes/malformed-must_use.stderr +++ b/tests/ui/attributes/malformed-must_use.stderr @@ -1,8 +1,21 @@ -error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]` +error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-must_use.rs:1:1 | LL | #[must_use()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^--^ + | | + | didn't expect a list here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[must_use()] +LL + #[must_use = "reason"] + | +LL - #[must_use()] +LL + #[must_use] + | error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/malformed-never-type-options.rs b/tests/ui/attributes/malformed-never-type-options.rs index 0c384be0e226..7dd7a854ed2e 100644 --- a/tests/ui/attributes/malformed-never-type-options.rs +++ b/tests/ui/attributes/malformed-never-type-options.rs @@ -2,7 +2,7 @@ //! The `rustc_*` attribute is malformed, but ICEing without a `feature(rustc_attrs)` is still bad. #![rustc_never_type_options(: Unsize = "hi")] -//~^ ERROR expected unsuffixed literal, found `:` +//~^ ERROR expected a literal //~| ERROR use of an internal attribute fn main() {} diff --git a/tests/ui/attributes/malformed-never-type-options.stderr b/tests/ui/attributes/malformed-never-type-options.stderr index 0d2ff4881f2a..98870c8bdded 100644 --- a/tests/ui/attributes/malformed-never-type-options.stderr +++ b/tests/ui/attributes/malformed-never-type-options.stderr @@ -1,9 +1,3 @@ -error: expected unsuffixed literal, found `:` - --> $DIR/malformed-never-type-options.rs:4:29 - | -LL | #![rustc_never_type_options(: Unsize = "hi")] - | ^ - error[E0658]: use of an internal attribute --> $DIR/malformed-never-type-options.rs:4:1 | @@ -14,6 +8,12 @@ LL | #![rustc_never_type_options(: Unsize = "hi")] = note: the `#[rustc_never_type_options]` attribute is an internal implementation detail that will never be stable = note: `rustc_never_type_options` is used to experiment with never type fallback and work on never type stabilization +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `:` + --> $DIR/malformed-never-type-options.rs:4:29 + | +LL | #![rustc_never_type_options(: Unsize = "hi")] + | ^ + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/attributes/malformed-no-std.stderr b/tests/ui/attributes/malformed-no-std.stderr index 89d7ee410d70..e994e28e030f 100644 --- a/tests/ui/attributes/malformed-no-std.stderr +++ b/tests/ui/attributes/malformed-no-std.stderr @@ -58,7 +58,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[no_std] | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this extern crate +note: this attribute does not have an `!`, which means it is applied to this extern crate --> $DIR/malformed-no-std.rs:26:1 | LL | extern crate core; @@ -75,7 +75,7 @@ error: crate-level attribute should be an inner attribute: add an exclamation ma LL | #[no_core] | ^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this extern crate +note: this attribute does not have an `!`, which means it is applied to this extern crate --> $DIR/malformed-no-std.rs:26:1 | LL | extern crate core; diff --git a/tests/ui/attributes/malformed-reprs.stderr b/tests/ui/attributes/malformed-reprs.stderr index 3a788999542b..504ba91aac5f 100644 --- a/tests/ui/attributes/malformed-reprs.stderr +++ b/tests/ui/attributes/malformed-reprs.stderr @@ -5,17 +5,6 @@ LL | #![repr] | ^^^^^^^^ expected this to be a list | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL | #![repr()] - | ++++++++++++++++ -LL | #![repr(C)] - | +++ -LL | #![repr(Rust)] - | ++++++ -LL | #![repr(align(...))] - | ++++++++++++ - = and 2 other candidates error[E0589]: invalid `repr(align)` attribute: not a power of two --> $DIR/malformed-reprs.rs:9:14 diff --git a/tests/ui/attributes/malformed-static-align.stderr b/tests/ui/attributes/malformed-static-align.stderr index e618ca8acd75..6f5225f7278d 100644 --- a/tests/ui/attributes/malformed-static-align.stderr +++ b/tests/ui/attributes/malformed-static-align.stderr @@ -2,9 +2,9 @@ error[E0539]: malformed `rustc_align_static` attribute input --> $DIR/malformed-static-align.rs:4:1 | LL | #[rustc_align_static = 16] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^^----^ + | | | + | | expected this to be a list | help: must be of the form: `#[rustc_align_static()]` error[E0589]: invalid alignment value: not an unsuffixed integer diff --git a/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr b/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr index 094987e944fd..04907f5d638e 100644 --- a/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr +++ b/tests/ui/attributes/rustc_skip_during_method_dispatch.stderr @@ -11,9 +11,9 @@ error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input --> $DIR/rustc_skip_during_method_dispatch.rs:7:1 | LL | #[rustc_skip_during_method_dispatch = "array"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^ + | | | + | | expected this to be a list | help: must be of the form: `#[rustc_skip_during_method_dispatch(array, boxed_slice)]` error[E0539]: malformed `rustc_skip_during_method_dispatch` attribute input diff --git a/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs index 6a9853b2f6fc..7d05e08b2623 100644 --- a/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/cfg-unsafe-attributes.rs @@ -1,6 +1,6 @@ //@ build-pass -#[cfg_attr(all(), unsafe(no_mangle))] +#[cfg_attr(true, unsafe(no_mangle))] fn a() {} fn main() {} diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs index 19046c08ca8b..a034b7246a34 100644 --- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs @@ -1,9 +1,9 @@ //@ edition: 2024 -#[unsafe(cfg(any()))] //~ ERROR: is not an unsafe attribute +#[unsafe(cfg(false))] //~ ERROR: is not an unsafe attribute fn a() {} -#[unsafe(cfg_attr(any(), allow(dead_code)))] //~ ERROR: is not an unsafe attribute +#[unsafe(cfg_attr(false, allow(dead_code)))] //~ ERROR: is not an unsafe attribute fn b() {} #[unsafe(test)] //~ ERROR: is not an unsafe attribute diff --git a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr index b549a638d5ea..dec8c4d3542b 100644 --- a/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/extraneous-unsafe-attributes.stderr @@ -1,7 +1,7 @@ error: `cfg` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:3:3 | -LL | #[unsafe(cfg(any()))] +LL | #[unsafe(cfg(false))] | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes @@ -9,7 +9,7 @@ LL | #[unsafe(cfg(any()))] error: `cfg_attr` is not an unsafe attribute --> $DIR/extraneous-unsafe-attributes.rs:6:3 | -LL | #[unsafe(cfg_attr(any(), allow(dead_code)))] +LL | #[unsafe(cfg_attr(false, allow(dead_code)))] | ^^^^^^ this is not an unsafe attribute | = note: extraneous unsafe is not allowed in attributes diff --git a/tests/ui/attributes/unsafe/unsafe-attributes.rs b/tests/ui/attributes/unsafe/unsafe-attributes.rs index 5c57767b3b96..c08b0ed995e5 100644 --- a/tests/ui/attributes/unsafe/unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/unsafe-attributes.rs @@ -6,7 +6,7 @@ fn a() {} #[unsafe(export_name = "foo")] fn b() {} -#[cfg_attr(any(), unsafe(no_mangle))] +#[cfg_attr(false, unsafe(no_mangle))] static VAR2: u32 = 1; fn main() {} diff --git a/tests/ui/attributes/use-doc-alias-name.rs b/tests/ui/attributes/use-doc-alias-name.rs index 1fc9199b6e38..4d27249b89a7 100644 --- a/tests/ui/attributes/use-doc-alias-name.rs +++ b/tests/ui/attributes/use-doc-alias-name.rs @@ -42,7 +42,7 @@ fn main() { //~| HELP: `S5` has a name defined in the doc alias attribute as `DocAliasS5` not_exist_module::DocAliasS1; - //~^ ERROR: use of unresolved module or unlinked crate `not_exist_module` + //~^ ERROR: cannot find module or crate `not_exist_module` //~| HELP: you might be missing a crate named `not_exist_module` use_doc_alias_name_extern::DocAliasS1; @@ -50,7 +50,7 @@ fn main() { //~| HELP: `S1` has a name defined in the doc alias attribute as `DocAliasS1` m::n::DocAliasX::y::S6; - //~^ ERROR: could not find `DocAliasX` in `n` + //~^ ERROR: cannot find `DocAliasX` in `n` //~| HELP: `x` has a name defined in the doc alias attribute as `DocAliasX` m::n::x::y::DocAliasS6; diff --git a/tests/ui/attributes/use-doc-alias-name.stderr b/tests/ui/attributes/use-doc-alias-name.stderr index 07f4865e4152..3b4a0a919b17 100644 --- a/tests/ui/attributes/use-doc-alias-name.stderr +++ b/tests/ui/attributes/use-doc-alias-name.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `DocAliasX` in `n` +error[E0433]: cannot find `DocAliasX` in `n` --> $DIR/use-doc-alias-name.rs:52:11 | LL | m::n::DocAliasX::y::S6; @@ -136,7 +136,7 @@ LL - doc_alias_f2(); LL + f(); | -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `not_exist_module` +error[E0433]: cannot find module or crate `not_exist_module` in this scope --> $DIR/use-doc-alias-name.rs:44:5 | LL | not_exist_module::DocAliasS1; diff --git a/tests/ui/auto-traits/assoc-ty.current.stderr b/tests/ui/auto-traits/assoc-ty.current.stderr index d793ae665267..5d3df17d26b1 100644 --- a/tests/ui/auto-traits/assoc-ty.current.stderr +++ b/tests/ui/auto-traits/assoc-ty.current.stderr @@ -1,9 +1,9 @@ error[E0380]: auto traits cannot have associated items - --> $DIR/assoc-ty.rs:10:10 + --> $DIR/assoc-ty.rs:11:10 | LL | auto trait Trait { | ----- auto traits cannot have associated items -LL | +... LL | type Output; | ^^^^^^ @@ -12,8 +12,9 @@ error[E0658]: auto traits are experimental and possibly buggy | LL | / auto trait Trait { LL | | -LL | | type Output; LL | | +LL | | type Output; +... | LL | | } | |_^ | @@ -22,7 +23,7 @@ LL | | } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0308]: mismatched types - --> $DIR/assoc-ty.rs:15:36 + --> $DIR/assoc-ty.rs:17:36 | LL | let _: <() as Trait>::Output = (); | --------------------- ^^ expected associated type, found `()` diff --git a/tests/ui/auto-traits/assoc-ty.next.stderr b/tests/ui/auto-traits/assoc-ty.next.stderr index a41f7d992785..19621064aa42 100644 --- a/tests/ui/auto-traits/assoc-ty.next.stderr +++ b/tests/ui/auto-traits/assoc-ty.next.stderr @@ -1,9 +1,9 @@ error[E0380]: auto traits cannot have associated items - --> $DIR/assoc-ty.rs:10:10 + --> $DIR/assoc-ty.rs:11:10 | LL | auto trait Trait { | ----- auto traits cannot have associated items -LL | +... LL | type Output; | ^^^^^^ @@ -12,8 +12,9 @@ error[E0658]: auto traits are experimental and possibly buggy | LL | / auto trait Trait { LL | | -LL | | type Output; LL | | +LL | | type Output; +... | LL | | } | |_^ | @@ -22,13 +23,13 @@ LL | | } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _` - --> $DIR/assoc-ty.rs:15:12 + --> $DIR/assoc-ty.rs:17:12 | LL | let _: <() as Trait>::Output = (); | ^^^^^^^^^^^^^^^^^^^^^ types differ error[E0271]: type mismatch resolving `<() as Trait>::Output normalizes-to _` - --> $DIR/assoc-ty.rs:15:12 + --> $DIR/assoc-ty.rs:17:12 | LL | let _: <() as Trait>::Output = (); | ^^^^^^^^^^^^^^^^^^^^^ types differ diff --git a/tests/ui/auto-traits/assoc-ty.rs b/tests/ui/auto-traits/assoc-ty.rs index efbfead9cd03..98a86d9a7540 100644 --- a/tests/ui/auto-traits/assoc-ty.rs +++ b/tests/ui/auto-traits/assoc-ty.rs @@ -7,13 +7,16 @@ auto trait Trait { //~^ ERROR auto traits are experimental and possibly buggy + //~| HELP add `#![feature(auto_traits)]` to the crate attributes to enable type Output; //~^ ERROR auto traits cannot have associated items + //~| HELP remove the associated items } fn main() { let _: <() as Trait>::Output = (); //[current]~^ ERROR mismatched types - //[next]~^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` + //[current]~| HELP consider constraining the associated type `<() as Trait>::Output` to `()` or calling a method that returns `<() as Trait>::Output` + //[next]~^^^ ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` //[next]~| ERROR type mismatch resolving `<() as Trait>::Output normalizes-to _` } diff --git a/tests/ui/autodiff/incremental.rs b/tests/ui/autodiff/incremental.rs index a79059deaa77..00dd632712ab 100644 --- a/tests/ui/autodiff/incremental.rs +++ b/tests/ui/autodiff/incremental.rs @@ -1,6 +1,6 @@ //@ revisions: DEBUG RELEASE //@[RELEASE] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3 -Clto=fat -//@[DEBUG] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=0 -Clto=fat -C debuginfo=2 +//@[DEBUG] compile-flags: -Zautodiff=Enable,NoTT -Copt-level=0 -Clto=fat -Cdebuginfo=2 -Ccodegen-units=8 //@ needs-enzyme //@ incremental //@ no-prefer-dynamic @@ -13,6 +13,10 @@ // dropped. We now use globals instead and add this test to verify that incremental // keeps working. Also testing debug mode while at it. +// We extended this test to use 8 codegen-units in debug mode and call an intrinsic like powi, +// rather than just simple arithmetic. This caused a compilation failure, since the definition of +// the intrinsic was not available in the same cgu as the function being differentiated. + use std::autodiff::autodiff_reverse; #[autodiff_reverse(bar, Duplicated, Duplicated)] @@ -20,7 +24,7 @@ pub fn foo(r: &[f64; 10], res: &mut f64) { let mut output = [0.0; 10]; output[0] = r[0]; output[1] = r[1] * r[2]; - output[2] = r[4] * r[5]; + output[2] = r[4] * r[5].powi(2); output[3] = r[2] * r[6]; output[4] = r[1] * r[7]; output[5] = r[2] * r[8]; diff --git a/tests/ui/autodiff/visibility.rs b/tests/ui/autodiff/visibility.rs index a84df75e7996..3cf13b5b5dce 100644 --- a/tests/ui/autodiff/visibility.rs +++ b/tests/ui/autodiff/visibility.rs @@ -1,5 +1,6 @@ //@ ignore-enzyme //@ revisions: std_autodiff no_std_autodiff +//@ only-nightly //@[no_std_autodiff] check-pass //@ proc-macro: my_macro.rs #![crate_type = "lib"] @@ -12,5 +13,4 @@ use my_macro::autodiff_forward; // bring `autodiff_forward` in scope #[autodiff_forward(dfoo)] //[std_autodiff]~^^^ ERROR the name `autodiff_forward` is defined multiple times -//[std_autodiff]~^^ ERROR this rustc version does not support autodiff fn foo() {} diff --git a/tests/ui/autodiff/visibility.std_autodiff.stderr b/tests/ui/autodiff/visibility.std_autodiff.stderr index e45f1139012a..6a0cdd492e2d 100644 --- a/tests/ui/autodiff/visibility.std_autodiff.stderr +++ b/tests/ui/autodiff/visibility.std_autodiff.stderr @@ -1,5 +1,5 @@ error[E0252]: the name `autodiff_forward` is defined multiple times - --> $DIR/visibility.rs:11:5 + --> $DIR/visibility.rs:12:5 | LL | use std::autodiff::autodiff_forward; | ------------------------------- previous import of the macro `autodiff_forward` here @@ -13,12 +13,6 @@ help: you can use `as` to change the binding name of the import LL | use my_macro::autodiff_forward as other_autodiff_forward; // bring `autodiff_forward` in scope | +++++++++++++++++++++++++ -error: this rustc version does not support autodiff - --> $DIR/visibility.rs:13:1 - | -LL | #[autodiff_forward(dfoo)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0252`. diff --git a/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs new file mode 100644 index 000000000000..fb7a8ee103e1 --- /dev/null +++ b/tests/ui/autoref-autoderef/autoderef-arc-boxed-closure-call.rs @@ -0,0 +1,10 @@ +//! regression test for +//@ run-pass + +use std::sync::Arc; + +fn main() { + let x = 5; + let command = Arc::new(Box::new(|| x * 2)); + assert_eq!(command(), 10); +} diff --git a/tests/ui/binop/binary-op-suggest-deref.stderr b/tests/ui/binop/binary-op-suggest-deref.stderr index 0c9b1d9bd938..eb17c6cbbc66 100644 --- a/tests/ui/binop/binary-op-suggest-deref.stderr +++ b/tests/ui/binop/binary-op-suggest-deref.stderr @@ -305,13 +305,19 @@ LL | let _ = FOO & (*"Sized".to_string().into_boxed_str()); help: the following other types implement trait `BitAnd` --> $SRC_DIR/core/src/ops/bit.rs:LL:COL | - = note: `&i32` implements `BitAnd` + = note: `i32` implements `BitAnd` + ::: $SRC_DIR/core/src/ops/bit.rs:LL:COL | - = note: `&i32` implements `BitAnd` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `BitAnd` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `BitAnd<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `BitAnd` + = note: `&i32` implements `BitAnd` = note: this error originates in the macro `bitand_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the size for values of type `str` cannot be known at compilation time diff --git a/tests/ui/binop/binary-operation-error-on-function-70724.stderr b/tests/ui/binop/binary-operation-error-on-function-70724.stderr index 11b0e4ba19c5..2eb980764a39 100644 --- a/tests/ui/binop/binary-operation-error-on-function-70724.stderr +++ b/tests/ui/binop/binary-operation-error-on-function-70724.stderr @@ -6,8 +6,6 @@ LL | assert_eq!(a, 0); | | | fn() -> i32 {a} | {integer} - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/binary-operation-error-on-function-70724.rs:7:5 @@ -17,7 +15,6 @@ LL | assert_eq!(a, 0); | = note: expected fn item `fn() -> i32 {a}` found type `{integer}` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn() -> i32 {a}` doesn't implement `Debug` --> $DIR/binary-operation-error-on-function-70724.rs:7:5 @@ -29,7 +26,6 @@ LL | assert_eq!(a, 0); | ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn() -> i32 {a}` | = help: use parentheses to call this function: `a()` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/binop/binop-mul-i32-f32.stderr b/tests/ui/binop/binop-mul-i32-f32.stderr index dc4e7fdf6c14..a8893700b1be 100644 --- a/tests/ui/binop/binop-mul-i32-f32.stderr +++ b/tests/ui/binop/binop-mul-i32-f32.stderr @@ -8,13 +8,19 @@ LL | x * y help: the following other types implement trait `Mul` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Mul` + = note: `i32` implements `Mul` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i32` implements `Mul` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i32` implements `Mul` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i32` implements `Mul<&i32>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i32` implements `Mul` + = note: `&i32` implements `Mul` = note: this error originates in the macro `mul_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/binop/can-have-side-effects-consider-operands.rs b/tests/ui/binop/can-have-side-effects-consider-operands.rs new file mode 100644 index 000000000000..34eeb11c6add --- /dev/null +++ b/tests/ui/binop/can-have-side-effects-consider-operands.rs @@ -0,0 +1,23 @@ +//@ check-pass + +#![allow(unused)] + +// Test if `Expr::can_have_side_effects` considers operands of binary operators. + +fn drop_repeat_in_arm_body() { + // Built-in lint `dropping_copy_types` relies on `Expr::can_have_side_effects` + // (See rust-clippy#9482 and rust#113231) + + match () { + () => drop(5 % 3), // No side effects + //~^ WARNING calls to `std::mem::drop` with a value that implements `Copy` does nothing + } + match () { + () => drop(5 % calls_are_considered_side_effects()), // Definitely has side effects + } +} +fn calls_are_considered_side_effects() -> i32 { + 3 +} + +fn main() {} diff --git a/tests/ui/binop/can-have-side-effects-consider-operands.stderr b/tests/ui/binop/can-have-side-effects-consider-operands.stderr new file mode 100644 index 000000000000..ef3fc6b4be7e --- /dev/null +++ b/tests/ui/binop/can-have-side-effects-consider-operands.stderr @@ -0,0 +1,13 @@ +warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing + --> $DIR/can-have-side-effects-consider-operands.rs:12:15 + | +LL | () => drop(5 % 3), // No side effects + | ^^^^^-----^ + | | + | argument has type `i32` + | + = note: use `let _ = ...` to ignore the expression or result + = note: `#[warn(dropping_copy_types)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/binop/eq-vec.stderr b/tests/ui/binop/eq-vec.stderr index 14739752877c..158bfe625934 100644 --- a/tests/ui/binop/eq-vec.stderr +++ b/tests/ui/binop/eq-vec.stderr @@ -12,7 +12,6 @@ note: an implementation of `PartialEq` might be missing for `Foo` | LL | enum Foo { | ^^^^^^^^ must implement `PartialEq` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `Foo` with `#[derive(PartialEq)]` | LL + #[derive(PartialEq)] diff --git a/tests/ui/binop/function-comparison-errors-59488.stderr b/tests/ui/binop/function-comparison-errors-59488.stderr index 615458bc45b4..43ecd6a36f38 100644 --- a/tests/ui/binop/function-comparison-errors-59488.stderr +++ b/tests/ui/binop/function-comparison-errors-59488.stderr @@ -80,24 +80,18 @@ LL | assert_eq!(Foo::Bar, i); | | | fn(usize) -> Foo {Foo::Bar} | fn(usize) -> Foo {Foo::Bar} - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` --> $DIR/function-comparison-errors-59488.rs:31:5 | LL | assert_eq!(Foo::Bar, i); | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}` - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` --> $DIR/function-comparison-errors-59488.rs:31:5 | LL | assert_eq!(Foo::Bar, i); | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}` - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors diff --git a/tests/ui/binop/issue-77910-1.stderr b/tests/ui/binop/issue-77910-1.stderr index 80c384f39bd1..9503813f4eb8 100644 --- a/tests/ui/binop/issue-77910-1.stderr +++ b/tests/ui/binop/issue-77910-1.stderr @@ -6,8 +6,6 @@ LL | assert_eq!(foo, y); | | | for<'a> fn(&'a i32) -> &'a i32 {foo} | _ - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `for<'a> fn(&'a i32) -> &'a i32 {foo}` doesn't implement `Debug` --> $DIR/issue-77910-1.rs:8:5 @@ -19,7 +17,6 @@ LL | assert_eq!(foo, y); | ^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}` | = help: use parentheses to call this function: `foo(/* &i32 */)` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0381]: used binding `xs` isn't initialized --> $DIR/issue-77910-1.rs:3:5 diff --git a/tests/ui/block-result/block-must-not-have-result-while.stderr b/tests/ui/block-result/block-must-not-have-result-while.stderr index 0b9941ea96ef..d8e854c9b9ba 100644 --- a/tests/ui/block-result/block-must-not-have-result-while.stderr +++ b/tests/ui/block-result/block-must-not-have-result-while.stderr @@ -9,12 +9,8 @@ LL | while true { error[E0308]: mismatched types --> $DIR/block-must-not-have-result-while.rs:5:9 | -LL | / while true { -LL | | true - | | ^^^^ expected `()`, found `bool` -LL | | -LL | | } - | |_____- expected this to be `()` +LL | true + | ^^^^ expected `()`, found `bool` error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/meta/no_std-extern-libc.rs b/tests/ui/bootstrap/no_std-extern-libc.rs similarity index 100% rename from tests/ui/meta/no_std-extern-libc.rs rename to tests/ui/bootstrap/no_std-extern-libc.rs diff --git a/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.stderr b/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.stderr index b5c2b662f315..c82821b04a35 100644 --- a/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.stderr +++ b/tests/ui/borrowck/alias-liveness/higher-ranked-outlives-for-capture.stderr @@ -8,8 +8,6 @@ LL | test(&vec![]) | argument requires that borrow lasts for `'static` LL | } | - temporary value is freed at the end of this statement - | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrow-box-in-map-3026.rs b/tests/ui/borrowck/borrow-box-in-map-3026.rs new file mode 100644 index 000000000000..dd63075eecba --- /dev/null +++ b/tests/ui/borrowck/borrow-box-in-map-3026.rs @@ -0,0 +1,12 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3026 + +//@ run-pass + +use std::collections::HashMap; + +pub fn main() { + let x: Box<_>; + let mut buggy_map: HashMap = HashMap::new(); + x = Box::new(1); + buggy_map.insert(42, &*x); +} diff --git a/tests/ui/borrowck/borrow-immutable-deref-box.rs b/tests/ui/borrowck/borrow-immutable-deref-box.rs new file mode 100644 index 000000000000..6d4932b5b4b5 --- /dev/null +++ b/tests/ui/borrowck/borrow-immutable-deref-box.rs @@ -0,0 +1,7 @@ +//! regression test for issue +fn f(x: &mut u32) {} + +fn main() { + let x = Box::new(3); + f(&mut *x); //~ ERROR cannot borrow `*x` as mutable, as `x` is not declared as mutable +} diff --git a/tests/ui/borrowck/borrow-immutable-deref-box.stderr b/tests/ui/borrowck/borrow-immutable-deref-box.stderr new file mode 100644 index 000000000000..6456dc8a0e5a --- /dev/null +++ b/tests/ui/borrowck/borrow-immutable-deref-box.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `*x` as mutable, as `x` is not declared as mutable + --> $DIR/borrow-immutable-deref-box.rs:6:7 + | +LL | f(&mut *x); + | ^^^^^^^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut x = Box::new(3); + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/borrowck-and-init.stderr b/tests/ui/borrowck/borrowck-and-init.stderr index 37386f1c4651..e6d49bc6e471 100644 --- a/tests/ui/borrowck/borrowck-and-init.stderr +++ b/tests/ui/borrowck/borrowck-and-init.stderr @@ -8,8 +8,6 @@ LL | println!("{}", false && { i = 5; true }); | ----- binding initialized here in some conditions LL | println!("{}", i); | ^ `i` used here but it is possibly-uninitialized - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr b/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr index 7f0ecf7b3596..9fd4ee9b99ba 100644 --- a/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr +++ b/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr @@ -8,7 +8,6 @@ LL | let x = defer(&vec!["Goodbye", "world!"]); LL | x.x[0]; | ------ borrow later used here | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider using a `let` binding to create a longer lived value | LL ~ let binding = vec!["Goodbye", "world!"]; diff --git a/tests/ui/borrowck/borrowck-break-uninit-2.stderr b/tests/ui/borrowck/borrowck-break-uninit-2.stderr index e23ca534e745..03730e338ee0 100644 --- a/tests/ui/borrowck/borrowck-break-uninit-2.stderr +++ b/tests/ui/borrowck/borrowck-break-uninit-2.stderr @@ -7,7 +7,6 @@ LL | let x: isize; LL | println!("{}", x); | ^ `x` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let x: isize = 42; diff --git a/tests/ui/borrowck/borrowck-break-uninit.stderr b/tests/ui/borrowck/borrowck-break-uninit.stderr index 0367d224f801..6ed095f2e4a3 100644 --- a/tests/ui/borrowck/borrowck-break-uninit.stderr +++ b/tests/ui/borrowck/borrowck-break-uninit.stderr @@ -7,7 +7,6 @@ LL | let x: isize; LL | println!("{}", x); | ^ `x` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let x: isize = 42; diff --git a/tests/ui/borrowck/borrowck-or-init.stderr b/tests/ui/borrowck/borrowck-or-init.stderr index 7b43f2aee30e..63c0c982351b 100644 --- a/tests/ui/borrowck/borrowck-or-init.stderr +++ b/tests/ui/borrowck/borrowck-or-init.stderr @@ -8,8 +8,6 @@ LL | println!("{}", false || { i = 5; true }); | ----- binding initialized here in some conditions LL | println!("{}", i); | ^ `i` used here but it is possibly-uninitialized - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-while-break.stderr b/tests/ui/borrowck/borrowck-while-break.stderr index e91af728b649..68333ce0a75d 100644 --- a/tests/ui/borrowck/borrowck-while-break.stderr +++ b/tests/ui/borrowck/borrowck-while-break.stderr @@ -8,8 +8,6 @@ LL | while cond { ... LL | println!("{}", v); | ^ `v` used here but it is possibly-uninitialized - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.rs b/tests/ui/borrowck/derive-clone-implicit-bound.rs new file mode 100644 index 000000000000..cd92ac1e9e59 --- /dev/null +++ b/tests/ui/borrowck/derive-clone-implicit-bound.rs @@ -0,0 +1,32 @@ +// Issue #108894 + +use std::marker::PhantomData; + +#[derive(Clone, Copy)] //~ NOTE: derived `Clone` adds implicit bounds on type parameters +pub struct TypedAddress{ +//~^ NOTE: if all bounds were met, you could clone the value +//~| NOTE: introduces an implicit `T: Clone` bound + inner: u64, + phantom: PhantomData, +} + +pub trait Memory { + fn write_value(&self, offset: TypedAddress, value: &T); + fn return_value(&self, offset: TypedAddress) -> T; + //~^ NOTE: consider changing this parameter type in method `return_value` to borrow instead if owning the value isn't necessary + //~| NOTE: in this method + //~| NOTE: this parameter takes ownership of the value + fn update_value(&self, offset: TypedAddress, update: F) + //~^ NOTE: move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait + where F: FnOnce(T) -> T //~ HELP: consider further restricting type parameter `T` + { + let old = self.return_value(offset); //~ NOTE: value moved here + //~^ NOTE: you could clone this value + let new = update(old); + self.write_value(offset, &new); //~ ERROR: use of moved value: `offset` + //~^ NOTE: value used here after move + //~| HELP: consider manually implementing `Clone` to avoid undesired bounds + } +} + +fn main() {} diff --git a/tests/ui/borrowck/derive-clone-implicit-bound.stderr b/tests/ui/borrowck/derive-clone-implicit-bound.stderr new file mode 100644 index 000000000000..246fd1eaf075 --- /dev/null +++ b/tests/ui/borrowck/derive-clone-implicit-bound.stderr @@ -0,0 +1,38 @@ +error[E0382]: use of moved value: `offset` + --> $DIR/derive-clone-implicit-bound.rs:26:26 + | +LL | fn update_value(&self, offset: TypedAddress, update: F) + | ------ move occurs because `offset` has type `TypedAddress`, which does not implement the `Copy` trait +... +LL | let old = self.return_value(offset); + | ------ value moved here +... +LL | self.write_value(offset, &new); + | ^^^^^^ value used here after move + | +note: consider changing this parameter type in method `return_value` to borrow instead if owning the value isn't necessary + --> $DIR/derive-clone-implicit-bound.rs:15:39 + | +LL | fn return_value(&self, offset: TypedAddress) -> T; + | ------------ in this method ^^^^^^^^^^^^^^^ this parameter takes ownership of the value +note: if all bounds were met, you could clone the value + --> $DIR/derive-clone-implicit-bound.rs:6:1 + | +LL | #[derive(Clone, Copy)] + | ----- derived `Clone` adds implicit bounds on type parameters +LL | pub struct TypedAddress{ + | ^^^^^^^^^^^^^^^^^^^^^^^^-^ + | | + | introduces an implicit `T: Clone` bound +... +LL | let old = self.return_value(offset); + | ------ you could clone this value + = help: consider manually implementing `Clone` to avoid undesired bounds +help: consider further restricting type parameter `T` with trait `Copy` + | +LL | where F: FnOnce(T) -> T, T: Copy + | +++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/borrowck/fsu-moves-and-copies.rs b/tests/ui/borrowck/fsu-moves-and-copies.rs index 397e4199bc05..6576fb51a5d2 100644 --- a/tests/ui/borrowck/fsu-moves-and-copies.rs +++ b/tests/ui/borrowck/fsu-moves-and-copies.rs @@ -1,11 +1,9 @@ //@ run-pass #![allow(non_camel_case_types)] -#![allow(stable_features)] // Issue 4691: Ensure that functional-struct-updates operates // correctly and moves rather than copy when appropriate. -#![feature(core)] struct ncint { v: isize } fn ncint(v: isize) -> ncint { ncint { v: v } } diff --git a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr index 8e1cd800b372..54aa756e581d 100644 --- a/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr +++ b/tests/ui/borrowck/ice-mutability-error-slicing-121807.stderr @@ -20,7 +20,7 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16; | ^^^^^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: Self::Assoc<'_>` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait diff --git a/tests/ui/borrowck/issue-24267-flow-exit.stderr b/tests/ui/borrowck/issue-24267-flow-exit.stderr index 216f8d49b1b0..e81f00f8c157 100644 --- a/tests/ui/borrowck/issue-24267-flow-exit.stderr +++ b/tests/ui/borrowck/issue-24267-flow-exit.stderr @@ -7,7 +7,6 @@ LL | loop { x = break; } LL | println!("{}", x); | ^ `x` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let x: i32 = 42; @@ -22,7 +21,6 @@ LL | for _ in 0..10 { x = continue; } LL | println!("{}", x); | ^ `x` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let x: i32 = 42; diff --git a/tests/ui/borrowck/issue-47646.stderr b/tests/ui/borrowck/issue-47646.stderr index cfe6f3f39938..c8d48b76757a 100644 --- a/tests/ui/borrowck/issue-47646.stderr +++ b/tests/ui/borrowck/issue-47646.stderr @@ -12,8 +12,6 @@ LL | println!("{:?}", heap); ... LL | }; | - ... and the mutable borrow might be used here, when that temporary is dropped and runs the destructor for type `(Option>, ())` - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr index 29a7363705cd..9136d6a7dc33 100644 --- a/tests/ui/borrowck/issue-64453.stderr +++ b/tests/ui/borrowck/issue-64453.stderr @@ -8,7 +8,6 @@ note: function `format` is not const --> $SRC_DIR/alloc/src/fmt.rs:LL:COL = note: calls in statics are limited to constant functions, tuple structs and tuple variants = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)` - = note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0507]: cannot move out of static item `settings_dir` --> $DIR/issue-64453.rs:13:37 diff --git a/tests/ui/borrowck/issue-92157.rs b/tests/ui/borrowck/issue-92157.rs deleted file mode 100644 index 3dbcb4ad8b7f..000000000000 --- a/tests/ui/borrowck/issue-92157.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ add-minicore -#![feature(no_core)] -#![feature(lang_items)] - -#![no_core] - -#[cfg(target_os = "linux")] -#[link(name = "c")] -extern "C" {} - -#[lang = "start"] -fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { - //~^ ERROR lang item `start` function has wrong type [E0308] - 40+2 -} - -extern crate minicore; -use minicore::*; - -fn main() {} diff --git a/tests/ui/borrowck/issue-92157.stderr b/tests/ui/borrowck/issue-92157.stderr deleted file mode 100644 index 248d700ab4b9..000000000000 --- a/tests/ui/borrowck/issue-92157.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: lang item `start` function has wrong type - --> $DIR/issue-92157.rs:12:1 - | -LL | fn start(_main: fn() -> T, _argc: isize, _argv: *const *const u8) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters - | - = note: expected signature `fn(fn() -> T, isize, *const *const u8, u8) -> _` - found signature `fn(fn() -> T, isize, *const *const u8) -> _` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.fixed b/tests/ui/borrowck/mut-borrow-of-mut-ref.fixed new file mode 100644 index 000000000000..f70983c65223 --- /dev/null +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.fixed @@ -0,0 +1,37 @@ +// Suggest not mutably borrowing a mutable reference +//@ run-rustfix +#![crate_type = "rlib"] + +pub fn f(mut b: &mut i32) { + //~^ ERROR: cannot borrow + //~| NOTE: not mutable + //~| NOTE: the binding is already a mutable borrow + //~| HELP: consider making the binding mutable if you need to reborrow multiple times + h(b); + //~^ NOTE: cannot borrow as mutable + //~| HELP: if there is only one mutable reborrow, remove the `&mut` + g(&mut &mut b); + //~^ NOTE: cannot borrow as mutable +} + +pub fn g(mut b: &mut i32) { //~ NOTE: the binding is already a mutable borrow + //~^ HELP: consider making the binding mutable if you need to reborrow multiple times + h(&mut &mut b); + //~^ ERROR: cannot borrow + //~| NOTE: cannot borrow as mutable +} + +pub fn h(_: &mut i32) {} + +trait Foo { + fn bar(&mut self); +} + +impl Foo for &mut String { + fn bar(&mut self) {} +} + +pub fn baz(mut f: &mut String) { //~ HELP consider making the binding mutable + f.bar(); //~ ERROR cannot borrow `f` as mutable, as it is not declared as mutable + //~^ NOTE cannot borrow as mutable +} diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.rs b/tests/ui/borrowck/mut-borrow-of-mut-ref.rs index 33954592bf65..d150b249bf2d 100644 --- a/tests/ui/borrowck/mut-borrow-of-mut-ref.rs +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.rs @@ -1,4 +1,5 @@ // Suggest not mutably borrowing a mutable reference +//@ run-rustfix #![crate_type = "rlib"] pub fn f(b: &mut i32) { @@ -11,7 +12,6 @@ pub fn f(b: &mut i32) { //~| HELP: if there is only one mutable reborrow, remove the `&mut` g(&mut &mut b); //~^ NOTE: cannot borrow as mutable - //~| HELP: if there is only one mutable reborrow, remove the `&mut` } pub fn g(b: &mut i32) { //~ NOTE: the binding is already a mutable borrow @@ -19,7 +19,6 @@ pub fn g(b: &mut i32) { //~ NOTE: the binding is already a mutable borrow h(&mut &mut b); //~^ ERROR: cannot borrow //~| NOTE: cannot borrow as mutable - //~| HELP: if there is only one mutable reborrow, remove the `&mut` } pub fn h(_: &mut i32) {} diff --git a/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr b/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr index 4c4a5e718393..01ceba90c943 100644 --- a/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr +++ b/tests/ui/borrowck/mut-borrow-of-mut-ref.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable - --> $DIR/mut-borrow-of-mut-ref.rs:4:10 + --> $DIR/mut-borrow-of-mut-ref.rs:5:10 | LL | pub fn f(b: &mut i32) { | ^ not mutable @@ -11,7 +11,7 @@ LL | g(&mut &mut b); | ------ cannot borrow as mutable | note: the binding is already a mutable borrow - --> $DIR/mut-borrow-of-mut-ref.rs:4:13 + --> $DIR/mut-borrow-of-mut-ref.rs:5:13 | LL | pub fn f(b: &mut i32) { | ^^^^^^^^ @@ -24,11 +24,6 @@ help: if there is only one mutable reborrow, remove the `&mut` LL - h(&mut b); LL + h(b); | -help: if there is only one mutable reborrow, remove the `&mut` - | -LL - g(&mut &mut b); -LL + g(&mut b); - | error[E0596]: cannot borrow `b` as mutable, as it is not declared as mutable --> $DIR/mut-borrow-of-mut-ref.rs:19:12 @@ -45,14 +40,9 @@ help: consider making the binding mutable if you need to reborrow multiple times | LL | pub fn g(mut b: &mut i32) { | +++ -help: if there is only one mutable reborrow, remove the `&mut` - | -LL - h(&mut &mut b); -LL + h(&mut b); - | error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable - --> $DIR/mut-borrow-of-mut-ref.rs:36:5 + --> $DIR/mut-borrow-of-mut-ref.rs:35:5 | LL | f.bar(); | ^ cannot borrow as mutable diff --git a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs index cf927e34fb41..48466af50481 100644 --- a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs +++ b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.rs @@ -4,9 +4,9 @@ fn main() { let mut a = E::StructVar { boxed: Box::new(5_i32) }; - //~^ ERROR failed to resolve: use of undeclared type `E` + //~^ ERROR cannot find type `E` match a { E::StructVar { box boxed } => { } - //~^ ERROR failed to resolve: use of undeclared type `E` + //~^ ERROR cannot find type `E` } } diff --git a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr index 349546606a57..7be9ed27db0e 100644 --- a/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr +++ b/tests/ui/borrowck/non-ADT-struct-pattern-box-pattern-ice-121463.stderr @@ -1,20 +1,24 @@ -error[E0433]: failed to resolve: use of undeclared type `E` +error[E0433]: cannot find type `E` in this scope --> $DIR/non-ADT-struct-pattern-box-pattern-ice-121463.rs:6:17 | LL | let mut a = E::StructVar { boxed: Box::new(5_i32) }; - | ^ - | | - | use of undeclared type `E` - | help: a trait with a similar name exists: `Eq` + | ^ use of undeclared type `E` + | +help: a trait with a similar name exists + | +LL | let mut a = Eq::StructVar { boxed: Box::new(5_i32) }; + | + -error[E0433]: failed to resolve: use of undeclared type `E` +error[E0433]: cannot find type `E` in this scope --> $DIR/non-ADT-struct-pattern-box-pattern-ice-121463.rs:9:9 | LL | E::StructVar { box boxed } => { } - | ^ - | | - | use of undeclared type `E` - | help: a trait with a similar name exists: `Eq` + | ^ use of undeclared type `E` + | +help: a trait with a similar name exists + | +LL | Eq::StructVar { box boxed } => { } + | + error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/ownership-struct-update-moved-error.stderr b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr index 83cfc7bb412c..f081bea76b7a 100644 --- a/tests/ui/borrowck/ownership-struct-update-moved-error.stderr +++ b/tests/ui/borrowck/ownership-struct-update-moved-error.stderr @@ -13,7 +13,6 @@ note: `Mine::make_string_bar` takes ownership of the receiver `self`, which move | LL | fn make_string_bar(mut self) -> Mine { | ^^^^ - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/reborrow-in-match-suggest-deref.fixed b/tests/ui/borrowck/reborrow-in-match-suggest-deref.fixed new file mode 100644 index 000000000000..3f52e57a804c --- /dev/null +++ b/tests/ui/borrowck/reborrow-in-match-suggest-deref.fixed @@ -0,0 +1,23 @@ +// Regression test for #81059. +// edition:2024 +//@ run-rustfix + +#![allow(unused)] + +fn test(mut outer: &mut Option) { + //~^ NOTE: the binding is already a mutable borrow + //~| HELP: consider making the binding mutable if you need to reborrow multiple times + match (&mut *outer, 23) { + //~^ ERROR: cannot borrow `outer` as mutable, as it is not declared as mutable + //~| NOTE: cannot borrow as mutable + //~| HELP: to reborrow the mutable reference, add `*` + (Some(inner), _) => { + *inner = 17; + } + _ => { + *outer = Some(2); + } + } +} + +fn main() {} diff --git a/tests/ui/borrowck/reborrow-in-match-suggest-deref.rs b/tests/ui/borrowck/reborrow-in-match-suggest-deref.rs new file mode 100644 index 000000000000..34c299f4f7b1 --- /dev/null +++ b/tests/ui/borrowck/reborrow-in-match-suggest-deref.rs @@ -0,0 +1,23 @@ +// Regression test for #81059. +// edition:2024 +//@ run-rustfix + +#![allow(unused)] + +fn test(outer: &mut Option) { + //~^ NOTE: the binding is already a mutable borrow + //~| HELP: consider making the binding mutable if you need to reborrow multiple times + match (&mut outer, 23) { + //~^ ERROR: cannot borrow `outer` as mutable, as it is not declared as mutable + //~| NOTE: cannot borrow as mutable + //~| HELP: to reborrow the mutable reference, add `*` + (Some(inner), _) => { + *inner = 17; + } + _ => { + *outer = Some(2); + } + } +} + +fn main() {} diff --git a/tests/ui/borrowck/reborrow-in-match-suggest-deref.stderr b/tests/ui/borrowck/reborrow-in-match-suggest-deref.stderr new file mode 100644 index 000000000000..db3129461518 --- /dev/null +++ b/tests/ui/borrowck/reborrow-in-match-suggest-deref.stderr @@ -0,0 +1,23 @@ +error[E0596]: cannot borrow `outer` as mutable, as it is not declared as mutable + --> $DIR/reborrow-in-match-suggest-deref.rs:10:12 + | +LL | match (&mut outer, 23) { + | ^^^^^^^^^^ cannot borrow as mutable + | +note: the binding is already a mutable borrow + --> $DIR/reborrow-in-match-suggest-deref.rs:7:16 + | +LL | fn test(outer: &mut Option) { + | ^^^^^^^^^^^^^^^^ +help: consider making the binding mutable if you need to reborrow multiple times + | +LL | fn test(mut outer: &mut Option) { + | +++ +help: to reborrow the mutable reference, add `*` + | +LL | match (&mut *outer, 23) { + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/return-ref-to-temporary.rs b/tests/ui/borrowck/return-ref-to-temporary.rs new file mode 100644 index 000000000000..90609b8d6da6 --- /dev/null +++ b/tests/ui/borrowck/return-ref-to-temporary.rs @@ -0,0 +1,7 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/46472 +fn bar<'a>() -> &'a mut u32 { + &mut 4 + //~^ ERROR cannot return reference to temporary value [E0515] +} + +fn main() {} diff --git a/tests/ui/borrowck/return-ref-to-temporary.stderr b/tests/ui/borrowck/return-ref-to-temporary.stderr new file mode 100644 index 000000000000..85faf0a9e375 --- /dev/null +++ b/tests/ui/borrowck/return-ref-to-temporary.stderr @@ -0,0 +1,12 @@ +error[E0515]: cannot return reference to temporary value + --> $DIR/return-ref-to-temporary.rs:3:5 + | +LL | &mut 4 + | ^^^^^- + | | | + | | temporary value created here + | returns a reference to data owned by the current function + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/borrowck/suggest-assign-rvalue.stderr b/tests/ui/borrowck/suggest-assign-rvalue.stderr index daaef6e3892d..6ae893915aa9 100644 --- a/tests/ui/borrowck/suggest-assign-rvalue.stderr +++ b/tests/ui/borrowck/suggest-assign-rvalue.stderr @@ -19,7 +19,6 @@ LL | let my_float: f32; LL | println!("my_float: {}", my_float); | ^^^^^^^^ `my_float` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let my_float: f32 = 3.14159; @@ -33,7 +32,6 @@ LL | let demo: Demo; LL | println!("demo: {:?}", demo); | ^^^^ `demo` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let demo: Demo = Default::default(); @@ -47,7 +45,6 @@ LL | let demo_no: DemoNoDef; LL | println!("demo_no: {:?}", demo_no); | ^^^^^^^ `demo_no` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let demo_no: DemoNoDef = /* value */; @@ -61,7 +58,6 @@ LL | let arr: [i32; 5]; LL | println!("arr: {:?}", arr); | ^^^ `arr` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let arr: [i32; 5] = [42; 5]; @@ -75,7 +71,6 @@ LL | let foo: Vec<&str>; LL | println!("foo: {:?}", foo); | ^^^ `foo` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let foo: Vec<&str> = vec![]; @@ -89,7 +84,6 @@ LL | let my_string: String; LL | println!("my_string: {}", my_string); | ^^^^^^^^^ `my_string` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let my_string: String = Default::default(); @@ -103,7 +97,6 @@ LL | let my_int: &i32; LL | println!("my_int: {}", *my_int); | ^^^^^^^ `*my_int` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let my_int: &i32 = &42; @@ -117,7 +110,6 @@ LL | let hello: &str; LL | println!("hello: {}", hello); | ^^^^^ `hello` used here but it isn't initialized | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | LL | let hello: &str = ""; @@ -130,8 +122,6 @@ LL | let never: !; | ----- binding declared here but left uninitialized LL | println!("never: {}", never); | ^^^^^ `never` used here but it isn't initialized - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors diff --git a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr index 34fd29a8b50c..df1a5ce909a1 100644 --- a/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr +++ b/tests/ui/borrowck/trait-impl-argument-difference-ice.stderr @@ -5,7 +5,7 @@ LL | extern "C" fn read_dword(Self::Assoc<'_>) -> u16; | ^^^^^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: Self::Assoc<'_>` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0185]: method `read_dword` has a `&self` declaration in the impl, but not in the trait diff --git a/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs b/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs index 61446577db29..342b8cce7b01 100644 --- a/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs +++ b/tests/ui/borrowck/two-phase-reservation-sharing-interference.rs @@ -3,7 +3,7 @@ // The nll_beyond revision is disabled due to missing support from two-phase beyond autorefs //@ unused-revision-names: nll_beyond //@[nll_beyond]compile-flags: -Z two-phase-beyond-autoref -//@[nll_beyond]should-fail +//@[nll_beyond]check-fail // This is a corner case that the current implementation is (probably) // treating more conservatively than is necessary. But it also does diff --git a/tests/ui/box/box-lifetime-argument-not-allowed.rs b/tests/ui/box/box-lifetime-argument-not-allowed.rs new file mode 100644 index 000000000000..647fe0917d0a --- /dev/null +++ b/tests/ui/box/box-lifetime-argument-not-allowed.rs @@ -0,0 +1,9 @@ +//! Test that `Box` cannot be used with a lifetime argument. +//! regression test for issue + +struct Foo<'a> { + x: Box<'a, isize>, + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied +} + +fn main() {} diff --git a/tests/ui/box/box-lifetime-argument-not-allowed.stderr b/tests/ui/box/box-lifetime-argument-not-allowed.stderr new file mode 100644 index 000000000000..a597a03023af --- /dev/null +++ b/tests/ui/box/box-lifetime-argument-not-allowed.stderr @@ -0,0 +1,11 @@ +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/box-lifetime-argument-not-allowed.rs:5:8 + | +LL | x: Box<'a, isize>, + | ^^^ -- help: remove the lifetime argument + | | + | expected 0 lifetime arguments + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/box/self-assignment.rs b/tests/ui/box/self-assignment.rs new file mode 100644 index 000000000000..3689ddac5d10 --- /dev/null +++ b/tests/ui/box/self-assignment.rs @@ -0,0 +1,10 @@ +//@ run-pass +//! regression test for + +#![allow(dead_code)] + +pub fn main() { + let mut x: Box<_> = Box::new(3); + x = x; + assert_eq!(*x, 3); +} diff --git a/tests/ui/c-variadic/copy.rs b/tests/ui/c-variadic/copy.rs new file mode 100644 index 000000000000..e9171738aa15 --- /dev/null +++ b/tests/ui/c-variadic/copy.rs @@ -0,0 +1,24 @@ +//@ run-pass +//@ ignore-backends: gcc +#![feature(c_variadic)] + +// Test the behavior of `VaList::clone`. In C a `va_list` is duplicated using `va_copy`, but the +// rust api just uses `Clone`. This should create a completely independent cursor into the +// variable argument list: advancing the original has no effect on the copy and vice versa. + +fn main() { + unsafe { variadic(1, 2, 3) } +} + +unsafe extern "C" fn variadic(mut ap1: ...) { + let mut ap2 = ap1.clone(); + + assert_eq!(ap1.arg::(), 1); + assert_eq!(ap2.arg::(), 1); + + assert_eq!(ap2.arg::(), 2); + assert_eq!(ap1.arg::(), 2); + + drop(ap1); + assert_eq!(ap2.arg::(), 3); +} diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr index fc5eb10bec4f..bb8cc64e15fa 100644 --- a/tests/ui/c-variadic/not-async.stderr +++ b/tests/ui/c-variadic/not-async.stderr @@ -14,9 +14,9 @@ error[E0700]: hidden type for `impl Future` captures lifetime that --> $DIR/not-async.rs:5:65 | LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, _: ...) {} - | --------------------------------------------------------------- ^^ - | | - | opaque type defined here + | -^^ + | | + | opaque type defined here | = note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_` @@ -24,9 +24,9 @@ error[E0700]: hidden type for `impl Future` captures lifetime that --> $DIR/not-async.rs:12:73 | LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, _: ...) {} - | ------------------------------------------------------------------- ^^ - | | - | opaque type defined here + | -^^ + | | + | opaque type defined here | = note: hidden type `{async fn body of S::method_cannot_be_async()}` captures lifetime `'_` diff --git a/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr new file mode 100644 index 000000000000..584416f58f86 --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.aarch64.stderr @@ -0,0 +1,80 @@ +error: fn_abi_of(take_va_list) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(32 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + in_memory_order: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(32 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + in_memory_order: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: C, + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:27:1 + | +LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/c-variadic/pass-by-value-abi.rs b/tests/ui/c-variadic/pass-by-value-abi.rs new file mode 100644 index 000000000000..a7cf37295a74 --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.rs @@ -0,0 +1,47 @@ +//@ check-fail +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" +//@ normalize-stderr: "valid_range: 0\.\.=\d+" -> "valid_range: 0..=$$MAX" +//@ normalize-stderr: "in_memory_order: \[[^\]]+\]" -> "in_memory_order: $$MEMORY_INDEX" +//@ normalize-stderr: "offsets: \[[^\]]+\]" -> "offsets: $$OFFSETS" +//@ revisions: x86_64 aarch64 win +//@ compile-flags: -O +//@ [x86_64] only-x86_64 +//@ [x86_64] ignore-windows +//@ [x86_64] ignore-uefi +//@ [aarch64] only-aarch64 +//@ [aarch64] ignore-windows +//@ [aarch64] ignore-apple +//@ [aarch64] ignore-uefi +// Windows doesn't use `#[rustc_pass_indirectly_in_non_rustic_abis]` and is tested in CI, so is here +// for comparison. +//@ [win] only-windows +//@ [win] only-x86_64 + +#![feature(rustc_attrs, c_variadic)] +#![crate_type = "lib"] + +// Can't use `minicore` here as this is testing the implementation in `core::ffi` specifically. +use std::ffi::VaList; + +#[rustc_abi(debug)] +pub extern "C" fn take_va_list(_: VaList<'_>) {} +//~^ ERROR fn_abi_of(take_va_list) = FnAbi { +//[x86_64]~^^ ERROR mode: Indirect { +//[x86_64]~^^^ ERROR on_stack: false, +//[aarch64]~^^^^ ERROR mode: Indirect { +//[aarch64]~^^^^^ ERROR on_stack: false, +//[win]~^^^^^^ ERROR mode: Direct( + +#[cfg(all(target_arch = "x86_64", not(windows)))] +#[rustc_abi(debug)] +pub extern "sysv64" fn take_va_list_sysv64(_: VaList<'_>) {} +//[x86_64]~^ ERROR fn_abi_of(take_va_list_sysv64) = FnAbi { +//[x86_64]~^^ ERROR mode: Indirect { +//[x86_64]~^^^ ERROR on_stack: false, + +#[cfg(all(target_arch = "x86_64", not(windows)))] +#[rustc_abi(debug)] +pub extern "win64" fn take_va_list_win64(_: VaList<'_>) {} +//[x86_64]~^ ERROR: fn_abi_of(take_va_list_win64) = FnAbi { +//[x86_64]~^^ ERROR mode: Indirect { +//[x86_64]~^^^ ERROR on_stack: false, diff --git a/tests/ui/c-variadic/pass-by-value-abi.win.stderr b/tests/ui/c-variadic/pass-by-value-abi.win.stderr new file mode 100644 index 000000000000..b8e3f699b30e --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.win.stderr @@ -0,0 +1,83 @@ +error: fn_abi_of(take_va_list) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(8 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Scalar( + Initialized { + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 0..=$MAX, + }, + ), + fields: Arbitrary { + offsets: $OFFSETS, + in_memory_order: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Direct( + ArgAttributes { + regular: NoUndef, + arg_ext: None, + pointee_size: Size(0 bytes), + pointee_align: None, + }, + ), + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + in_memory_order: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: C, + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:27:1 + | +LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr new file mode 100644 index 000000000000..b5e0e8589af1 --- /dev/null +++ b/tests/ui/c-variadic/pass-by-value-abi.x86_64.stderr @@ -0,0 +1,240 @@ +error: fn_abi_of(take_va_list) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(24 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + in_memory_order: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(24 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + in_memory_order: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: C, + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:27:1 + | +LL | pub extern "C" fn take_va_list(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: fn_abi_of(take_va_list_sysv64) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(24 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + in_memory_order: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(24 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + in_memory_order: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: X86( + SysV64, + ), + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:37:1 + | +LL | pub extern "sysv64" fn take_va_list_sysv64(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: fn_abi_of(take_va_list_win64) = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: VaList<'_>, + layout: Layout { + size: Size(24 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: $OFFSETS, + in_memory_order: $MEMORY_INDEX, + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: CapturesAddress | NoAlias | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(24 bytes), + pointee_align: Some( + Align(8 bytes), + ), + }, + meta_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + in_memory_order: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: X86( + Win64, + ), + can_unwind: false, + } + --> $DIR/pass-by-value-abi.rs:44:1 + | +LL | pub extern "win64" fn take_va_list_win64(_: VaList<'_>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/c-variadic/variadic-ffi-4.rs b/tests/ui/c-variadic/variadic-ffi-4.rs index 806403794225..d9e2e617ce3a 100644 --- a/tests/ui/c-variadic/variadic-ffi-4.rs +++ b/tests/ui/c-variadic/variadic-ffi-4.rs @@ -2,37 +2,30 @@ #![no_std] #![feature(c_variadic)] -use core::ffi::{VaList, VaListImpl}; +use core::ffi::VaList; -pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { +pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaList<'f> { ap //~^ ERROR: lifetime may not live long enough - //~| ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { +pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { ap //~ ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) { - let _ = ap.with_copy(|ap| ap); //~ ERROR: lifetime may not live long enough -} - -pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { *ap0 = ap1; //~^ ERROR: lifetime may not live long enough - //~| ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { ap0 = &mut ap1; //~^ ERROR: `ap1` does not live long enough //~| ERROR: lifetime may not live long enough //~| ERROR: lifetime may not live long enough } -pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { +pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaList, mut ap1: ...) { *ap0 = ap1.clone(); //~^ ERROR: lifetime may not live long enough - //~| ERROR: lifetime may not live long enough } diff --git a/tests/ui/c-variadic/variadic-ffi-4.stderr b/tests/ui/c-variadic/variadic-ffi-4.stderr index fc9f8036083a..01ace5c79680 100644 --- a/tests/ui/c-variadic/variadic-ffi-4.stderr +++ b/tests/ui/c-variadic/variadic-ffi-4.stderr @@ -1,113 +1,64 @@ error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:8:5 | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | -- -- has type `VaListImpl<'1>` - | | - | lifetime `'f` defined here -LL | ap - | ^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'f` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:8:5 - | -LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { - | -- -- has type `VaListImpl<'1>` +LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaList<'f> { + | -- -- has type `VaList<'1>` | | | lifetime `'f` defined here LL | ap | ^^ function was supposed to return data with lifetime `'f` but it is returning data with lifetime `'1` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:14:5 + --> $DIR/variadic-ffi-4.rs:13:5 | -LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaListImpl<'static> { - | -- has type `VaListImpl<'1>` +LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> { + | -- has type `VaList<'1>` LL | ap | ^^ returning this value requires that `'1` must outlive `'static` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:18:31 + --> $DIR/variadic-ffi-4.rs:17:5 | -LL | let _ = ap.with_copy(|ap| ap); - | --- ^^ returning this value requires that `'1` must outlive `'2` - | | | - | | return type of closure is VaList<'2, '_> - | has type `VaList<'1, '_>` - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:22:5 - | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'2>` LL | *ap0 = ap1; | ^^^^ assignment requires that `'1` must outlive `'2` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance error: lifetime may not live long enough --> $DIR/variadic-ffi-4.rs:22:5 | -LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaListImpl<'1>` -LL | *ap0 = ap1; - | ^^^^ assignment requires that `'2` must outlive `'1` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance - -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:28:5 - | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` - | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'2>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2` | - = note: requirement occurs because of a mutable reference to `VaListImpl<'_>` + = note: requirement occurs because of a mutable reference to `VaList<'_>` = note: mutable references are invariant over their type parameter = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:28:5 + --> $DIR/variadic-ffi-4.rs:22:5 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'2>` LL | ap0 = &mut ap1; | ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1` | - = note: requirement occurs because of a mutable reference to `VaListImpl<'_>` + = note: requirement occurs because of a mutable reference to `VaList<'_>` = note: mutable references are invariant over their type parameter = help: see for more information about variance error[E0597]: `ap1` does not live long enough - --> $DIR/variadic-ffi-4.rs:28:11 + --> $DIR/variadic-ffi-4.rs:22:11 | -LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | - ------- binding `ap1` declared here +LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | - ------- binding `ap1` declared here | | | let's call the lifetime of this reference `'3` LL | ap0 = &mut ap1; @@ -120,33 +71,15 @@ LL | } | - `ap1` dropped here while still borrowed error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:35:5 + --> $DIR/variadic-ffi-4.rs:29:5 | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` +LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaList, mut ap1: ...) { + | ------- ------- has type `VaList<'1>` | | - | has type `&mut VaListImpl<'1>` + | has type `&mut VaList<'2>` LL | *ap0 = ap1.clone(); - | ^^^^ assignment requires that `'2` must outlive `'1` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance + | ^^^^ assignment requires that `'1` must outlive `'2` -error: lifetime may not live long enough - --> $DIR/variadic-ffi-4.rs:35:12 - | -LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) { - | ------- ------- has type `VaListImpl<'2>` - | | - | has type `&mut VaListImpl<'1>` -LL | *ap0 = ap1.clone(); - | ^^^^^^^^^^^ argument requires that `'1` must outlive `'2` - | - = note: requirement occurs because of the type `VaListImpl<'_>`, which makes the generic argument `'_` invariant - = note: the struct `VaListImpl<'f>` is invariant over the parameter `'f` - = help: see for more information about variance - -error: aborting due to 11 previous errors +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/cast/cast-enum-const.rs b/tests/ui/cast/cast-enum-const.rs new file mode 100644 index 000000000000..cfad40c07b0e --- /dev/null +++ b/tests/ui/cast/cast-enum-const.rs @@ -0,0 +1,12 @@ +//! regression test for +//@ run-pass + +fn main() { + const QUUX: isize = 5; + + enum Stuff { + Bar = QUUX, + } + + assert_eq!(Stuff::Bar as isize, QUUX); +} diff --git a/tests/ui/cast/cast-rfc0401-2.rs b/tests/ui/cast/cast-rfc0401-2.rs deleted file mode 100644 index 70604a587ea1..000000000000 --- a/tests/ui/cast/cast-rfc0401-2.rs +++ /dev/null @@ -1,8 +0,0 @@ -// RFC 401 test extracted into distinct file. This is because some the -// change to suppress "derived" errors wound up suppressing this error -// message, since the fallback for `3` doesn't occur. - -fn main() { - let _ = 3 as bool; - //~^ ERROR cannot cast `i32` as `bool` -} diff --git a/tests/ui/cast/cast-rfc0401-2.stderr b/tests/ui/cast/cast-rfc0401-2.stderr deleted file mode 100644 index f2956cdfa335..000000000000 --- a/tests/ui/cast/cast-rfc0401-2.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0054]: cannot cast `i32` as `bool` - --> $DIR/cast-rfc0401-2.rs:6:13 - | -LL | let _ = 3 as bool; - | ^^^^^^^^^ - | -help: compare with zero instead - | -LL - let _ = 3 as bool; -LL + let _ = 3 != 0; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0054`. diff --git a/tests/ui/cast/cast-rfc0401-fail.rs b/tests/ui/cast/cast-rfc0401-fail.rs new file mode 100644 index 000000000000..fb04e3f5f9a0 --- /dev/null +++ b/tests/ui/cast/cast-rfc0401-fail.rs @@ -0,0 +1,77 @@ +fn illegal_cast(u: *const U) -> *const V { + u as *const V //~ ERROR is invalid +} + +fn illegal_cast_2(u: *const U) -> *const str { + u as *const str //~ ERROR is invalid +} + +trait Foo { + fn foo(&self) {} +} +impl Foo for T {} + +trait Bar { + fn foo(&self) {} +} +impl Bar for T {} + +enum E { + A, + B, +} + +struct Inches(i32); + +fn main() { + let f: f32 = 1.2; + let v = core::ptr::null::(); + let fat_v: *const [u8] = unsafe { &*core::ptr::null::<[u8; 1]>() }; + let fat_sv: *const [i8] = unsafe { &*core::ptr::null::<[i8; 1]>() }; + let foo: &dyn Foo = &f; + + let _ = v as &u8; //~ ERROR non-primitive cast + let _ = v as E; //~ ERROR non-primitive cast + let _ = v as fn(); //~ ERROR non-primitive cast + let _ = v as (u32,); //~ ERROR non-primitive cast + let _ = Some(&v) as *const u8; //~ ERROR non-primitive cast + + let _ = v as f32; //~ ERROR is invalid + let _ = main as f64; //~ ERROR is invalid + let _ = &v as usize; //~ ERROR is invalid + let _ = f as *const u8; //~ ERROR is invalid + let _ = 3_i32 as bool; //~ ERROR cannot cast + let _ = E::A as bool; //~ ERROR cannot cast + let _ = 0x61u32 as char; //~ ERROR can be cast as + let _ = Inches as f32; //~ ERROR is invalid + + let _ = false as f32; //~ ERROR is invalid + let _ = E::A as f32; //~ ERROR is invalid + let _ = 'a' as f32; //~ ERROR is invalid + + let _ = false as *const u8; //~ ERROR is invalid + let _ = E::A as *const u8; //~ ERROR is invalid + let _ = 'a' as *const u8; //~ ERROR is invalid + + let _ = 42usize as *const [u8]; //~ ERROR cannot cast `usize` to a pointer that is wide + let _ = v as *const [u8]; //~ ERROR cannot cast + let _ = fat_v as *const dyn Foo; //~ ERROR the size for values of type + let _ = foo as *const str; //~ ERROR is invalid + let _ = foo as *mut str; //~ ERROR is invalid + let _ = main as *mut str; //~ ERROR is invalid + let _ = &f as *mut f32; //~ ERROR is invalid + let _ = &f as *const f64; //~ ERROR is invalid + let _ = fat_sv as usize; //~ ERROR is invalid + + let a: *const str = "hello"; + let _ = a as *const dyn Foo; //~ ERROR the size for values of type + + // check no error cascade + let _ = main.f as *const u32; //~ ERROR no field + + let cf: *const dyn Foo = &0; + let _ = cf as *const [u16]; //~ ERROR is invalid + let _ = cf as *const dyn Bar; //~ ERROR casting `*const dyn Foo` as `*const dyn Bar` is invalid + + vec![0.0].iter().map(|s| s as f32).collect::>(); //~ ERROR is invalid +} diff --git a/tests/ui/cast/cast-rfc0401-fail.stderr b/tests/ui/cast/cast-rfc0401-fail.stderr new file mode 100644 index 000000000000..c41e6e3612dd --- /dev/null +++ b/tests/ui/cast/cast-rfc0401-fail.stderr @@ -0,0 +1,263 @@ +error[E0606]: casting `*const U` as `*const V` is invalid + --> $DIR/cast-rfc0401-fail.rs:2:5 + | +LL | u as *const V + | ^^^^^^^^^^^^^ + | + = note: the pointers may have different metadata + +error[E0606]: casting `*const U` as `*const str` is invalid + --> $DIR/cast-rfc0401-fail.rs:6:5 + | +LL | u as *const str + | ^^^^^^^^^^^^^^^ + | + = note: the pointers may have different metadata + +error[E0609]: no field `f` on type `fn() {main}` + --> $DIR/cast-rfc0401-fail.rs:70:18 + | +LL | let _ = main.f as *const u32; + | ^ unknown field + +error[E0605]: non-primitive cast: `*const u8` as `&u8` + --> $DIR/cast-rfc0401-fail.rs:33:13 + | +LL | let _ = v as &u8; + | ^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL - let _ = v as &u8; +LL + let _ = &*v; + | + +error[E0605]: non-primitive cast: `*const u8` as `E` + --> $DIR/cast-rfc0401-fail.rs:34:13 + | +LL | let _ = v as E; + | ^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error[E0605]: non-primitive cast: `*const u8` as `fn()` + --> $DIR/cast-rfc0401-fail.rs:35:13 + | +LL | let _ = v as fn(); + | ^^^^^^^^^ invalid cast + +error[E0605]: non-primitive cast: `*const u8` as `(u32,)` + --> $DIR/cast-rfc0401-fail.rs:36:13 + | +LL | let _ = v as (u32,); + | ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error[E0605]: non-primitive cast: `Option<&*const u8>` as `*const u8` + --> $DIR/cast-rfc0401-fail.rs:37:13 + | +LL | let _ = Some(&v) as *const u8; + | ^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object + +error[E0606]: casting `*const u8` as `f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:39:13 + | +LL | let _ = v as f32; + | ^^^^^^^^ + +error[E0606]: casting `fn() {main}` as `f64` is invalid + --> $DIR/cast-rfc0401-fail.rs:40:13 + | +LL | let _ = main as f64; + | ^^^^^^^^^^^ + +error[E0606]: casting `&*const u8` as `usize` is invalid + --> $DIR/cast-rfc0401-fail.rs:41:13 + | +LL | let _ = &v as usize; + | ^^^^^^^^^^^ + | + = help: cast through a raw pointer first + +error[E0606]: casting `f32` as `*const u8` is invalid + --> $DIR/cast-rfc0401-fail.rs:42:13 + | +LL | let _ = f as *const u8; + | ^^^^^^^^^^^^^^ + +error[E0054]: cannot cast `i32` as `bool` + --> $DIR/cast-rfc0401-fail.rs:43:13 + | +LL | let _ = 3_i32 as bool; + | ^^^^^^^^^^^^^ + | +help: compare with zero instead + | +LL - let _ = 3_i32 as bool; +LL + let _ = 3_i32 != 0; + | + +error[E0054]: cannot cast `E` as `bool` + --> $DIR/cast-rfc0401-fail.rs:44:13 + | +LL | let _ = E::A as bool; + | ^^^^^^^^^^^^ unsupported cast + +error[E0604]: only `u8` can be cast as `char`, not `u32` + --> $DIR/cast-rfc0401-fail.rs:45:13 + | +LL | let _ = 0x61u32 as char; + | ^^^^^^^^^^^^^^^ invalid cast + | +help: consider using `char::from_u32` instead + | +LL - let _ = 0x61u32 as char; +LL + let _ = char::from_u32(0x61u32); + | + +error[E0606]: casting `fn(i32) -> Inches {Inches}` as `f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:46:13 + | +LL | let _ = Inches as f32; + | ^^^^^^^^^^^^^ + +error[E0606]: casting `bool` as `f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:48:13 + | +LL | let _ = false as f32; + | ^^^^^^^^^^^^ + | + = help: cast through an integer first + +error[E0606]: casting `E` as `f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:49:13 + | +LL | let _ = E::A as f32; + | ^^^^^^^^^^^ + | + = help: cast through an integer first + +error[E0606]: casting `char` as `f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:50:13 + | +LL | let _ = 'a' as f32; + | ^^^^^^^^^^ + | + = help: cast through an integer first + +error[E0606]: casting `bool` as `*const u8` is invalid + --> $DIR/cast-rfc0401-fail.rs:52:13 + | +LL | let _ = false as *const u8; + | ^^^^^^^^^^^^^^^^^^ + +error[E0606]: casting `E` as `*const u8` is invalid + --> $DIR/cast-rfc0401-fail.rs:53:13 + | +LL | let _ = E::A as *const u8; + | ^^^^^^^^^^^^^^^^^ + +error[E0606]: casting `char` as `*const u8` is invalid + --> $DIR/cast-rfc0401-fail.rs:54:13 + | +LL | let _ = 'a' as *const u8; + | ^^^^^^^^^^^^^^^^ + +error[E0606]: cannot cast `usize` to a pointer that is wide + --> $DIR/cast-rfc0401-fail.rs:56:24 + | +LL | let _ = 42usize as *const [u8]; + | ------- ^^^^^^^^^^^ creating a `*const [u8]` requires both an address and a length + | | + | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` + +error[E0607]: cannot cast thin pointer `*const u8` to wide pointer `*const [u8]` + --> $DIR/cast-rfc0401-fail.rs:57:13 + | +LL | let _ = v as *const [u8]; + | ^^^^^^^^^^^^^^^^ + +error[E0606]: casting `&dyn Foo` as `*const str` is invalid + --> $DIR/cast-rfc0401-fail.rs:59:13 + | +LL | let _ = foo as *const str; + | ^^^^^^^^^^^^^^^^^ + +error[E0606]: casting `&dyn Foo` as `*mut str` is invalid + --> $DIR/cast-rfc0401-fail.rs:60:13 + | +LL | let _ = foo as *mut str; + | ^^^^^^^^^^^^^^^ + +error[E0606]: casting `fn() {main}` as `*mut str` is invalid + --> $DIR/cast-rfc0401-fail.rs:61:13 + | +LL | let _ = main as *mut str; + | ^^^^^^^^^^^^^^^^ + +error[E0606]: casting `&f32` as `*mut f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:62:13 + | +LL | let _ = &f as *mut f32; + | ^^^^^^^^^^^^^^ + +error[E0606]: casting `&f32` as `*const f64` is invalid + --> $DIR/cast-rfc0401-fail.rs:63:13 + | +LL | let _ = &f as *const f64; + | ^^^^^^^^^^^^^^^^ + +error[E0606]: casting `*const [i8]` as `usize` is invalid + --> $DIR/cast-rfc0401-fail.rs:64:13 + | +LL | let _ = fat_sv as usize; + | ^^^^^^^^^^^^^^^ + | + = help: cast through a thin pointer first + +error[E0606]: casting `*const dyn Foo` as `*const [u16]` is invalid + --> $DIR/cast-rfc0401-fail.rs:73:13 + | +LL | let _ = cf as *const [u16]; + | ^^^^^^^^^^^^^^^^^^ + | + = note: the pointers have different metadata + +error[E0606]: casting `*const dyn Foo` as `*const dyn Bar` is invalid + --> $DIR/cast-rfc0401-fail.rs:74:13 + | +LL | let _ = cf as *const dyn Bar; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: the trait objects may have different vtables + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/cast-rfc0401-fail.rs:58:13 + | +LL | let _ = fat_v as *const dyn Foo; + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: required for the cast from `*const [u8]` to `*const dyn Foo` + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/cast-rfc0401-fail.rs:67:13 + | +LL | let _ = a as *const dyn Foo; + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: required for the cast from `*const str` to `*const dyn Foo` + +error[E0606]: casting `&{float}` as `f32` is invalid + --> $DIR/cast-rfc0401-fail.rs:76:30 + | +LL | vec![0.0].iter().map(|s| s as f32).collect::>(); + | ^^^^^^^^ + | +help: dereference the expression + | +LL | vec![0.0].iter().map(|s| *s as f32).collect::>(); + | + + +error: aborting due to 35 previous errors + +Some errors have detailed explanations: E0054, E0277, E0604, E0605, E0606, E0607, E0609. +For more information about an error, try `rustc --explain E0054`. diff --git a/tests/ui/cast/cast-to-box-arr.rs b/tests/ui/cast/cast-to-box-arr.rs new file mode 100644 index 000000000000..1a9004cd074e --- /dev/null +++ b/tests/ui/cast/cast-to-box-arr.rs @@ -0,0 +1,7 @@ +//! regression test for +//@ run-pass +fn main() { + let x = Box::new([1, 2, 3]); + let y = x as Box<[i32]>; + println!("y: {:?}", y); +} diff --git a/tests/ui/cast/cast-to-char-compare.rs b/tests/ui/cast/cast-to-char-compare.rs new file mode 100644 index 000000000000..159b8ee04e02 --- /dev/null +++ b/tests/ui/cast/cast-to-char-compare.rs @@ -0,0 +1,10 @@ +//! regression test for +//@ check-pass + +fn main() { + if ('x' as char) < ('y' as char) { + print!("x"); + } else { + print!("y"); + } +} diff --git a/tests/ui/cast/cast-to-dyn-any.rs b/tests/ui/cast/cast-to-dyn-any.rs new file mode 100644 index 000000000000..3180c530209e --- /dev/null +++ b/tests/ui/cast/cast-to-dyn-any.rs @@ -0,0 +1,4 @@ +//! regression test for issue +fn main() { + 0 as &dyn std::any::Any; //~ ERROR non-primitive cast +} diff --git a/tests/ui/cast/cast-to-dyn-any.stderr b/tests/ui/cast/cast-to-dyn-any.stderr new file mode 100644 index 000000000000..6ee1098fcf40 --- /dev/null +++ b/tests/ui/cast/cast-to-dyn-any.stderr @@ -0,0 +1,14 @@ +error[E0605]: non-primitive cast: `i32` as `&(dyn Any + 'static)` + --> $DIR/cast-to-dyn-any.rs:3:5 + | +LL | 0 as &dyn std::any::Any; + | ^^^^^^^^^^^^^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL | &0 as &dyn std::any::Any; + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/cast/cast-to-unsized-type.rs b/tests/ui/cast/cast-to-unsized-type.rs new file mode 100644 index 000000000000..4c7ca49fd98d --- /dev/null +++ b/tests/ui/cast/cast-to-unsized-type.rs @@ -0,0 +1,15 @@ +//! regression test for + +fn main() { + let _foo = &[1_usize, 2] as [usize]; + //~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]` + + let _bar = Box::new(1_usize) as dyn std::fmt::Debug; + //~^ ERROR cast to unsized type: `Box` as `dyn Debug` + + let _baz = 1_usize as dyn std::fmt::Debug; + //~^ ERROR cast to unsized type: `usize` as `dyn Debug` + + let _quux = [1_usize, 2] as [usize]; + //~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]` +} diff --git a/tests/ui/cast/cast-to-unsized-type.stderr b/tests/ui/cast/cast-to-unsized-type.stderr new file mode 100644 index 000000000000..087cfac77484 --- /dev/null +++ b/tests/ui/cast/cast-to-unsized-type.stderr @@ -0,0 +1,49 @@ +error[E0620]: cast to unsized type: `&[usize; 2]` as `[usize]` + --> $DIR/cast-to-unsized-type.rs:4:16 + | +LL | let _foo = &[1_usize, 2] as [usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider casting to a reference instead + | +LL | let _foo = &[1_usize, 2] as &[usize]; + | + + +error[E0620]: cast to unsized type: `Box` as `dyn Debug` + --> $DIR/cast-to-unsized-type.rs:7:16 + | +LL | let _bar = Box::new(1_usize) as dyn std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: you can cast to a `Box` instead + | +LL | let _bar = Box::new(1_usize) as Box; + | ++++ + + +error[E0620]: cast to unsized type: `usize` as `dyn Debug` + --> $DIR/cast-to-unsized-type.rs:10:16 + | +LL | let _baz = 1_usize as dyn std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a box or reference as appropriate + --> $DIR/cast-to-unsized-type.rs:10:16 + | +LL | let _baz = 1_usize as dyn std::fmt::Debug; + | ^^^^^^^ + +error[E0620]: cast to unsized type: `[usize; 2]` as `[usize]` + --> $DIR/cast-to-unsized-type.rs:13:17 + | +LL | let _quux = [1_usize, 2] as [usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider using a box or reference as appropriate + --> $DIR/cast-to-unsized-type.rs:13:17 + | +LL | let _quux = [1_usize, 2] as [usize]; + | ^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0620`. diff --git a/tests/ui/cast/fat-ptr-cast.stderr b/tests/ui/cast/fat-ptr-cast.stderr index 2b0bceebf15c..c6354122f568 100644 --- a/tests/ui/cast/fat-ptr-cast.stderr +++ b/tests/ui/cast/fat-ptr-cast.stderr @@ -81,6 +81,8 @@ LL | let s = 0 as *const T; | - ^^^^^^^^ creating a `*const T` requires both an address and type-specific metadata | | | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` + | + = note: the type parameter `T` is not known to be `Sized`, so this pointer may be wide error: aborting due to 11 previous errors diff --git a/tests/ui/cast/generic-trait-object-call.rs b/tests/ui/cast/generic-trait-object-call.rs new file mode 100644 index 000000000000..a6703dfd8aa6 --- /dev/null +++ b/tests/ui/cast/generic-trait-object-call.rs @@ -0,0 +1,31 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2288 + +//@ run-pass +#![allow(non_camel_case_types)] + +trait clam { + fn chowder(&self, y: A); +} + +#[derive(Copy, Clone)] +struct foo { + x: A, +} + +impl clam for foo { + fn chowder(&self, _y: A) {} +} + +fn foo(b: A) -> foo { + foo { x: b } +} + +fn f(x: Box>, a: A) { + x.chowder(a); +} + +pub fn main() { + let c = foo(42); + let d: Box> = Box::new(c) as Box>; + f(d, c.x); +} diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.rs b/tests/ui/cast/ice-cast-type-with-error-124848.rs index 9b3732b02db4..0c623de8050b 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.rs +++ b/tests/ui/cast/ice-cast-type-with-error-124848.rs @@ -14,5 +14,4 @@ fn main() { let bad_addr = &unpinned as *const Cell>> as usize; //~^ ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` - //~| ERROR casting `&MyType<'_>` as `*const Cell>>` is invalid } diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr index dff227727324..665b0e0a0dd4 100644 --- a/tests/ui/cast/ice-cast-type-with-error-124848.stderr +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -58,13 +58,7 @@ help: provide the argument LL | let mut unpinned = MyType(Cell::new(None), /* value */); | +++++++++++++ -error[E0606]: casting `&MyType<'_>` as `*const Cell>>` is invalid - --> $DIR/ice-cast-type-with-error-124848.rs:14:20 - | -LL | let bad_addr = &unpinned as *const Cell>> as usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: aborting due to 5 previous errors -error: aborting due to 6 previous errors - -Some errors have detailed explanations: E0061, E0261, E0425, E0606. +Some errors have detailed explanations: E0061, E0261, E0425. For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/cast/non-primitive-isize-ref-cast.rs b/tests/ui/cast/non-primitive-isize-ref-cast.rs new file mode 100644 index 000000000000..95259456eede --- /dev/null +++ b/tests/ui/cast/non-primitive-isize-ref-cast.rs @@ -0,0 +1,7 @@ +//! regression test for + +fn bad (p: *const isize) { + let _q: &isize = p as &isize; //~ ERROR non-primitive cast +} + +fn main() { } diff --git a/tests/ui/cast/non-primitive-isize-ref-cast.stderr b/tests/ui/cast/non-primitive-isize-ref-cast.stderr new file mode 100644 index 000000000000..3f4c171d3dc7 --- /dev/null +++ b/tests/ui/cast/non-primitive-isize-ref-cast.stderr @@ -0,0 +1,15 @@ +error[E0605]: non-primitive cast: `*const isize` as `&isize` + --> $DIR/non-primitive-isize-ref-cast.rs:4:22 + | +LL | let _q: &isize = p as &isize; + | ^^^^^^^^^^^ invalid cast + | +help: consider borrowing the value + | +LL - let _q: &isize = p as &isize; +LL + let _q: &isize = &*p; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0605`. diff --git a/tests/ui/cast/ptr-ptr-to-ptr-ptr-different-regions.rs b/tests/ui/cast/ptr-ptr-to-ptr-ptr-different-regions.rs new file mode 100644 index 000000000000..bb4aeadbb433 --- /dev/null +++ b/tests/ui/cast/ptr-ptr-to-ptr-ptr-different-regions.rs @@ -0,0 +1,15 @@ +//@ check-pass + +// We allow extending lifetimes of object types if they are behind two layers +// of pointer indirection (as opposed to one). This is because this is the more +// general case of casting between two sized types (`*mut T as *mut U`). + +trait Trait { + fn foo(&self) {} +} + +fn bar<'a>(a: *mut *mut (dyn Trait + 'a)) -> *mut *mut (dyn Trait + 'static) { + a as _ +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-ptr-different-regions.rs b/tests/ui/cast/ptr-to-ptr-different-regions.rs index 0d525edc1332..f0021628be01 100644 --- a/tests/ui/cast/ptr-to-ptr-different-regions.rs +++ b/tests/ui/cast/ptr-to-ptr-different-regions.rs @@ -1,20 +1,24 @@ -//@ check-pass - // https://github.com/rust-lang/rust/issues/113257 #![deny(trivial_casts)] // The casts here are not trivial. -struct Foo<'a> { a: &'a () } +struct Foo<'a> { + a: &'a (), +} fn extend_lifetime_very_very_safely<'a>(v: *const Foo<'a>) -> *const Foo<'static> { - // This should pass because raw pointer casts can do anything they want. + // This should pass because raw pointer casts can do anything they want when + // VTables are not involved v as *const Foo<'static> } trait Trait {} +// We want to forbid this as extending lifetimes on object types may allow for +// uncallable VTable methods to become accessible. fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { ptr as _ + //~^ ERROR: lifetime may not live long enough } fn main() { diff --git a/tests/ui/cast/ptr-to-ptr-different-regions.stderr b/tests/ui/cast/ptr-to-ptr-different-regions.stderr new file mode 100644 index 000000000000..c5910be2396b --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-different-regions.stderr @@ -0,0 +1,31 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-different-regions.rs:20:5 + | +LL | fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { + | -- lifetime `'a` defined here +LL | ptr as _ + | ^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Trait` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-different-regions.rs:20:5 + | +LL | ptr as _ + | ^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `ptr` + | +LL - fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { +LL + fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) { +LL + fn assert_static<'a>(ptr: *mut (dyn Trait + 'static)) -> *mut (dyn Trait + 'static) { + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-ptr-indirect-different-regions.rs b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.rs new file mode 100644 index 000000000000..50f11c568ad2 --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.rs @@ -0,0 +1,15 @@ +// We want to forbid extending lifetimes on object types behind ptrs +// as it may allow for uncallable VTable methods to become accessible. + +trait Trait { + fn foo(&self) {} +} + +struct MyWrap(T); + +fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { + a as _ + //~^ ERROR: lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-ptr-indirect-different-regions.stderr b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.stderr new file mode 100644 index 000000000000..43609fa570cb --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-indirect-different-regions.stderr @@ -0,0 +1,31 @@ +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-indirect-different-regions.rs:11:5 + | +LL | fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { + | -- lifetime `'a` defined here +LL | a as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `MyWrap` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-indirect-different-regions.rs:11:5 + | +LL | a as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `a` + | +LL - fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { +LL + fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'a)> { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'a)>) -> *mut MyWrap<(dyn Trait + 'static)> { +LL + fn bar<'a>(a: *mut MyWrap<(dyn Trait + 'static)>) -> *mut MyWrap<(dyn Trait + 'static)> { + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/cast/ptr-to-ptr-principalless.rs b/tests/ui/cast/ptr-to-ptr-principalless.rs new file mode 100644 index 000000000000..0b1032d2669d --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-principalless.rs @@ -0,0 +1,74 @@ +// Test cases involving principal-less traits (dyn Send without a primary trait). + +struct Wrapper(T); + +// Cast to same auto trait + +fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'b) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +// Cast to different auto trait + +fn unprincipled2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +// Cast away principal trait +trait Trait {} + +fn unprincipled3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'b) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { + x as _ + //~^ ERROR: lifetime may not live long enough +} + +fn unprincipled_wrap3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut Wrapper { + x as _ + //~^ ERROR: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'b)>` is invalid +} + +fn unprincipled_wrap3_static<'a>( + x: *mut (dyn Trait + Send + 'a) +) -> *mut Wrapper { + x as _ + //~^ ERROR: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'static)>` is invalid +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-ptr-principalless.stderr b/tests/ui/cast/ptr-to-ptr-principalless.stderr new file mode 100644 index 000000000000..78f949232a1c --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-principalless.stderr @@ -0,0 +1,274 @@ +error[E0606]: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'b)>` is invalid + --> $DIR/ptr-to-ptr-principalless.rs:63:5 + | +LL | x as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error[E0606]: casting `*mut (dyn Trait + Send + 'a)` as `*mut Wrapper<(dyn Send + 'static)>` is invalid + --> $DIR/ptr-to-ptr-principalless.rs:70:5 + | +LL | x as _ + | ^^^^^^ + | + = note: the trait objects may have different vtables + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:8:5 + | +LL | fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'b) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:8:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:13:5 + | +LL | fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:13:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled_static<'a>(x: *mut (dyn Send + 'static)) -> *mut (dyn Send + 'static) { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:18:5 + | +LL | fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:18:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:23:5 + | +LL | fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:23:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap_static<'a>(x: *mut (dyn Send + 'static)) -> *mut Wrapper { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:30:5 + | +LL | fn unprincipled2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Sync` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:30:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:35:5 + | +LL | fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Sync` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:35:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { +LL + fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'static) { +LL + fn unprincipled2_static<'a>(x: *mut (dyn Send + 'static)) -> *mut (dyn Sync + 'static) { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:40:5 + | +LL | fn unprincipled_wrap2<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:40:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:45:5 + | +LL | fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `Wrapper` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:45:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +LL + fn unprincipled_wrap2_static<'a>(x: *mut (dyn Send + 'static)) -> *mut Wrapper { + | + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:53:5 + | +LL | fn unprincipled3<'a, 'b>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'b) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +LL | x as _ + | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:53:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information + +error: lifetime may not live long enough + --> $DIR/ptr-to-ptr-principalless.rs:58:5 + | +LL | fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `dyn Send` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-ptr-principalless.rs:58:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL - fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'a) { + | +help: alternatively, add an explicit `'static` bound to this reference + | +LL - fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'a)) -> *mut (dyn Send + 'static) { +LL + fn unprincipled3_static<'a>(x: *mut (dyn Trait + Send + 'static)) -> *mut (dyn Send + 'static) { + | + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0606`. diff --git a/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs b/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs new file mode 100644 index 000000000000..7319a670c881 --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs @@ -0,0 +1,15 @@ +//@ check-pass + +// During MIR typeck when casting `*mut dyn Sync + '?x` to +// `*mut Wrap` we compute the tail of `Wrap` as `dyn Sync + 'static`. +// +// This test ensures that we first convert the `'static` lifetime to +// the nll var `'?0` before introducing the region constraint `'?x: 'static`. + +struct Wrap(dyn Sync + 'static); + +fn cast(x: *mut (dyn Sync + 'static)) { + x as *mut Wrap; +} + +fn main() {} diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr index 4e43d3b93fa3..af7744192223 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.current.stderr @@ -7,9 +7,13 @@ LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` | - = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant - = note: the struct `S` is invariant over the parameter `T` - = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + | +LL | let _send = unsend as *const S>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr index 4e43d3b93fa3..af7744192223 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-id-trait.next.stderr @@ -7,9 +7,13 @@ LL | let unsend: *const dyn Cat<'a> = &(); LL | let _send = unsend as *const S>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static` | - = note: requirement occurs because of the type `S>`, which makes the generic argument `dyn Cat<'_>` invariant - = note: the struct `S` is invariant over the parameter `T` - = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-id-trait.rs:24:17 + | +LL | let _send = unsend as *const S>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr index b7319e3356bd..4b5927f094bc 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-lt-ext.stderr @@ -5,6 +5,14 @@ LL | fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> { | -- lifetime `'a` defined here LL | x as _ | ^^^^^^ returning this value requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-lt-ext.rs:12:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 1 previous error diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index 88a89dc4ac1b..f2c060e4b279 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -12,6 +12,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 @@ -27,6 +34,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:7:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other @@ -44,6 +58,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:12:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:16:5 @@ -59,6 +80,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Trait<'_>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:16:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:20:5 @@ -97,6 +125,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 @@ -113,6 +148,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other | @@ -133,6 +175,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: lifetime may not live long enough --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 @@ -149,6 +198,13 @@ LL | x as _ = note: requirement occurs because of a mutable pointer to `dyn Assocked>` = note: mutable pointers are invariant over their type parameter = help: see for more information about variance +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:5 + | +LL | x as _ + | ^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information help: `'b` and `'a` must be the same: replace one with the other | @@ -168,6 +224,14 @@ LL | require_static(ptr as _) | | | `ptr` escapes the function body here | argument requires that `'a` must outlive `'static` + | +note: raw pointer casts of trait objects cannot extend lifetimes + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:46:20 + | +LL | require_static(ptr as _) + | ^^^^^^^^ + = note: this was previously accepted by the compiler but was changed recently + = help: see for more information error: aborting due to 11 previous errors diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs index dbeee9d29441..e6b3b23e2da2 100644 --- a/tests/ui/cast/ptr-to-trait-obj-ok.rs +++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs @@ -1,12 +1,23 @@ //@ check-pass +// Casting pointers to object types has some special rules in order to +// ensure VTables stay valid. E.g. +// - Cannot introduce new autotraits +// - Cannot extend or shrink lifetimes in trait arguments +// - Cannot extend the lifetime of the object type +// +// This test is a mostly miscellaneous set of examples of casts that do +// uphold these rules + trait Trait<'a> {} fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> { x as _ } -fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) { +fn cast_inherent_lt<'a: 'b, 'b>( + x: *mut (dyn Trait<'static> + 'a) +) -> *mut (dyn Trait<'static> + 'b) { x as _ } @@ -14,7 +25,11 @@ fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait< x as _ } -fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { +fn unprincipled<'a: 'b, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { + x as _ +} + +fn remove_principal<'a: 'b, 'b, 't>(x: *mut (dyn Trait<'t> + Send + 'a)) -> *mut (dyn Send + 'b) { x as _ } @@ -29,7 +44,7 @@ fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper( +fn cast_inherent_lt_wrap<'a: 'b, 'b>( x: *mut (dyn Trait<'static> + 'a), ) -> *mut Wrapper + 'b> { x as _ @@ -39,7 +54,7 @@ fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapp x as _ } -fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { +fn unprincipled_wrap<'a: 'b, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { x as _ } diff --git a/tests/ui/cfg/conditional-compilation-struct-11085.rs b/tests/ui/cfg/conditional-compilation-struct-11085.rs index cd6dded54d30..8fdc88be37d2 100644 --- a/tests/ui/cfg/conditional-compilation-struct-11085.rs +++ b/tests/ui/cfg/conditional-compilation-struct-11085.rs @@ -11,7 +11,7 @@ struct Foo { } struct Foo2 { - #[cfg(all())] + #[cfg(true)] foo: isize, } diff --git a/tests/ui/cfg/conditional-compile.rs b/tests/ui/cfg/conditional-compile.rs index 0739e877bfd1..8761197891f5 100644 --- a/tests/ui/cfg/conditional-compile.rs +++ b/tests/ui/cfg/conditional-compile.rs @@ -151,5 +151,5 @@ mod test_methods { } } -#[cfg(any())] +#[cfg(false)] mod nonexistent_file; // Check that unconfigured non-inline modules are not loaded or parsed. diff --git a/tests/ui/cfg/crt-static-off-works.rs b/tests/ui/cfg/crt-static-off-works.rs index 1d77dba24b1c..520d139915cc 100644 --- a/tests/ui/cfg/crt-static-off-works.rs +++ b/tests/ui/cfg/crt-static-off-works.rs @@ -1,10 +1,6 @@ //@ run-pass - -#![allow(stable_features)] //@ compile-flags:-C target-feature=-crt-static -Z unstable-options //@ ignore-musl - requires changing the linker which is hard -#![feature(cfg_target_feature)] - #[cfg(not(target_feature = "crt-static"))] fn main() {} diff --git a/tests/ui/cfg/diagnostics-cross-crate.rs b/tests/ui/cfg/diagnostics-cross-crate.rs index f959332c817f..c5d8dcdc62f0 100644 --- a/tests/ui/cfg/diagnostics-cross-crate.rs +++ b/tests/ui/cfg/diagnostics-cross-crate.rs @@ -14,7 +14,7 @@ fn main() { // The module isn't found - we would like to get a diagnostic, but currently don't due to // the awkward way the resolver diagnostics are currently implemented. - cfged_out::inner::doesnt_exist::hello(); //~ ERROR failed to resolve + cfged_out::inner::doesnt_exist::hello(); //~ ERROR cannot find //~^ NOTE could not find `doesnt_exist` in `inner` //~| NOTE found an item that was configured out diff --git a/tests/ui/cfg/diagnostics-cross-crate.stderr b/tests/ui/cfg/diagnostics-cross-crate.stderr index 658e5a442bda..15e60cc43a3c 100644 --- a/tests/ui/cfg/diagnostics-cross-crate.stderr +++ b/tests/ui/cfg/diagnostics-cross-crate.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner` +error[E0433]: cannot find `doesnt_exist` in `inner` --> $DIR/diagnostics-cross-crate.rs:17:23 | LL | cfged_out::inner::doesnt_exist::hello(); diff --git a/tests/ui/cfg/diagnostics-reexport-2.rs b/tests/ui/cfg/diagnostics-reexport-2.rs index f66b9ed99ee6..bef832517061 100644 --- a/tests/ui/cfg/diagnostics-reexport-2.rs +++ b/tests/ui/cfg/diagnostics-reexport-2.rs @@ -40,22 +40,22 @@ mod reexport32 { fn main() { reexport::gated::foo(); - //~^ ERROR failed to resolve: could not find `gated` in `reexport` + //~^ ERROR cannot find //~| NOTE could not find `gated` in `reexport` reexport2::gated::foo(); - //~^ ERROR failed to resolve: could not find `gated` in `reexport2` + //~^ ERROR cannot find //~| NOTE could not find `gated` in `reexport2` reexport30::gated::foo(); - //~^ ERROR failed to resolve: could not find `gated` in `reexport30` + //~^ ERROR cannot find //~| NOTE could not find `gated` in `reexport30` reexport31::gated::foo(); - //~^ ERROR failed to resolve: could not find `gated` in `reexport31` + //~^ ERROR cannot find //~| NOTE could not find `gated` in `reexport31` reexport32::gated::foo(); - //~^ ERROR failed to resolve: could not find `gated` in `reexport32` + //~^ ERROR cannot find //~| NOTE could not find `gated` in `reexport32` } diff --git a/tests/ui/cfg/diagnostics-reexport-2.stderr b/tests/ui/cfg/diagnostics-reexport-2.stderr index 713cffce65b6..a79c623856ff 100644 --- a/tests/ui/cfg/diagnostics-reexport-2.stderr +++ b/tests/ui/cfg/diagnostics-reexport-2.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: could not find `gated` in `reexport` +error[E0433]: cannot find `gated` in `reexport` --> $DIR/diagnostics-reexport-2.rs:42:15 | LL | reexport::gated::foo(); @@ -13,7 +13,7 @@ LL | #[cfg(false)] LL | pub mod gated { | ^^^^^ -error[E0433]: failed to resolve: could not find `gated` in `reexport2` +error[E0433]: cannot find `gated` in `reexport2` --> $DIR/diagnostics-reexport-2.rs:46:16 | LL | reexport2::gated::foo(); @@ -28,7 +28,7 @@ LL | #[cfg(false)] LL | pub mod gated { | ^^^^^ -error[E0433]: failed to resolve: could not find `gated` in `reexport30` +error[E0433]: cannot find `gated` in `reexport30` --> $DIR/diagnostics-reexport-2.rs:50:17 | LL | reexport30::gated::foo(); @@ -43,7 +43,7 @@ LL | #[cfg(false)] LL | pub mod gated { | ^^^^^ -error[E0433]: failed to resolve: could not find `gated` in `reexport31` +error[E0433]: cannot find `gated` in `reexport31` --> $DIR/diagnostics-reexport-2.rs:54:17 | LL | reexport31::gated::foo(); @@ -58,7 +58,7 @@ LL | #[cfg(false)] LL | pub mod gated { | ^^^^^ -error[E0433]: failed to resolve: could not find `gated` in `reexport32` +error[E0433]: cannot find `gated` in `reexport32` --> $DIR/diagnostics-reexport-2.rs:58:17 | LL | reexport32::gated::foo(); diff --git a/tests/ui/cfg/diagnostics-same-crate.rs b/tests/ui/cfg/diagnostics-same-crate.rs index 29209d5f3eaa..40babaa3d4c9 100644 --- a/tests/ui/cfg/diagnostics-same-crate.rs +++ b/tests/ui/cfg/diagnostics-same-crate.rs @@ -50,7 +50,7 @@ fn main() { //~| NOTE not found in `inner` // The module isn't found - we get a diagnostic. - inner::doesnt_exist::hello(); //~ ERROR failed to resolve + inner::doesnt_exist::hello(); //~ ERROR cannot find //~| NOTE could not find `doesnt_exist` in `inner` // It should find the one in the right module, not the wrong one. diff --git a/tests/ui/cfg/diagnostics-same-crate.stderr b/tests/ui/cfg/diagnostics-same-crate.stderr index a8d789e61d1a..c20542e19eaf 100644 --- a/tests/ui/cfg/diagnostics-same-crate.stderr +++ b/tests/ui/cfg/diagnostics-same-crate.stderr @@ -28,7 +28,7 @@ LL | #[cfg(false)] LL | pub mod doesnt_exist { | ^^^^^^^^^^^^ -error[E0433]: failed to resolve: could not find `doesnt_exist` in `inner` +error[E0433]: cannot find `doesnt_exist` in `inner` --> $DIR/diagnostics-same-crate.rs:53:12 | LL | inner::doesnt_exist::hello(); diff --git a/tests/ui/cfg/invalid-cli-cfg-pred.rs b/tests/ui/cfg/invalid-cli-cfg-pred.rs new file mode 100644 index 000000000000..fdfb6b18d96b --- /dev/null +++ b/tests/ui/cfg/invalid-cli-cfg-pred.rs @@ -0,0 +1,5 @@ +//@ compile-flags: --cfg foo=1x + +fn main() {} + +//~? ERROR invalid `--cfg` argument diff --git a/tests/ui/cfg/invalid-cli-cfg-pred.stderr b/tests/ui/cfg/invalid-cli-cfg-pred.stderr new file mode 100644 index 000000000000..2f5ed55a6423 --- /dev/null +++ b/tests/ui/cfg/invalid-cli-cfg-pred.stderr @@ -0,0 +1,7 @@ +error: invalid suffix `x` for number literal + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + = note: this occurred on the command line: `--cfg=foo=1x` + +error: invalid `--cfg` argument: `foo=1x` (expected `key` or `key="value"`, ensure escaping is appropriate for your shell, try 'key="value"' or key=\"value\") + diff --git a/tests/ui/cfg/invalid-cli-check-cfg-pred.rs b/tests/ui/cfg/invalid-cli-check-cfg-pred.rs new file mode 100644 index 000000000000..30417a912bfc --- /dev/null +++ b/tests/ui/cfg/invalid-cli-check-cfg-pred.rs @@ -0,0 +1,5 @@ +//@ compile-flags: --check-cfg 'foo=1x' + +fn main() {} + +//~? ERROR invalid `--check-cfg` argument diff --git a/tests/ui/cfg/invalid-cli-check-cfg-pred.stderr b/tests/ui/cfg/invalid-cli-check-cfg-pred.stderr new file mode 100644 index 000000000000..be8299aa9edf --- /dev/null +++ b/tests/ui/cfg/invalid-cli-check-cfg-pred.stderr @@ -0,0 +1,10 @@ +error: invalid suffix `x` for number literal + | + = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + = note: this occurred on the command line: `--check-cfg=foo=1x` + +error: invalid `--check-cfg` argument: `foo=1x` + | + = note: expected `cfg(name, values("value1", "value2", ... "valueN"))` + = note: visit for more details + diff --git a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs index c5d86a27d522..8e79ce8d1546 100644 --- a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs +++ b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.rs @@ -3,14 +3,14 @@ //! expansion works from outside to inside, eventually applying the innermost //! conditional compilation directive. //! -//! In this test, `cfg_attr(all(), cfg_attr(all(), cfg(false)))` should expand to: -//! 1. `cfg_attr(all(), cfg(false))` (outer cfg_attr applied) +//! In this test, `cfg_attr(true, cfg_attr(true, cfg(false)))` should expand to: +//! 1. `cfg_attr(true, cfg(false))` (outer cfg_attr applied) //! 2. `cfg(false)` (inner cfg_attr applied) //! 3. Function `f` is excluded from compilation //! //! Added in . -#[cfg_attr(all(), cfg_attr(all(), cfg(false)))] //~ NOTE the item is gated here +#[cfg_attr(true, cfg_attr(true, cfg(false)))] //~ NOTE the item is gated here fn f() {} //~ NOTE found an item that was configured out fn main() { diff --git a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr index 3f833bd558b8..e93a5433d979 100644 --- a/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr +++ b/tests/ui/cfg/nested-cfg-attr-conditional-compilation.stderr @@ -7,8 +7,8 @@ LL | f() note: found an item that was configured out --> $DIR/nested-cfg-attr-conditional-compilation.rs:14:4 | -LL | #[cfg_attr(all(), cfg_attr(all(), cfg(false)))] - | ----- the item is gated here +LL | #[cfg_attr(true, cfg_attr(true, cfg(false)))] + | ----- the item is gated here LL | fn f() {} | ^ diff --git a/tests/ui/cfg/struct-field-empty.rs b/tests/ui/cfg/struct-field-empty.rs new file mode 100644 index 000000000000..eed69a0c03f0 --- /dev/null +++ b/tests/ui/cfg/struct-field-empty.rs @@ -0,0 +1,13 @@ +//! regression test for +//@ run-pass +#![allow(unused_variables)] +// `#[cfg]` on struct field permits empty unusable struct + +struct S { + #[cfg(false)] + a: int, +} + +fn main() { + let s = S {}; +} diff --git a/tests/ui/check-cfg/cfg-select.rs b/tests/ui/check-cfg/cfg-select.rs index 39703489818d..ffa5e40bff08 100644 --- a/tests/ui/check-cfg/cfg-select.rs +++ b/tests/ui/check-cfg/cfg-select.rs @@ -4,7 +4,7 @@ #![crate_type = "lib"] cfg_select! { - true => {} + false => {} invalid_cfg1 => {} //~^ WARN unexpected `cfg` condition name _ => {} @@ -13,6 +13,6 @@ cfg_select! { cfg_select! { invalid_cfg2 => {} //~^ WARN unexpected `cfg` condition name - true => {} + false => {} _ => {} } diff --git a/tests/ui/check-cfg/false.rs b/tests/ui/check-cfg/false.rs new file mode 100644 index 000000000000..f7ed43ccfa95 --- /dev/null +++ b/tests/ui/check-cfg/false.rs @@ -0,0 +1,61 @@ +//! Check that `cfg(false)` is suggested instead of cfg(FALSE) +// +//@ check-pass +//@ no-auto-check-cfg +//@ compile-flags: --check-cfg=cfg() + +#[cfg(FALSE)] +//~^ WARNING unexpected `cfg` condition name: `FALSE` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `false` (notice the capitalization). +pub fn a() {} + +#[cfg(False)] +//~^ WARNING unexpected `cfg` condition name: `False` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `false` (notice the capitalization). +pub fn b() {} + +#[cfg(r#false)] +//~^ WARNING unexpected `cfg` condition name: `r#false` +//~| HELP: to expect this configuration use +// No capitalization help for r#false +pub fn c() {} + +#[cfg(r#False)] +//~^ WARNING unexpected `cfg` condition name: `False` +//~| HELP: to expect this configuration use +// No capitalization help for r#False +pub fn d() {} + +#[cfg(false)] +pub fn e() {} + +#[cfg(TRUE)] +//~^ WARNING unexpected `cfg` condition name: `TRUE` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `true` (notice the capitalization). +pub fn f() {} + +#[cfg(True)] +//~^ WARNING unexpected `cfg` condition name: `True` +//~| HELP: to expect this configuration use +//~| HELP: you may have meant to use `true` (notice the capitalization). +pub fn g() {} + +#[cfg(r#true)] +//~^ WARNING unexpected `cfg` condition name: `r#true` +//~| HELP: to expect this configuration use +// No capitalization help for r#true +pub fn h() {} + +#[cfg(r#True)] +//~^ WARNING unexpected `cfg` condition name: `True` +//~| HELP: to expect this configuration use +// No capitalization help for r#True +pub fn i() {} + +#[cfg(true)] +pub fn j() {} + +pub fn main() {} diff --git a/tests/ui/check-cfg/false.stderr b/tests/ui/check-cfg/false.stderr new file mode 100644 index 000000000000..f4480a3dc67e --- /dev/null +++ b/tests/ui/check-cfg/false.stderr @@ -0,0 +1,95 @@ +warning: unexpected `cfg` condition name: `FALSE` + --> $DIR/false.rs:7:7 + | +LL | #[cfg(FALSE)] + | ^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(FALSE)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +help: you may have meant to use `false` (notice the capitalization). Doing so makes this predicate evaluate to `false` unconditionally + | +LL - #[cfg(FALSE)] +LL + #[cfg(false)] + | + +warning: unexpected `cfg` condition name: `False` + --> $DIR/false.rs:13:7 + | +LL | #[cfg(False)] + | ^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(False)` + = note: see for more information about checking conditional configuration +help: you may have meant to use `false` (notice the capitalization). Doing so makes this predicate evaluate to `false` unconditionally (notice the capitalization) + | +LL - #[cfg(False)] +LL + #[cfg(false)] + | + +warning: unexpected `cfg` condition name: `r#false` + --> $DIR/false.rs:19:7 + | +LL | #[cfg(r#false)] + | ^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(r#false)` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `False` + --> $DIR/false.rs:25:7 + | +LL | #[cfg(r#False)] + | ^^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(False)` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `TRUE` + --> $DIR/false.rs:34:7 + | +LL | #[cfg(TRUE)] + | ^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(TRUE)` + = note: see for more information about checking conditional configuration +help: you may have meant to use `true` (notice the capitalization). Doing so makes this predicate evaluate to `true` unconditionally + | +LL - #[cfg(TRUE)] +LL + #[cfg(true)] + | + +warning: unexpected `cfg` condition name: `True` + --> $DIR/false.rs:40:7 + | +LL | #[cfg(True)] + | ^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(True)` + = note: see for more information about checking conditional configuration +help: you may have meant to use `true` (notice the capitalization). Doing so makes this predicate evaluate to `true` unconditionally + | +LL - #[cfg(True)] +LL + #[cfg(true)] + | + +warning: unexpected `cfg` condition name: `r#true` + --> $DIR/false.rs:46:7 + | +LL | #[cfg(r#true)] + | ^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(r#true)` + = note: see for more information about checking conditional configuration + +warning: unexpected `cfg` condition name: `True` + --> $DIR/false.rs:52:7 + | +LL | #[cfg(r#True)] + | ^^^^^^ + | + = help: to expect this configuration use `--check-cfg=cfg(True)` + = note: see for more information about checking conditional configuration + +warning: 8 warnings emitted + diff --git a/tests/ui/check-cfg/nested-cfg.rs b/tests/ui/check-cfg/nested-cfg.rs new file mode 100644 index 000000000000..2b3a21f88dc5 --- /dev/null +++ b/tests/ui/check-cfg/nested-cfg.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#[cfg(unknown)] //~ WARN unexpected `cfg` condition name +#[cfg(false)] +#[cfg(unknown)] // Should not warn +fn foo() {} + +fn main() {} diff --git a/tests/ui/check-cfg/nested-cfg.stderr b/tests/ui/check-cfg/nested-cfg.stderr new file mode 100644 index 000000000000..6fdae732bbe5 --- /dev/null +++ b/tests/ui/check-cfg/nested-cfg.stderr @@ -0,0 +1,23 @@ +warning: unexpected `cfg` condition name: `unknown` + --> $DIR/nested-cfg.rs:3:7 + | +LL | #[cfg(unknown)] + | ^^^^^^^ + | + = help: expected names are: `FALSE` and `test` and 31 more + = help: to expect this configuration use `--check-cfg=cfg(unknown)` + = note: see for more information about checking conditional configuration + = note: `#[warn(unexpected_cfgs)]` on by default +help: found config with similar value + | +LL - #[cfg(unknown)] +LL + #[cfg(target_os = "unknown")] + | +help: found config with similar value + | +LL - #[cfg(unknown)] +LL + #[cfg(target_vendor = "unknown")] + | + +warning: 1 warning emitted + diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index d25e7f094964..06a7f477a7fd 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -14,6 +14,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `7e10` `a` `aclass` +`addsubiw` `adx` `aes` `altivec` @@ -57,6 +58,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `bf16` `bmi1` `bmi2` +`break` `bti` `bulk-memory` `c` @@ -83,6 +85,9 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `e2` `ecv` `edsp` +`eijmpcall` +`elpm` +`elpmx` `elrw` `enhanced-sort` `ermsb` @@ -121,6 +126,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `frecipe` `frintts` `fxsr` +`gc` `gfni` `guarded-storage` `hard-float` @@ -130,9 +136,24 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `high-registers` `high-word` `hvx` +`hvx-ieee-fp` `hvx-length128b` +`hvx-length64b` +`hvx-qfloat` +`hvxv60` +`hvxv62` +`hvxv65` +`hvxv66` +`hvxv67` +`hvxv68` +`hvxv69` +`hvxv71` +`hvxv73` +`hvxv75` +`hvxv79` `hwdiv` `i8mm` +`ijmpcall` `isa-68000` `isa-68010` `isa-68020` @@ -141,6 +162,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `isa-68060` `isa-68881` `isa-68882` +`jmpcall` `jsconv` `kl` `lahfsahf` @@ -151,6 +173,9 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `ld-seq-sa` `leoncasa` `lor` +`lowbytefirst` +`lpm` +`lpmx` `lse` `lse128` `lse2` @@ -172,11 +197,13 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `mops` `movbe` `movrs` +`movw` `mp` `mp1e2` `msa` `msync` `mte` +`mul` `multivalue` `mutable-globals` `neon` @@ -241,6 +268,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `reference-types` `relax` `relaxed-simd` +`rmw` `rtm` `rva23u64` `sb` @@ -293,6 +321,8 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `sme2p1` `soft-float` `spe` +`spm` +`spmx` `ssbs` `sse` `sse2` @@ -317,6 +347,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `tbm` `thumb-mode` `thumb2` +`tinyencoding` `tme` `transactional-execution` `trust` @@ -423,12 +454,14 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `zkn` `zknd` `zkne` +`zkne_or_zknd` `zknh` `zkr` `zks` `zksed` `zksh` `zkt` +`zreg` `ztso` `zvbb` `zvbc` diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index 2912c83b58de..21b6af9b5560 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -4,7 +4,9 @@ //@ check-pass //@ no-auto-check-cfg //@ needs-llvm-components: x86 -//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json +//@ compile-flags: --crate-type=lib --check-cfg=cfg() +//@ compile-flags: -Zunstable-options --target={{src-base}}/check-cfg/my-awesome-platform.json +//@ ignore-backends: gcc #![feature(lang_items, no_core, auto_traits, rustc_attrs)] #![no_core] diff --git a/tests/ui/closures/2229_closure_analysis/capture-enums.rs b/tests/ui/closures/2229_closure_analysis/capture-enums.rs index d9c06a68c95b..36b98351854b 100644 --- a/tests/ui/closures/2229_closure_analysis/capture-enums.rs +++ b/tests/ui/closures/2229_closure_analysis/capture-enums.rs @@ -1,6 +1,7 @@ //@ edition:2021 #![feature(rustc_attrs)] +#![feature(stmt_expr_attributes)] enum Info { Point(i32, i32, String), @@ -14,14 +15,12 @@ fn multi_variant_enum() { let meta = Info::Meta("meta".into(), vec); let c = #[rustc_capture_analysis] - //~^ ERROR: attributes on expressions are experimental - //~| NOTE: see issue #15701 - //~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date || { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: if let Info::Point(_, _, str) = point { //~^ NOTE: Capturing point[] -> Immutable + //~| NOTE: Capturing point[] -> Immutable //~| NOTE: Capturing point[(2, 0)] -> ByValue //~| NOTE: Min Capture point[] -> ByValue println!("{}", str); @@ -29,6 +28,7 @@ fn multi_variant_enum() { if let Info::Meta(_, v) = meta { //~^ NOTE: Capturing meta[] -> Immutable + //~| NOTE: Capturing meta[] -> Immutable //~| NOTE: Capturing meta[(1, 1)] -> ByValue //~| NOTE: Min Capture meta[] -> ByValue println!("{:?}", v); @@ -46,9 +46,6 @@ fn single_variant_enum() { let point = SingleVariant::Point(10, -10, "1".into()); let c = #[rustc_capture_analysis] - //~^ ERROR: attributes on expressions are experimental - //~| NOTE: see issue #15701 - //~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date || { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: diff --git a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr index 89a879cec468..2f49c8668f85 100644 --- a/tests/ui/closures/2229_closure_analysis/capture-enums.stderr +++ b/tests/ui/closures/2229_closure_analysis/capture-enums.stderr @@ -1,25 +1,5 @@ -error[E0658]: attributes on expressions are experimental - --> $DIR/capture-enums.rs:16:13 - | -LL | let c = #[rustc_capture_analysis] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #15701 for more information - = help: add `#![feature(stmt_expr_attributes)]` 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[E0658]: attributes on expressions are experimental - --> $DIR/capture-enums.rs:48:13 - | -LL | let c = #[rustc_capture_analysis] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #15701 for more information - = help: add `#![feature(stmt_expr_attributes)]` 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: First Pass analysis includes: - --> $DIR/capture-enums.rs:20:5 + --> $DIR/capture-enums.rs:18:5 | LL | / || { LL | | @@ -30,28 +10,38 @@ LL | | }; | |_____^ | note: Capturing point[] -> Immutable - --> $DIR/capture-enums.rs:23:41 + --> $DIR/capture-enums.rs:21:41 + | +LL | if let Info::Point(_, _, str) = point { + | ^^^^^ +note: Capturing point[] -> Immutable + --> $DIR/capture-enums.rs:21:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Capturing point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:23:41 + --> $DIR/capture-enums.rs:21:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Capturing meta[] -> Immutable - --> $DIR/capture-enums.rs:30:35 + --> $DIR/capture-enums.rs:29:35 + | +LL | if let Info::Meta(_, v) = meta { + | ^^^^ +note: Capturing meta[] -> Immutable + --> $DIR/capture-enums.rs:29:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ note: Capturing meta[(1, 1)] -> ByValue - --> $DIR/capture-enums.rs:30:35 + --> $DIR/capture-enums.rs:29:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ error: Min Capture analysis includes: - --> $DIR/capture-enums.rs:20:5 + --> $DIR/capture-enums.rs:18:5 | LL | / || { LL | | @@ -62,18 +52,18 @@ LL | | }; | |_____^ | note: Min Capture point[] -> ByValue - --> $DIR/capture-enums.rs:23:41 + --> $DIR/capture-enums.rs:21:41 | LL | if let Info::Point(_, _, str) = point { | ^^^^^ note: Min Capture meta[] -> ByValue - --> $DIR/capture-enums.rs:30:35 + --> $DIR/capture-enums.rs:29:35 | LL | if let Info::Meta(_, v) = meta { | ^^^^ error: First Pass analysis includes: - --> $DIR/capture-enums.rs:52:5 + --> $DIR/capture-enums.rs:49:5 | LL | / || { LL | | @@ -85,13 +75,13 @@ LL | | }; | |_____^ | note: Capturing point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:55:47 + --> $DIR/capture-enums.rs:52:47 | LL | let SingleVariant::Point(_, _, str) = point; | ^^^^^ error: Min Capture analysis includes: - --> $DIR/capture-enums.rs:52:5 + --> $DIR/capture-enums.rs:49:5 | LL | / || { LL | | @@ -103,11 +93,10 @@ LL | | }; | |_____^ | note: Min Capture point[(2, 0)] -> ByValue - --> $DIR/capture-enums.rs:55:47 + --> $DIR/capture-enums.rs:52:47 | LL | let SingleVariant::Point(_, _, str) = point; | ^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs b/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs new file mode 100644 index 000000000000..b2c0eac9efa2 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/deref-mut-in-pattern.rs @@ -0,0 +1,54 @@ +// Newly accepted examples as a result of the changes introduced in #138961. +// +//@ edition:2024 +//@ check-pass +#![allow(unused_assignments)] + +// Reading the length as part of a pattern captures the pointee. +fn f() { + let mut x: &mut [u8] = &mut [1, 2, 3]; + let c = || { + match x { + [] => (), + _ => (), + } + }; + x = &mut []; + c(); +} + +// Plain old deref as part of pattern behaves similarly +fn g() { + let mut x: &mut bool = &mut false; + let mut t = true; + let c = || { + match x { + true => (), + false => (), + } + }; + x = &mut t; + c(); +} + +// Like f, but the lifetime implications are expressed in terms of +// returning a closure. +fn f2<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l { + || match *x { + &[] => (), + _ => (), + } +} + +// Related testcase that was already accepted before +fn f3<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l { + || match **x { + [] => (), + _ => (), + } +} + +fn main() { + f(); + g(); +} diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr index 97ecdfab8205..4249dea10a36 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/arrays.stderr @@ -53,8 +53,6 @@ LL | println!("{}", arr[3]); ... LL | c(); | - mutable borrow later used here - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0502]: cannot borrow `arr` as immutable because it is also borrowed as mutable --> $DIR/arrays.rs:71:24 diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr index 2e3259e64059..09143f44dc83 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/box.stderr @@ -25,8 +25,6 @@ LL | println!("{}", e.0.0.m.x); LL | LL | c(); | - mutable borrow later used here - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0506]: cannot assign to `e.0.0.m.x` because it is borrowed --> $DIR/box.rs:55:5 diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr index 0e93e033c022..f59be6b7a720 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr @@ -7,7 +7,6 @@ LL | println!("{}", foo.x); = note: this struct is 1-byte aligned, but the type of this field may require higher alignment = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr index 68fdb3ce131f..406f7c63b734 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/simple-struct-min-capture.stderr @@ -13,8 +13,6 @@ LL | println!("{:?}", p); LL | LL | c(); | - mutable borrow later used here - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_drop_order_lib.rs b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_drop_order_lib.rs new file mode 100644 index 000000000000..8cf25c6ba7b2 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_drop_order_lib.rs @@ -0,0 +1,11 @@ +pub struct LoudDrop(pub &'static str); +impl Drop for LoudDrop { + fn drop(&mut self) { + println!("dropping {}", self.0); + } +} + +#[non_exhaustive] +pub enum ExtNonExhaustive { + One(i32, LoudDrop), +} diff --git a/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_lib.rs b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_lib.rs new file mode 100644 index 000000000000..b0646f1d0032 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/auxiliary/partial_move_lib.rs @@ -0,0 +1,4 @@ +#[non_exhaustive] +pub enum ExtNonExhaustive { + A(u32, String), +} diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs index a3b19708899a..81013e5b2cd1 100644 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs +++ b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.rs @@ -34,4 +34,82 @@ fn edge_case_if() { _b(); } +struct Unit; + +enum TSingle { + A(u32, u32), +} + +enum SSingle { + A { a: u32, b: u32 }, +} + +struct TStruct(u32, u32); +struct SStruct { a: u32, b: u32 } + + +// Destructuring a unit struct should not capture it +fn match_unit_struct(mut x: (Unit, u32)) { + let r = &mut x.0; + let _ = || { + let (Unit, a) = x; + a + }; + + let _ = *r; +} + +// The same is true for an equivalent enum +fn match_unit_enum(mut x: (SingleVariant, u32)) { + let r = &mut x.0; + let _ = || { + let (SingleVariant::A, a) = x; + a + }; + + let _ = *r; +} + +// More generally, destructuring a struct should only capture the fields being touched +fn match_struct(mut x: SStruct) { + let r = &mut x.a; + let _ = || { + let SStruct { b, .. } = x; + b + }; + + let _ = *r; +} + +fn match_tuple_struct(mut x: TStruct) { + let r = &mut x.0; + let _ = || { + let TStruct(_, a) = x; + a + }; + + let _ = *r; +} + +// The same is true for an equivalent enum as well +fn match_singleton(mut x: SSingle) { + let SSingle::A { a: ref mut r, .. } = x; + let _ = || { + let SSingle::A { b, .. } = x; + b + }; + + let _ = *r; +} + +fn match_tuple_singleton(mut x: TSingle) { + let TSingle::A(ref mut r, _) = x; + let _ = || { + let TSingle::A(_, a) = x; + a + }; + + let _ = *r; +} + fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr index d82db0481a06..3f5fe9eda423 100644 --- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_2.stderr @@ -4,7 +4,7 @@ error[E0505]: cannot move out of `ts` because it is borrowed LL | let _b = || { match ts { | -- -- borrow occurs due to use in closure | | - | borrow of `ts` occurs here + | borrow of `ts.x` occurs here ... LL | let mut mut_ts = ts; | ^^ move out of `ts` occurs here diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs index 322555827181..f47d70b52f20 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs @@ -10,6 +10,8 @@ // Ignore non_exhaustive in the same crate #[non_exhaustive] enum L1 { A, B } + +#[non_exhaustive] enum L2 { C } extern crate match_non_exhaustive_lib; @@ -26,12 +28,6 @@ fn main() { let _b = || { match l1 { L1::A => () } }; //~^ ERROR: non-exhaustive patterns: `L1::B` not covered [E0004] - // l2 should not be captured as it is a non-exhaustive SingleVariant - // defined in this crate - let _c = || { match l2 { L2::C => (), _ => () } }; - let mut mut_l2 = l2; - _c(); - // E1 is not visibly uninhabited from here let (e1, e2, e3, e4) = bar(); let _d = || { match e1 {} }; @@ -40,8 +36,14 @@ fn main() { //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004] let _f = || { match e2 { E2::A => (), E2::B => (), _ => () } }; - // e3 should be captured as it is a non-exhaustive SingleVariant - // defined in another crate + // non-exhaustive enums should always be captured, regardless if they + // are defined in the current crate: + let _c = || { match l2 { L2::C => (), _ => () } }; + let mut mut_l2 = l2; + //~^ ERROR: cannot move out of `l2` because it is borrowed + _c(); + + // ...or in another crate: let _g = || { match e3 { E3::C => (), _ => () } }; let mut mut_e3 = e3; //~^ ERROR: cannot move out of `e3` because it is borrowed diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr index 85426dd9a5ea..e34d1889803a 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `L1::B` not covered - --> $DIR/non-exhaustive-match.rs:26:25 + --> $DIR/non-exhaustive-match.rs:28:25 | LL | let _b = || { match l1 { L1::A => () } }; | ^^ pattern `L1::B` not covered @@ -16,7 +16,7 @@ LL | let _b = || { match l1 { L1::A => (), L1::B => todo!() } }; | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: type `E1` is non-empty - --> $DIR/non-exhaustive-match.rs:37:25 + --> $DIR/non-exhaustive-match.rs:33:25 | LL | let _d = || { match e1 {} }; | ^^ @@ -35,7 +35,7 @@ LL ~ } }; | error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/non-exhaustive-match.rs:39:25 + --> $DIR/non-exhaustive-match.rs:35:25 | LL | let _e = || { match e2 { E2::A => (), E2::B => () } }; | ^^ pattern `_` not covered @@ -52,8 +52,21 @@ help: ensure that all possible cases are being handled by adding a match arm wit LL | let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } }; | ++++++++++++++ +error[E0505]: cannot move out of `l2` because it is borrowed + --> $DIR/non-exhaustive-match.rs:42:22 + | +LL | let _c = || { match l2 { L2::C => (), _ => () } }; + | -- -- borrow occurs due to use in closure + | | + | borrow of `l2` occurs here +LL | let mut mut_l2 = l2; + | ^^ move out of `l2` occurs here +LL | +LL | _c(); + | -- borrow later used here + error[E0505]: cannot move out of `e3` because it is borrowed - --> $DIR/non-exhaustive-match.rs:46:22 + --> $DIR/non-exhaustive-match.rs:48:22 | LL | let _g = || { match e3 { E3::C => (), _ => () } }; | -- -- borrow occurs due to use in closure @@ -65,7 +78,7 @@ LL | LL | _g(); | -- borrow later used here -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0004, E0505. For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs new file mode 100644 index 000000000000..348d558dd980 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.rs @@ -0,0 +1,88 @@ +// Make sure that #[non_exhaustive] cannot cause drop order to depend on which +// crate the code is in. +// +// See rust-lang/rust#147722 +// +//@ edition:2021 +//@ run-pass +//@ check-run-results +//@ aux-build:partial_move_drop_order_lib.rs + +extern crate partial_move_drop_order_lib; +use partial_move_drop_order_lib::{LoudDrop, ExtNonExhaustive}; + +pub enum OneVariant { + One(i32, LoudDrop), +} + +pub enum TwoVariants { + One(i32, LoudDrop), + Two, +} + +#[non_exhaustive] +pub enum NonExhaustive { + One(i32, LoudDrop), +} + +#[allow(unused)] +fn one_variant() { + println!("one variant:"); + let mut thing = OneVariant::One(0, LoudDrop("a")); + let closure = move || match thing { + OneVariant::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = OneVariant::One(1, LoudDrop("b")); + println!("after assign"); +} + +#[allow(unused)] +fn two_variants() { + println!("two variants:"); + let mut thing = TwoVariants::One(0, LoudDrop("a")); + let closure = move || match thing { + TwoVariants::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = TwoVariants::One(1, LoudDrop("b")); + println!("after assign"); +} + +#[allow(unused)] +fn non_exhaustive() { + println!("non exhaustive:"); + let mut thing = NonExhaustive::One(0, LoudDrop("a")); + let closure = move || match thing { + NonExhaustive::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = NonExhaustive::One(1, LoudDrop("b")); + println!("after assign"); +} + +#[allow(unused)] +fn ext_non_exhaustive() { + println!("external non exhaustive:"); + let mut thing = ExtNonExhaustive::One(0, LoudDrop("a")); + let closure = move || match thing { + ExtNonExhaustive::One(x, _) => {} + _ => unreachable!(), + }; + println!("before assign"); + thing = ExtNonExhaustive::One(1, LoudDrop("b")); + println!("after assign"); +} + +fn main() { + one_variant(); + println!(); + two_variants(); + println!(); + non_exhaustive(); + println!(); + ext_non_exhaustive(); +} diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout new file mode 100644 index 000000000000..3fa346d87b07 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move-drop-order.run.stdout @@ -0,0 +1,23 @@ +one variant: +before assign +dropping a +after assign +dropping b + +two variants: +before assign +after assign +dropping a +dropping b + +non exhaustive: +before assign +after assign +dropping a +dropping b + +external non exhaustive: +before assign +after assign +dropping a +dropping b diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.rs b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs new file mode 100644 index 000000000000..7bd435bd1856 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.rs @@ -0,0 +1,116 @@ +// This test measures the effect of matching-induced partial captures on the borrow checker. +// In particular, in each of the cases below, the closure either captures the entire enum/struct, +// or each field separately. +// +// If the entire ADT gets captured, it'll happen by move, and the closure will live for 'static. +// On the other hand, if each field gets captured separately, the u32 field, being Copy, will only +// get captured by an immutable borrow, resulting in a borrow checker error. +// +// See rust-lang/rust#147722 +// +//@ edition:2021 +//@ aux-build:partial_move_lib.rs +pub struct Struct(u32, String); + +pub enum Enum { + A(u32, String), +} + +pub enum TwoVariants { + A(u32, String), + B, +} + +#[non_exhaustive] +pub enum NonExhaustive { + A(u32, String), +} + +extern crate partial_move_lib; +use partial_move_lib::ExtNonExhaustive; + +// First, let's assert that the additional wildcard arm is not a source of any behavior +// differences: +pub fn test_enum1(x: Enum) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + Enum::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +pub fn test_enum2(x: Enum) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + Enum::A(a, b) => { + drop((a, b)); + } + } + } +} + +// The behavior for single-variant enums matches what happens for a struct +pub fn test_struct(x: Struct) -> impl FnOnce() { + || { + //~^ ERROR: closure may outlive the current function, but it borrows `x.0` + match x { + Struct(a, b) => { + drop((a, b)); + } + } + } +} + +// If we have two variants, the entire enum gets moved into the closure +pub fn test_two_variants(x: TwoVariants) -> impl FnOnce() { + || { + match x { + TwoVariants::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +// ...and single-variant, non-exhaustive enums behave as if they had multiple variants +pub fn test_non_exhaustive1(x: NonExhaustive) -> impl FnOnce() { + || { + match x { + NonExhaustive::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +// (again, wildcard branch or not) +pub fn test_non_exhaustive2(x: NonExhaustive) -> impl FnOnce() { + || { + match x { + NonExhaustive::A(a, b) => { + drop((a, b)); + } + } + } +} + +// ...regardless of whether the enum is defined in the current, or in another crate +pub fn test_ext(x: ExtNonExhaustive) -> impl FnOnce() { + || { + match x { + ExtNonExhaustive::A(a, b) => { + drop((a, b)); + } + _ => unreachable!(), + } + } +} + +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr new file mode 100644 index 000000000000..09f9adf95d5b --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/match/partial-move.stderr @@ -0,0 +1,75 @@ +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:35:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:35:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | Enum::A(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:47:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:47:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | Enum::A(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error[E0373]: closure may outlive the current function, but it borrows `x.0`, which is owned by the current function + --> $DIR/partial-move.rs:59:5 + | +LL | || { + | ^^ may outlive borrowed value `x.0` +LL | +LL | match x { + | - `x.0` is borrowed here + | +note: closure is returned here + --> $DIR/partial-move.rs:59:5 + | +LL | / || { +LL | | +LL | | match x { +LL | | Struct(a, b) => { +... | +LL | | } + | |_____^ +help: to force the closure to take ownership of `x.0` (and any other referenced variables), use the `move` keyword + | +LL | move || { + | ++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0373`. diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs index 40330af4088c..16cb9d7355da 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs @@ -64,9 +64,8 @@ fn test_6_should_capture_single_variant() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match variant { - //~^ NOTE: Capturing variant[] -> Immutable - //~| NOTE: Capturing variant[(0, 0)] -> Immutable - //~| NOTE: Min Capture variant[] -> Immutable + //~^ NOTE: Capturing variant[(0, 0)] -> Immutable + //~| NOTE: Min Capture variant[(0, 0)] -> Immutable SingleVariant::Points(a) => { println!("{:?}", a); } @@ -149,8 +148,8 @@ fn test_7_should_capture_slice_len() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match slice { - //~^ NOTE: Capturing slice[] -> Immutable - //~| NOTE: Min Capture slice[] -> Immutable + //~^ NOTE: Capturing slice[Deref] -> Immutable + //~| NOTE: Min Capture slice[Deref] -> Immutable [_,_,_] => {}, _ => {} } @@ -161,8 +160,8 @@ fn test_7_should_capture_slice_len() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match slice { - //~^ NOTE: Capturing slice[] -> Immutable - //~| NOTE: Min Capture slice[] -> Immutable + //~^ NOTE: Capturing slice[Deref] -> Immutable + //~| NOTE: Min Capture slice[Deref] -> Immutable [] => {}, _ => {} } @@ -173,8 +172,8 @@ fn test_7_should_capture_slice_len() { //~^ ERROR First Pass analysis includes: //~| ERROR Min Capture analysis includes: match slice { - //~^ NOTE: Capturing slice[] -> Immutable - //~| NOTE: Min Capture slice[] -> Immutable + //~^ NOTE: Capturing slice[Deref] -> Immutable + //~| NOTE: Min Capture slice[Deref] -> Immutable [_, .. ,_] => {}, _ => {} } diff --git a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr index e7e5e7f7fa1b..73c685e15276 100644 --- a/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr @@ -65,11 +65,6 @@ LL | | match variant { LL | | }; | |_____^ | -note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:66:15 - | -LL | match variant { - | ^^^^^^^ note: Capturing variant[(0, 0)] -> Immutable --> $DIR/patterns-capture-analysis.rs:66:15 | @@ -87,14 +82,14 @@ LL | | match variant { LL | | }; | |_____^ | -note: Min Capture variant[] -> Immutable +note: Min Capture variant[(0, 0)] -> Immutable --> $DIR/patterns-capture-analysis.rs:66:15 | LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:83:5 + --> $DIR/patterns-capture-analysis.rs:82:5 | LL | / || { LL | | @@ -105,7 +100,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:95:5 + --> $DIR/patterns-capture-analysis.rs:94:5 | LL | / || { LL | | @@ -116,7 +111,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:108:5 + --> $DIR/patterns-capture-analysis.rs:107:5 | LL | / || { LL | | @@ -127,7 +122,7 @@ LL | | }; | |_____^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:130:5 + --> $DIR/patterns-capture-analysis.rs:129:5 | LL | / || { LL | | @@ -138,13 +133,13 @@ LL | | }; | |_____^ | note: Capturing variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:133:15 + --> $DIR/patterns-capture-analysis.rs:132:15 | LL | match variant { | ^^^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:130:5 + --> $DIR/patterns-capture-analysis.rs:129:5 | LL | / || { LL | | @@ -155,13 +150,13 @@ LL | | }; | |_____^ | note: Min Capture variant[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:133:15 + --> $DIR/patterns-capture-analysis.rs:132:15 | LL | match variant { | ^^^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:148:5 + --> $DIR/patterns-capture-analysis.rs:147:5 | LL | / || { LL | | @@ -171,14 +166,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:151:15 +note: Capturing slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:150:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:148:5 + --> $DIR/patterns-capture-analysis.rs:147:5 | LL | / || { LL | | @@ -188,14 +183,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:151:15 +note: Min Capture slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:150:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:160:5 + --> $DIR/patterns-capture-analysis.rs:159:5 | LL | / || { LL | | @@ -205,14 +200,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:163:15 +note: Capturing slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:162:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:160:5 + --> $DIR/patterns-capture-analysis.rs:159:5 | LL | / || { LL | | @@ -222,14 +217,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:163:15 +note: Min Capture slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:162:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:172:5 + --> $DIR/patterns-capture-analysis.rs:171:5 | LL | / || { LL | | @@ -239,14 +234,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Capturing slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:175:15 +note: Capturing slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:174:15 | LL | match slice { | ^^^^^ error: Min Capture analysis includes: - --> $DIR/patterns-capture-analysis.rs:172:5 + --> $DIR/patterns-capture-analysis.rs:171:5 | LL | / || { LL | | @@ -256,14 +251,14 @@ LL | | match slice { LL | | }; | |_____^ | -note: Min Capture slice[] -> Immutable - --> $DIR/patterns-capture-analysis.rs:175:15 +note: Min Capture slice[Deref] -> Immutable + --> $DIR/patterns-capture-analysis.rs:174:15 | LL | match slice { | ^^^^^ error: First Pass analysis includes: - --> $DIR/patterns-capture-analysis.rs:189:5 + --> $DIR/patterns-capture-analysis.rs:188:5 | LL | / || { LL | | diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs new file mode 100644 index 000000000000..c7f367cc48ab --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.rs @@ -0,0 +1,22 @@ +// This example used to compile, but the fact that it should was never properly +// discussed. With further experience, we concluded that capture precision +// depending on whether some types are inhabited goes too far, introducing a +// bunch of headaches without much benefit. +//@ edition:2021 +enum Void {} + +pub fn main() { + let mut r = Result::::Err((0, 0)); + let mut f = || { + let Err((ref mut a, _)) = r; + *a = 1; + }; + let mut g = || { + //~^ ERROR: cannot borrow `r` as mutable more than once at a time + let Err((_, ref mut b)) = r; + *b = 2; + }; + f(); + g(); + assert!(matches!(r, Err((1, 2)))); +} diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr new file mode 100644 index 000000000000..7f4c8942b0d9 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant-stable.stderr @@ -0,0 +1,20 @@ +error[E0499]: cannot borrow `r` as mutable more than once at a time + --> $DIR/only-inhabited-variant-stable.rs:14:17 + | +LL | let mut f = || { + | -- first mutable borrow occurs here +LL | let Err((ref mut a, _)) = r; + | - first borrow occurs due to use of `r` in closure +... +LL | let mut g = || { + | ^^ second mutable borrow occurs here +LL | +LL | let Err((_, ref mut b)) = r; + | - second borrow occurs due to use of `r` in closure +... +LL | f(); + | - first borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.exhaustive_patterns.stderr b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.exhaustive_patterns.stderr new file mode 100644 index 000000000000..58a5348aa391 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.exhaustive_patterns.stderr @@ -0,0 +1,20 @@ +error[E0499]: cannot borrow `r` as mutable more than once at a time + --> $DIR/only-inhabited-variant.rs:16:17 + | +LL | let mut f = || { + | -- first mutable borrow occurs here +LL | let Err((ref mut a, _)) = r; + | - first borrow occurs due to use of `r` in closure +... +LL | let mut g = || { + | ^^ second mutable borrow occurs here +LL | +LL | let Err((_, ref mut b)) = r; + | - second borrow occurs due to use of `r` in closure +... +LL | f(); + | - first borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.normal.stderr b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.normal.stderr new file mode 100644 index 000000000000..58a5348aa391 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.normal.stderr @@ -0,0 +1,20 @@ +error[E0499]: cannot borrow `r` as mutable more than once at a time + --> $DIR/only-inhabited-variant.rs:16:17 + | +LL | let mut f = || { + | -- first mutable borrow occurs here +LL | let Err((ref mut a, _)) = r; + | - first borrow occurs due to use of `r` in closure +... +LL | let mut g = || { + | ^^ second mutable borrow occurs here +LL | +LL | let Err((_, ref mut b)) = r; + | - second borrow occurs due to use of `r` in closure +... +LL | f(); + | - first borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.rs b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.rs new file mode 100644 index 000000000000..463838734726 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/only-inhabited-variant.rs @@ -0,0 +1,24 @@ +// This example used to compile, but the fact that it should was never properly +// discussed. With further experience, we concluded that capture precision +// depending on whether some types are inhabited goes too far, introducing a +// bunch of headaches without much benefit. +//@ revisions: normal exhaustive_patterns +//@ edition:2021 +#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] +#![feature(never_type)] + +pub fn main() { + let mut r = Result::::Err((0, 0)); + let mut f = || { + let Err((ref mut a, _)) = r; + *a = 1; + }; + let mut g = || { + //~^ ERROR: cannot borrow `r` as mutable more than once at a time + let Err((_, ref mut b)) = r; + *b = 2; + }; + f(); + g(); + assert_eq!(r, Err((1, 2))); +} diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs deleted file mode 100644 index 74f37b514e4a..000000000000 --- a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Test precise capture of a multi-variant enum (when remaining variants are -// visibly uninhabited). -//@ revisions: normal exhaustive_patterns -//@ edition:2021 -//@ run-pass -#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))] -#![feature(never_type)] - -pub fn main() { - let mut r = Result::::Err((0, 0)); - let mut f = || { - let Err((ref mut a, _)) = r; - *a = 1; - }; - let mut g = || { - let Err((_, ref mut b)) = r; - *b = 2; - }; - f(); - g(); - assert_eq!(r, Err((1, 2))); -} diff --git a/tests/ui/closures/at-pattern-weirdness-issue-137553.rs b/tests/ui/closures/at-pattern-weirdness-issue-137553.rs new file mode 100644 index 000000000000..7c934d4a1433 --- /dev/null +++ b/tests/ui/closures/at-pattern-weirdness-issue-137553.rs @@ -0,0 +1,41 @@ +//@ edition:2024 +//@ check-pass + +// Background: +fn f1() { + let mut a = (21, 37); + // only captures a.0, example compiles fine + let mut f = || { + let (ref mut x, _) = a; + *x = 42; + }; + a.1 = 69; + f(); +} + +// This used to error out: +fn f2() { + let mut a = (21, 37); + // used to capture all of a, now captures only a.0 + let mut f = || { + match a { + (ref mut x, _) => *x = 42, + } + }; + a.1 = 69; + f(); +} + +// This was inconsistent with the following: +fn main() { + let mut a = (21, 37); + // the useless @-pattern would cause it to capture only a.0. now the + // behavior is consistent with the case that doesn't use the @-pattern + let mut f = || { + match a { + (ref mut x @ _, _) => *x = 42, + } + }; + a.1 = 69; + f(); +} diff --git a/tests/ui/closures/binder/implicit-stuff.rs b/tests/ui/closures/binder/implicit-stuff.rs index c976c200b0c8..09e4c747afee 100644 --- a/tests/ui/closures/binder/implicit-stuff.rs +++ b/tests/ui/closures/binder/implicit-stuff.rs @@ -24,5 +24,4 @@ fn main() { //~| ERROR `'_` cannot be used here let _ = for<'a> |x: &()| -> &'a () { x }; //~ ERROR `&` without an explicit lifetime name cannot be used here let _ = for<'a> |x: &'a ()| -> &() { x }; //~ ERROR `&` without an explicit lifetime name cannot be used here - //~^ ERROR: lifetime may not live long enough } diff --git a/tests/ui/closures/binder/implicit-stuff.stderr b/tests/ui/closures/binder/implicit-stuff.stderr index 330a05a79bae..cec2a60ba28c 100644 --- a/tests/ui/closures/binder/implicit-stuff.stderr +++ b/tests/ui/closures/binder/implicit-stuff.stderr @@ -102,15 +102,6 @@ LL | let _ = for<'a> |x: &'a _, y, z: _| -> &'a _ { | | | `for<...>` is here -error: lifetime may not live long enough - --> $DIR/implicit-stuff.rs:26:42 - | -LL | let _ = for<'a> |x: &'a ()| -> &() { x }; - | -- - ^ returning this value requires that `'a` must outlive `'1` - | | | - | | let's call the lifetime of this reference `'1` - | lifetime `'a` defined here - -error: aborting due to 16 previous errors +error: aborting due to 15 previous errors For more information about this error, try `rustc --explain E0637`. diff --git a/tests/ui/closures/closure-arg-borrow-ice-issue-152331.rs b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.rs new file mode 100644 index 000000000000..261f8fedc38f --- /dev/null +++ b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.rs @@ -0,0 +1,10 @@ +fn main() { + h2(|_: (), _: (), _: (), x: &_| {}); + //~^ ERROR type mismatch in closure arguments +} + +fn h2(_: F) +where + F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())), +{ +} diff --git a/tests/ui/closures/closure-arg-borrow-ice-issue-152331.stderr b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.stderr new file mode 100644 index 000000000000..7cfc9f0576ec --- /dev/null +++ b/tests/ui/closures/closure-arg-borrow-ice-issue-152331.stderr @@ -0,0 +1,32 @@ +error[E0631]: type mismatch in closure arguments + --> $DIR/closure-arg-borrow-ice-issue-152331.rs:2:5 + | +LL | h2(|_: (), _: (), _: (), x: &_| {}); + | ^^^----------------------------^^^^ + | | | + | | found signature defined here + | expected due to this + | + = note: expected closure signature `for<'a, 't0> fn(&'a (), Box<(dyn for<'a> Fn(&'a ()) + 'static)>, &'t0 (), for<'a, 'b> fn(&'a (), &'b ())) -> _` + found closure signature `fn((), (), (), &_) -> _` +note: required by a bound in `h2` + --> $DIR/closure-arg-borrow-ice-issue-152331.rs:8:8 + | +LL | fn h2(_: F) + | -- required by a bound in this function +LL | where +LL | F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `h2` +help: consider adjusting the signature so it borrows its arguments + | +LL | h2(|_: &(), _: (), _: &(), x: &_| {}); + | + + +help: consider adjusting the signature so it does not borrow its argument + | +LL - h2(|_: (), _: (), _: (), x: &_| {}); +LL + h2(|_: (), _: (), _: (), x: _| {}); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0631`. diff --git a/tests/ui/closures/closure-array-break-length.rs b/tests/ui/closures/closure-array-break-length.rs index fda590fda022..c90ae6585dca 100644 --- a/tests/ui/closures/closure-array-break-length.rs +++ b/tests/ui/closures/closure-array-break-length.rs @@ -1,7 +1,18 @@ +//! regression test for issue fn main() { |_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop + |_: [_; break]| (); //~ ERROR: `break` outside of a loop or labeled block + while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop + + loop { + |_: [_; break]| {} //~ ERROR: `break` outside of a loop + } + + loop { + |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop + } } diff --git a/tests/ui/closures/closure-array-break-length.stderr b/tests/ui/closures/closure-array-break-length.stderr index 7e0b0027a6f0..3256c50bb906 100644 --- a/tests/ui/closures/closure-array-break-length.stderr +++ b/tests/ui/closures/closure-array-break-length.stderr @@ -1,21 +1,39 @@ error[E0268]: `continue` outside of a loop - --> $DIR/closure-array-break-length.rs:2:13 + --> $DIR/closure-array-break-length.rs:3:13 | LL | |_: [_; continue]| {}; | ^^^^^^^^ cannot `continue` outside of a loop +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/closure-array-break-length.rs:5:13 + | +LL | |_: [_; break]| (); + | ^^^^^ cannot `break` outside of a loop or labeled block + error[E0268]: `continue` outside of a loop - --> $DIR/closure-array-break-length.rs:4:19 + --> $DIR/closure-array-break-length.rs:7:19 | LL | while |_: [_; continue]| {} {} | ^^^^^^^^ cannot `continue` outside of a loop error[E0268]: `break` outside of a loop or labeled block - --> $DIR/closure-array-break-length.rs:6:19 + --> $DIR/closure-array-break-length.rs:9:19 | LL | while |_: [_; break]| {} {} | ^^^^^ cannot `break` outside of a loop or labeled block -error: aborting due to 3 previous errors +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/closure-array-break-length.rs:12:17 + | +LL | |_: [_; break]| {} + | ^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `continue` outside of a loop + --> $DIR/closure-array-break-length.rs:16:17 + | +LL | |_: [_; continue]| {} + | ^^^^^^^^ cannot `continue` outside of a loop + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.rs b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs new file mode 100644 index 000000000000..863bcedd01e6 --- /dev/null +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.rs @@ -0,0 +1,16 @@ +//! regression test for +struct NoCopy; //~ NOTE: if `NoCopy` implemented `Clone`, you could clone the value +//~^ NOTE: consider implementing `Clone` for this type +fn main() { + let x = NoCopy; + //~^ NOTE: move occurs because `x` has type `NoCopy` + let f = move || { + //~^ NOTE: value moved into closure here + let y = x; + //~^ NOTE: variable moved due to use in closure + //~| NOTE: you could clone this value + }; + let z = x; + //~^ ERROR: use of moved value: `x` + //~| NOTE: value used here after move +} diff --git a/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr new file mode 100644 index 000000000000..94f80da1b10a --- /dev/null +++ b/tests/ui/closures/closure-move-use-after-move-diagnostic.stderr @@ -0,0 +1,27 @@ +error[E0382]: use of moved value: `x` + --> $DIR/closure-move-use-after-move-diagnostic.rs:13:13 + | +LL | let x = NoCopy; + | - move occurs because `x` has type `NoCopy`, which does not implement the `Copy` trait +LL | +LL | let f = move || { + | ------- value moved into closure here +LL | +LL | let y = x; + | - variable moved due to use in closure +... +LL | let z = x; + | ^ value used here after move + | +note: if `NoCopy` implemented `Clone`, you could clone the value + --> $DIR/closure-move-use-after-move-diagnostic.rs:2:1 + | +LL | struct NoCopy; + | ^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let y = x; + | - you could clone this value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/closures/closure-upvar-trait-caching.rs b/tests/ui/closures/closure-upvar-trait-caching.rs new file mode 100644 index 000000000000..82588631c99c --- /dev/null +++ b/tests/ui/closures/closure-upvar-trait-caching.rs @@ -0,0 +1,15 @@ +//@ run-pass +#![allow(path_statements)] +#![allow(unused_variables)] +// Regression test for issue #19499. Due to incorrect caching of trait +// results for closures with upvars whose types were not fully +// computed, this rather bizarre little program (along with many more +// reasonable examples) let to ambiguity errors about not being able +// to infer sufficient type information. + +fn main() { + let n = 0; + let it = Some(1_usize).into_iter().inspect(|_| { + n; + }); +} diff --git a/tests/ui/closures/issue-111932.stderr b/tests/ui/closures/issue-111932.stderr index fc3b7b0c6e66..2d10a2657aa0 100644 --- a/tests/ui/closures/issue-111932.stderr +++ b/tests/ui/closures/issue-111932.stderr @@ -17,7 +17,6 @@ LL | println!("{:?}", foo); | required by this formatting parameter | = help: the trait `Sized` is not implemented for `dyn Foo` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/closures/issue-90871.stderr b/tests/ui/closures/issue-90871.stderr index 071694def413..140f24982140 100644 --- a/tests/ui/closures/issue-90871.stderr +++ b/tests/ui/closures/issue-90871.stderr @@ -2,11 +2,15 @@ error[E0425]: cannot find type `n` in this scope --> $DIR/issue-90871.rs:4:22 | LL | type_ascribe!(2, n([u8; || 1])) - | ^ help: a trait with a similar name exists: `Fn` + | ^ | --> $SRC_DIR/core/src/ops/function.rs:LL:COL | = note: similarly named trait `Fn` defined here +help: a trait with a similar name exists + | +LL | type_ascribe!(2, Fn([u8; || 1])) + | + error[E0308]: mismatched types --> $DIR/issue-90871.rs:4:29 diff --git a/tests/ui/closures/local-enums-in-closure-2074.rs b/tests/ui/closures/local-enums-in-closure-2074.rs new file mode 100644 index 000000000000..29cd6f13e3bb --- /dev/null +++ b/tests/ui/closures/local-enums-in-closure-2074.rs @@ -0,0 +1,22 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/2074 + +//@ run-pass + +#![allow(non_camel_case_types)] + +pub fn main() { + let one = || { + enum r { + a, + } + r::a as usize + }; + let two = || { + enum r { + a, + } + r::a as usize + }; + one(); + two(); +} diff --git a/tests/ui/closures/malformed-pattern-issue-140011.rs b/tests/ui/closures/malformed-pattern-issue-140011.rs new file mode 100644 index 000000000000..18061613e988 --- /dev/null +++ b/tests/ui/closures/malformed-pattern-issue-140011.rs @@ -0,0 +1,13 @@ +//@compile-flags: -Wrust-2021-incompatible-closure-captures +enum B { + C(D), //~ ERROR: cannot find type `D` in this scope + E(F), +} +struct F; +fn f(h: B) { + || { + let B::E(a) = h; //~ ERROR: refutable pattern in local binding + }; +} + +fn main() {} diff --git a/tests/ui/closures/malformed-pattern-issue-140011.stderr b/tests/ui/closures/malformed-pattern-issue-140011.stderr new file mode 100644 index 000000000000..43beb7c58632 --- /dev/null +++ b/tests/ui/closures/malformed-pattern-issue-140011.stderr @@ -0,0 +1,36 @@ +error[E0425]: cannot find type `D` in this scope + --> $DIR/malformed-pattern-issue-140011.rs:3:7 + | +LL | C(D), + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | enum B { + | +++ + +error[E0005]: refutable pattern in local binding + --> $DIR/malformed-pattern-issue-140011.rs:9:13 + | +LL | let B::E(a) = h; + | ^^^^^^^ pattern `B::C(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html +note: `B` defined here + --> $DIR/malformed-pattern-issue-140011.rs:2:6 + | +LL | enum B { + | ^ +LL | C(D), + | - not covered + = note: the matched value is of type `B` +help: you might want to use `let...else` to handle the variant that isn't matched + | +LL | let B::E(a) = h else { todo!() }; + | ++++++++++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0005, E0425. +For more information about an error, try `rustc --explain E0005`. diff --git a/tests/ui/closures/multiple-fn-bounds.stderr b/tests/ui/closures/multiple-fn-bounds.stderr index 9b824fa0eefb..c99cbac01faf 100644 --- a/tests/ui/closures/multiple-fn-bounds.stderr +++ b/tests/ui/closures/multiple-fn-bounds.stderr @@ -19,11 +19,6 @@ note: required by a bound in `foo` | LL | fn foo bool + Fn(char) -> bool>(f: F) { | ^^^^^^^^^^^^^^^^ required by this bound in `foo` -help: consider adjusting the signature so it does not borrow its argument - | -LL - foo(move |x| v); -LL + foo(move |char| v); - | error: aborting due to 1 previous error diff --git a/tests/ui/closures/nested-closure-call.rs b/tests/ui/closures/nested-closure-call.rs new file mode 100644 index 000000000000..9d0860167a1a --- /dev/null +++ b/tests/ui/closures/nested-closure-call.rs @@ -0,0 +1,5 @@ +//! regression test for https://github.com/rust-lang/rust/issues/24779 +//@ run-pass +fn main() { + assert_eq!((|| || 42)()(), 42); +} diff --git a/tests/ui/closures/nested-closure-escape-borrow.rs b/tests/ui/closures/nested-closure-escape-borrow.rs new file mode 100644 index 000000000000..afd440ba4250 --- /dev/null +++ b/tests/ui/closures/nested-closure-escape-borrow.rs @@ -0,0 +1,10 @@ +//! regression test for +fn main() { + let mut x = 0; + || { + || { + //~^ ERROR captured variable cannot escape `FnMut` closure body + let _y = &mut x; + } + }; +} diff --git a/tests/ui/closures/nested-closure-escape-borrow.stderr b/tests/ui/closures/nested-closure-escape-borrow.stderr new file mode 100644 index 000000000000..5a77652fa376 --- /dev/null +++ b/tests/ui/closures/nested-closure-escape-borrow.stderr @@ -0,0 +1,23 @@ +error: captured variable cannot escape `FnMut` closure body + --> $DIR/nested-closure-escape-borrow.rs:5:9 + | +LL | let mut x = 0; + | ----- variable defined here +LL | || { + | - inferred to be a `FnMut` closure +LL | / || { +LL | | +LL | | let _y = &mut x; + | | - variable captured here +LL | | } + | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body + | + = note: `FnMut` closures only have access to their captured variables while they are executing... + = note: ...therefore, they cannot allow references to captured variables to escape +help: consider adding 'move' keyword before the nested closure + | +LL | move || { + | ++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/closures/or-patterns-issue-137467.rs b/tests/ui/closures/or-patterns-issue-137467.rs new file mode 100644 index 000000000000..de2a4beeaf9d --- /dev/null +++ b/tests/ui/closures/or-patterns-issue-137467.rs @@ -0,0 +1,113 @@ +//@ edition:2024 +//@ check-pass + +const X: u32 = 0; + +fn match_literal(x: (u32, u32, u32)) { + let _ = || { + let ((0, a, _) | (_, _, a)) = x; + a + }; +} + +fn match_range(x: (u32, u32, u32)) { + let _ = || { + let ((0..5, a, _) | (_, _, a)) = x; + a + }; +} + +fn match_const(x: (u32, u32, u32)) { + let _ = || { + let ((X, a, _) | (_, _, a)) = x; + a + }; +} + +// related testcase reported in #138973 +fn without_bindings(x: u32) { + let _ = || { + let (0 | _) = x; + }; +} + +enum Choice { A, B } + +fn match_unit_variant(x: (Choice, u32, u32)) { + let _ = || { + let ((Choice::A, a, _) | (Choice::B, _, a)) = x; + a + }; +} + +enum TEnum { + A(u32), + B(u32), +} + +enum SEnum { + A { a: u32 }, + B { a: u32 }, +} + +fn match_tuple_enum(x: TEnum) { + let _ = || { + let (TEnum::A(a) | TEnum::B(a)) = x; + a + }; +} + +fn match_struct_enum(x: SEnum) { + let _ = || { + let (SEnum::A { a } | SEnum::B { a }) = x; + a + }; +} + +enum TSingle { + A(u32, u32), +} + +enum SSingle { + A { a: u32, b: u32 }, +} + +struct TStruct(u32, u32); +struct SStruct { a: u32, b: u32 } + +fn match_slice(x: (&[u32], u32, u32)) { + let _ = || { + let (([], a, _) | ([_, ..], _, a)) = x; + a + }; +} + +// Original testcase, for completeness +enum Camera { + Normal { base_transform: i32 }, + Volume { transform: i32 }, +} + +fn draw_ui(camera: &mut Camera) { + || { + let (Camera::Normal { + base_transform: _transform, + } + | Camera::Volume { + transform: _transform, + }) = camera; + }; +} + +fn draw_ui2(camera: &mut Camera) { + || { + let (Camera::Normal { + base_transform: _, + } + | Camera::Volume { + transform: _, + }) = camera; + }; +} + +fn main() {} diff --git a/tests/ui/closures/simple-capture-and-call.rs b/tests/ui/closures/simple-capture-and-call.rs new file mode 100644 index 000000000000..112324eb7204 --- /dev/null +++ b/tests/ui/closures/simple-capture-and-call.rs @@ -0,0 +1,8 @@ +//! regression test for issue #1895 +//@ run-pass + +fn main() { + let x = 1_usize; + let y = || x; + let _z = y(); +} diff --git a/tests/ui/closures/unsized_value_move.rs b/tests/ui/closures/unsized_value_move.rs new file mode 100644 index 000000000000..da39cc0f35f4 --- /dev/null +++ b/tests/ui/closures/unsized_value_move.rs @@ -0,0 +1,8 @@ +//! regression test for +// Test that moves of unsized values within closures are caught +// and rejected. + +fn main() { + (|| Box::new(*(&[0][..])))(); + //~^ ERROR the size for values of type +} diff --git a/tests/ui/closures/unsized_value_move.stderr b/tests/ui/closures/unsized_value_move.stderr new file mode 100644 index 000000000000..a9a26a42d167 --- /dev/null +++ b/tests/ui/closures/unsized_value_move.stderr @@ -0,0 +1,20 @@ +error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time + --> $DIR/unsized_value_move.rs:6:18 + | +LL | (|| Box::new(*(&[0][..])))(); + | -------- ^^^^^^^^^^^ doesn't have a size known at compile-time + | | + | required by a bound introduced by this call + | + = help: the trait `Sized` is not implemented for `[{integer}]` +note: required by a bound in `Box::::new` + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL +help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression + | +LL - (|| Box::new(*(&[0][..])))(); +LL + (|| Box::new((&[0][..])))(); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs index fc5db3cd7543..7cf63352234d 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr index a3848182ef14..64dbcd42033d 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr @@ -1,11 +1,11 @@ error: function pointer types may not have generic parameters - --> $DIR/generics.rs:14:40 + --> $DIR/generics.rs:15:40 | LL | f1: extern "cmse-nonsecure-call" fn(U, u32, u32, u32) -> u64, | ^^^^^^^^^ error[E0425]: cannot find type `U` in this scope - --> $DIR/generics.rs:14:50 + --> $DIR/generics.rs:15:50 | LL | struct Test { | - similarly named type parameter `T` defined here @@ -23,7 +23,7 @@ LL | struct Test { | +++ error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters - --> $DIR/generics.rs:17:41 + --> $DIR/generics.rs:18:41 | LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl Copy, | ^^^^^^^^^ @@ -31,7 +31,7 @@ LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl C = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer return types - --> $DIR/generics.rs:17:70 + --> $DIR/generics.rs:18:70 | LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl Copy, | ^^^^^^^^^ @@ -39,7 +39,7 @@ LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl C = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters - --> $DIR/generics.rs:20:42 + --> $DIR/generics.rs:21:42 | LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> (impl Copy, u32), | ^^^^^^^^^ @@ -47,7 +47,7 @@ LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0562]: `impl Trait` is not allowed in `fn` pointer return types - --> $DIR/generics.rs:20:78 + --> $DIR/generics.rs:21:78 | LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> (impl Copy, u32), | ^^^^^^^^^ @@ -55,19 +55,19 @@ LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures - --> $DIR/generics.rs:23:41 + --> $DIR/generics.rs:24:41 | LL | f4: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures - --> $DIR/generics.rs:24:41 + --> $DIR/generics.rs:25:41 | LL | f5: extern "cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:30:71 + --> $DIR/generics.rs:31:71 | LL | type WithTraitObject = extern "cmse-nonsecure-call" fn(&dyn Trait) -> &dyn Trait; | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -76,7 +76,7 @@ LL | type WithTraitObject = extern "cmse-nonsecure-call" fn(&dyn Trait) -> &dyn = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:34:60 + --> $DIR/generics.rs:35:60 | LL | extern "cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Trait; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -85,7 +85,7 @@ LL | extern "cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Tra = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:41:60 + --> $DIR/generics.rs:42:60 | LL | extern "cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTransparent; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -94,7 +94,7 @@ LL | extern "cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspare = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0045]: C-variadic functions with the "cmse-nonsecure-call" calling convention are not supported - --> $DIR/generics.rs:44:20 + --> $DIR/generics.rs:45:20 | LL | type WithVarArgs = extern "cmse-nonsecure-call" fn(u32, ...); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs index 3452dc268e59..231a21cd874b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr index aab314c1ff25..398236b089b4 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/infer.stderr @@ -1,23 +1,23 @@ error[E0282]: type annotations needed - --> $DIR/infer.rs:16:13 + --> $DIR/infer.rs:17:13 | LL | let _ = mem::transmute:: _, extern "cmse-nonsecure-call" fn() -> _>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:21:13 + --> $DIR/infer.rs:22:13 | LL | let _ = mem::transmute:: (i32, _), extern "cmse-nonsecure-call" fn() -> (i32, _)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:26:13 + --> $DIR/infer.rs:27:13 | LL | let _ = mem::transmute:: (), extern "cmse-nonsecure-call" fn(_: _) -> ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:32:9 + --> $DIR/infer.rs:33:9 | LL | mem::transmute:: (), extern "cmse-nonsecure-call" fn(_: (i32, _)) -> ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs index e35138bf7cb8..8896235614e3 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr index 5a059e4df7b1..a3201844035c 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:16:64 + --> $DIR/params-via-stack.rs:17:64 | LL | f1: extern "cmse-nonsecure-call" fn(u32, u32, u32, u32, x: u32, y: u32), | ^^^ ^^^ does not fit in the available registers @@ -9,7 +9,7 @@ LL | f1: extern "cmse-nonsecure-call" fn(u32, u32, u32, u32, x: u32, y: u32) = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:17:61 + --> $DIR/params-via-stack.rs:18:61 | LL | f2: extern "cmse-nonsecure-call" fn(u32, u32, u32, u16, u16), | ^^^ does not fit in the available registers @@ -17,7 +17,7 @@ LL | f2: extern "cmse-nonsecure-call" fn(u32, u32, u32, u16, u16), = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:18:51 + --> $DIR/params-via-stack.rs:19:51 | LL | f3: extern "cmse-nonsecure-call" fn(u32, u64, u32), | ^^^ does not fit in the available registers @@ -25,7 +25,7 @@ LL | f3: extern "cmse-nonsecure-call" fn(u32, u64, u32), = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:19:56 + --> $DIR/params-via-stack.rs:20:56 | LL | f4: extern "cmse-nonsecure-call" fn(AlignRelevant, u32), | ^^^ does not fit in the available registers @@ -33,7 +33,7 @@ LL | f4: extern "cmse-nonsecure-call" fn(AlignRelevant, u32), = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:20:41 + --> $DIR/params-via-stack.rs:21:41 | LL | f5: extern "cmse-nonsecure-call" fn([u32; 5]), | ^^^^^^^^ does not fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs index b9d9fc92c8e2..55160f7a0f00 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm //@ add-minicore +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items)] #![no_core] @@ -12,6 +13,9 @@ use minicore::*; #[repr(C)] pub struct ReprCU64(u64); +#[repr(Rust)] +pub struct ReprRustU64(u64); + #[repr(C)] pub struct ReprCBytes(u8, u8, u8, u8, u8); @@ -24,10 +28,11 @@ pub struct ReprCAlign16(u16); #[no_mangle] pub fn test( f1: extern "cmse-nonsecure-call" fn() -> ReprCU64, //~ ERROR [E0798] - f2: extern "cmse-nonsecure-call" fn() -> ReprCBytes, //~ ERROR [E0798] - f3: extern "cmse-nonsecure-call" fn() -> U64Compound, //~ ERROR [E0798] - f4: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, //~ ERROR [E0798] - f5: extern "cmse-nonsecure-call" fn() -> [u8; 5], //~ ERROR [E0798] + f2: extern "cmse-nonsecure-call" fn() -> ReprRustU64, //~ ERROR [E0798] + f3: extern "cmse-nonsecure-call" fn() -> ReprCBytes, //~ ERROR [E0798] + f4: extern "cmse-nonsecure-call" fn() -> U64Compound, //~ ERROR [E0798] + f5: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, //~ ERROR [E0798] + f6: extern "cmse-nonsecure-call" fn() -> [u8; 5], //~ ERROR [E0798] ) { } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr index ddf969c1bce1..6b7446abc8eb 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/return-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:36:48 + --> $DIR/return-via-stack.rs:41:48 | LL | u128: extern "cmse-nonsecure-call" fn() -> u128, | ^^^^ this type doesn't fit in the available registers @@ -8,7 +8,7 @@ LL | u128: extern "cmse-nonsecure-call" fn() -> u128, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:37:48 + --> $DIR/return-via-stack.rs:42:48 | LL | i128: extern "cmse-nonsecure-call" fn() -> i128, | ^^^^ this type doesn't fit in the available registers @@ -17,7 +17,7 @@ LL | i128: extern "cmse-nonsecure-call" fn() -> i128, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:26:46 + --> $DIR/return-via-stack.rs:30:46 | LL | f1: extern "cmse-nonsecure-call" fn() -> ReprCU64, | ^^^^^^^^ this type doesn't fit in the available registers @@ -26,43 +26,52 @@ LL | f1: extern "cmse-nonsecure-call" fn() -> ReprCU64, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:27:46 + --> $DIR/return-via-stack.rs:31:46 | -LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCBytes, - | ^^^^^^^^^^ this type doesn't fit in the available registers - | - = note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers - = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size - -error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:28:46 - | -LL | f3: extern "cmse-nonsecure-call" fn() -> U64Compound, +LL | f2: extern "cmse-nonsecure-call" fn() -> ReprRustU64, | ^^^^^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:29:46 + --> $DIR/return-via-stack.rs:32:46 | -LL | f4: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, +LL | f3: extern "cmse-nonsecure-call" fn() -> ReprCBytes, + | ^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers + --> $DIR/return-via-stack.rs:33:46 + | +LL | f4: extern "cmse-nonsecure-call" fn() -> U64Compound, + | ^^^^^^^^^^^ this type doesn't fit in the available registers + | + = note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers + = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size + +error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers + --> $DIR/return-via-stack.rs:34:46 + | +LL | f5: extern "cmse-nonsecure-call" fn() -> ReprCAlign16, | ^^^^^^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:30:46 + --> $DIR/return-via-stack.rs:35:46 | -LL | f5: extern "cmse-nonsecure-call" fn() -> [u8; 5], +LL | f6: extern "cmse-nonsecure-call" fn() -> [u8; 5], | ^^^^^^^ this type doesn't fit in the available registers | = note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:52:46 + --> $DIR/return-via-stack.rs:57:46 | LL | f1: extern "cmse-nonsecure-call" fn() -> ReprRustUnionU64, | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,7 +80,7 @@ LL | f1: extern "cmse-nonsecure-call" fn() -> ReprRustUnionU64, = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/return-via-stack.rs:53:46 + --> $DIR/return-via-stack.rs:58:46 | LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCUnionU64, | ^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -79,6 +88,6 @@ LL | f2: extern "cmse-nonsecure-call" fn() -> ReprCUnionU64, = note: functions with the `"cmse-nonsecure-call"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs index 1ed5df459c7b..2d6b71502fce 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ incremental (required to trigger the bug) //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr index 7300bdb72cdd..99255e9f22b1 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/undeclared-lifetime.rs:15:43 + --> $DIR/undeclared-lifetime.rs:16:43 | LL | id::(PhantomData); | ^^ undeclared lifetime diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs index db9a51969a9f..5528865fc840 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/via-registers.rs @@ -2,6 +2,7 @@ //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, no_core, lang_items, intrinsics)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs index 290688f8ed95..8bbce0d7948b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, lang_items, no_core)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr index b9cccecc64bf..2ed3a6569719 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-1.stderr @@ -1,5 +1,5 @@ error[E0781]: the `"cmse-nonsecure-call"` ABI is only allowed on function pointers - --> $DIR/wrong-abi-location-1.rs:10:1 + --> $DIR/wrong-abi-location-1.rs:11:1 | LL | pub extern "cmse-nonsecure-call" fn test() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs index f23677e1ed71..3f99dcbdbb46 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, lang_items, no_core)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr index 437d7b80b1fd..0fe8341b8d7d 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/wrong-abi-location-2.stderr @@ -1,5 +1,5 @@ error[E0781]: the `"cmse-nonsecure-call"` ABI is only allowed on function pointers - --> $DIR/wrong-abi-location-2.rs:10:1 + --> $DIR/wrong-abi-location-2.rs:11:1 | LL | / extern "cmse-nonsecure-call" { LL | | fn test(); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs index d4a6c1fa07c1..213b69b6fa20 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs @@ -2,6 +2,7 @@ //@ edition: 2018 //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr index 5b0924d6f2af..2a2d769c7cf8 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr @@ -1,5 +1,5 @@ error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions - --> $DIR/c-variadic.rs:14:60 + --> $DIR/c-variadic.rs:15:60 | LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { | ----------------------------- ^^^^^^ @@ -9,13 +9,13 @@ LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: functions cannot be both `async` and C-variadic - --> $DIR/c-variadic.rs:19:1 + --> $DIR/c-variadic.rs:20:1 | LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { | ^^^^^ `async` because of this ^^^^^^ C-variadic because of this error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions - --> $DIR/c-variadic.rs:19:68 + --> $DIR/c-variadic.rs:20:68 | LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { | ----------------------------- ^^^^^^ @@ -25,10 +25,10 @@ LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/c-variadic.rs:25:1 + --> $DIR/c-variadic.rs:26:69 | LL | async unsafe extern "cmse-nonsecure-entry" fn async_is_not_allowed() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ error: aborting due to 4 previous errors diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index 023f50d636bf..bcae7f0c47f1 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index 5ddd29883f86..653e8f73012b 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,53 +1,53 @@ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:31:8 + --> $DIR/generics.rs:32:8 | LL | _: U, | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:64:48 + --> $DIR/generics.rs:65:48 | LL | extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { | ^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:79:57 + --> $DIR/generics.rs:80:57 | LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { | ^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:79:71 + --> $DIR/generics.rs:80:71 | LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { | ^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:86:8 + --> $DIR/generics.rs:87:8 | LL | v: (impl Copy, i32), | ^^^^^^^^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:88:6 + --> $DIR/generics.rs:89:6 | LL | ) -> (impl Copy, i32) { | ^^^^^^^^^^^^^^^^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:14:57 + --> $DIR/generics.rs:15:57 | LL | extern "cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 { | ^ error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:20:12 + --> $DIR/generics.rs:21:12 | LL | _: Wrapper, | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:46:65 + --> $DIR/generics.rs:47:65 | LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -56,7 +56,7 @@ LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:51:80 + --> $DIR/generics.rs:52:80 | LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) -> &'static dyn Trait { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -65,7 +65,7 @@ LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:59:81 + --> $DIR/generics.rs:60:81 | LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> WrapperTransparent { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -74,13 +74,13 @@ LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:69:57 + --> $DIR/generics.rs:70:57 | LL | extern "cmse-nonsecure-entry" fn return_impl_trait() -> impl Copy { | ^^^^^^^^^ error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures - --> $DIR/generics.rs:74:64 + --> $DIR/generics.rs:75:64 | LL | extern "cmse-nonsecure-entry" fn return_impl_trait_nested() -> (impl Copy, i32) { | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs index 75a08ff40356..ceb09c8ad6f7 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr index 4243771c3e67..f9352a8a2fbf 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/infer.stderr @@ -1,23 +1,23 @@ error[E0282]: type annotations needed - --> $DIR/infer.rs:16:13 + --> $DIR/infer.rs:17:13 | LL | let _ = mem::transmute:: _, extern "cmse-nonsecure-entry" fn() -> _>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:21:13 + --> $DIR/infer.rs:22:13 | LL | let _ = mem::transmute:: (i32, _), extern "cmse-nonsecure-entry" fn() -> (i32, _)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:26:13 + --> $DIR/infer.rs:27:13 | LL | let _ = mem::transmute:: (), extern "cmse-nonsecure-entry" fn(_: _) -> ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Src` declared on the function `transmute` error[E0282]: type annotations needed - --> $DIR/infer.rs:31:13 + --> $DIR/infer.rs:32:13 | LL | let _ = mem::transmute::< | _____________^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs index 5326dd5765f1..2e73ef8c32f5 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] @@ -23,3 +24,24 @@ pub extern "cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} //~ ERROR [ #[no_mangle] #[allow(improper_ctypes_definitions)] pub extern "cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} //~ ERROR [E0798] + +struct Four { + a: u32, + b: u32, + c: u32, + d: u32, +} + +struct Five { + a: u32, + b: u32, + c: u32, + d: u32, + e: u32, +} + +#[no_mangle] +pub extern "cmse-nonsecure-entry" fn four(_: Four) {} + +#[no_mangle] +pub extern "cmse-nonsecure-entry" fn five(_: Five) {} //~ ERROR [E0798] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr index 3d523fc7be67..c17cf50a6139 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:15:76 + --> $DIR/params-via-stack.rs:16:76 | LL | pub extern "cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} | ^^^ ^^^ does not fit in the available registers @@ -9,7 +9,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:17:76 + --> $DIR/params-via-stack.rs:18:76 | LL | pub extern "cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} | ^^^ does not fit in the available registers @@ -17,7 +17,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:19:60 + --> $DIR/params-via-stack.rs:20:60 | LL | pub extern "cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} | ^^^ does not fit in the available registers @@ -25,7 +25,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:21:62 + --> $DIR/params-via-stack.rs:22:62 | LL | pub extern "cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} | ^^^ does not fit in the available registers @@ -33,13 +33,21 @@ LL | pub extern "cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/params-via-stack.rs:25:44 + --> $DIR/params-via-stack.rs:26:44 | LL | pub extern "cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} | ^^^^^^^^ does not fit in the available registers | = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers -error: aborting due to 5 previous errors +error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers + --> $DIR/params-via-stack.rs:47:46 + | +LL | pub extern "cmse-nonsecure-entry" fn five(_: Five) {} + | ^^^^ does not fit in the available registers + | + = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs index 19abd1740e65..bfc8ad458359 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.rs @@ -1,6 +1,7 @@ //@ add-minicore //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr index 07ee31bef23c..c5effed92ae9 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/return-via-stack.stderr @@ -1,5 +1,5 @@ error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:24:46 + --> $DIR/return-via-stack.rs:25:46 | LL | pub extern "cmse-nonsecure-entry" fn f1() -> ReprCU64 { | ^^^^^^^^ this type doesn't fit in the available registers @@ -8,7 +8,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f1() -> ReprCU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:29:46 + --> $DIR/return-via-stack.rs:30:46 | LL | pub extern "cmse-nonsecure-entry" fn f2() -> ReprCBytes { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -17,7 +17,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f2() -> ReprCBytes { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:34:46 + --> $DIR/return-via-stack.rs:35:46 | LL | pub extern "cmse-nonsecure-entry" fn f3() -> U64Compound { | ^^^^^^^^^^^ this type doesn't fit in the available registers @@ -26,7 +26,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f3() -> U64Compound { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:39:46 + --> $DIR/return-via-stack.rs:40:46 | LL | pub extern "cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { | ^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -35,7 +35,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f4() -> ReprCAlign16 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:46:46 + --> $DIR/return-via-stack.rs:47:46 | LL | pub extern "cmse-nonsecure-entry" fn f5() -> [u8; 5] { | ^^^^^^^ this type doesn't fit in the available registers @@ -44,7 +44,7 @@ LL | pub extern "cmse-nonsecure-entry" fn f5() -> [u8; 5] { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:52:48 + --> $DIR/return-via-stack.rs:53:48 | LL | pub extern "cmse-nonsecure-entry" fn u128() -> u128 { | ^^^^ this type doesn't fit in the available registers @@ -53,7 +53,7 @@ LL | pub extern "cmse-nonsecure-entry" fn u128() -> u128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:58:48 + --> $DIR/return-via-stack.rs:59:48 | LL | pub extern "cmse-nonsecure-entry" fn i128() -> i128 { | ^^^^ this type doesn't fit in the available registers @@ -62,7 +62,7 @@ LL | pub extern "cmse-nonsecure-entry" fn i128() -> i128 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:75:54 + --> $DIR/return-via-stack.rs:76:54 | LL | pub extern "cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { | ^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,7 +71,7 @@ LL | pub extern "cmse-nonsecure-entry" fn union_rust() -> ReprRustUnionU64 { = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/return-via-stack.rs:80:51 + --> $DIR/return-via-stack.rs:81:51 | LL | pub extern "cmse-nonsecure-entry" fn union_c() -> ReprCUnionU64 { | ^^^^^^^^^^^^^ this type doesn't fit in the available registers diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs index 0a6565e37fc7..756cc6816acd 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs @@ -40,9 +40,15 @@ pub extern "cmse-nonsecure-entry" fn inputs5(_: f64, _: f32, _: f32) {} #[no_mangle] pub extern "cmse-nonsecure-entry" fn inputs6(_: ReprTransparentStruct, _: U32Compound) {} #[no_mangle] -#[allow(improper_ctypes_definitions)] +#[expect(improper_ctypes_definitions)] pub extern "cmse-nonsecure-entry" fn inputs7(_: [u32; 4]) {} +// With zero-sized types we can actually have more than 4 arguments. +#[expect(improper_ctypes_definitions)] +pub extern "cmse-nonsecure-entry" fn inputs8(_: (), _: (), _: (), _: (), _: ()) {} +#[expect(improper_ctypes_definitions)] +pub extern "cmse-nonsecure-entry" fn inputs9(_: (), _: (), _: (), _: (), _: ()) {} + #[no_mangle] pub extern "cmse-nonsecure-entry" fn outputs1() -> u32 { 0 @@ -69,8 +75,8 @@ pub extern "cmse-nonsecure-entry" fn outputs6() -> ReprTransparentStruct { ReprTransparentStruct { _marker1: (), _marker2: (), field: 0xAA, _marker3: () } } #[no_mangle] -pub extern "cmse-nonsecure-entry" fn outputs7( -) -> ReprTransparentStruct> { +pub extern "cmse-nonsecure-entry" fn outputs7() -> ReprTransparentStruct> +{ ReprTransparentStruct { _marker1: (), _marker2: (), diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-137823.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.rs new file mode 100644 index 000000000000..4ae8d84eba11 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.rs @@ -0,0 +1,39 @@ +//@ build-fail + +// Regression test for issue #137823 +// Tests that recursive monomorphization with associated types produces +// a proper "recursion limit" error instead of an ICE. + +fn convert() -> S::Out { + convert2::>() + //~^ ERROR: reached the recursion limit while instantiating +} + +fn convert2() -> S::Out { + convert::() +} + +fn main() { + convert::(); +} + +trait Converter { + type Out; +} + +struct Ser; + +impl Converter for Ser { + type Out = (); +} + +struct ConvertWrap { + _d: S, +} + +impl Converter for ConvertWrap +where + S: Converter, +{ + type Out = S::Out; +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-137823.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.stderr new file mode 100644 index 000000000000..3d80c45685f5 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-137823.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `convert2::>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` + --> $DIR/recursion-issue-137823.rs:8:5 + | +LL | convert2::>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `convert2` defined here + --> $DIR/recursion-issue-137823.rs:12:1 + | +LL | fn convert2() -> S::Out { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/codemap_tests/bad-format-args.stderr b/tests/ui/codemap_tests/bad-format-args.stderr index 8f79beaa9e1b..ef0fa5f481e5 100644 --- a/tests/ui/codemap_tests/bad-format-args.stderr +++ b/tests/ui/codemap_tests/bad-format-args.stderr @@ -3,8 +3,6 @@ error: requires at least a format string argument | LL | format!(); | ^^^^^^^^^ - | - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected `,`, found `1` --> $DIR/bad-format-args.rs:3:16 diff --git a/tests/ui/codemap_tests/tab_3.stderr b/tests/ui/codemap_tests/tab_3.stderr index 7ae21a57052f..2a0a9e2d48f3 100644 --- a/tests/ui/codemap_tests/tab_3.stderr +++ b/tests/ui/codemap_tests/tab_3.stderr @@ -11,7 +11,6 @@ LL | println!("{:?}", some_vec); | note: `into_iter` takes ownership of the receiver `self`, which moves `some_vec` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: you can `clone` the value and consume it, but this might not be your desired behavior | LL | some_vec.clone().into_iter(); diff --git a/tests/ui/codemap_tests/unicode.expanded.stdout b/tests/ui/codemap_tests/unicode.expanded.stdout index af375108b478..4a29277fe3bf 100644 --- a/tests/ui/codemap_tests/unicode.expanded.stdout +++ b/tests/ui/codemap_tests/unicode.expanded.stdout @@ -1,6 +1,5 @@ #![feature(prelude_import)] #![no_std] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/coercion/closure-in-array.rs b/tests/ui/coercion/closure-in-array.rs new file mode 100644 index 000000000000..ca5c021c77a7 --- /dev/null +++ b/tests/ui/coercion/closure-in-array.rs @@ -0,0 +1,7 @@ +// Weakened closure sig inference by #140283. +fn foo usize, const N: usize>(x: [F; N]) {} + +fn main() { + foo([|s| s.len()]) + //~^ ERROR: type annotations needed +} diff --git a/tests/ui/coercion/closure-in-array.stderr b/tests/ui/coercion/closure-in-array.stderr new file mode 100644 index 000000000000..90cf590c09e7 --- /dev/null +++ b/tests/ui/coercion/closure-in-array.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed + --> $DIR/closure-in-array.rs:5:11 + | +LL | foo([|s| s.len()]) + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | foo([|s: /* Type */| s.len()]) + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/coercion/coerce-many-with-ty-var.rs b/tests/ui/coercion/coerce-many-with-ty-var.rs new file mode 100644 index 000000000000..cbd16f58ea5b --- /dev/null +++ b/tests/ui/coercion/coerce-many-with-ty-var.rs @@ -0,0 +1,36 @@ +//@ run-pass +// Check that least upper bound coercions don't resolve type variable merely based on the first +// coercion. Check issue #136420. + +fn foo() {} +fn bar() {} + +fn infer(_: T) {} + +fn infer_array_element(_: [T; 2]) {} + +fn main() { + // Previously the element type's ty var will be unified with `foo`. + let _: [_; 2] = [foo, bar]; + infer_array_element([foo, bar]); + + let _ = if false { + foo + } else { + bar + }; + infer(if false { + foo + } else { + bar + }); + + let _ = match false { + true => foo, + false => bar, + }; + infer(match false { + true => foo, + false => bar, + }); +} diff --git a/tests/ui/coercion/vec-macro-coercions.rs b/tests/ui/coercion/vec-macro-coercions.rs new file mode 100644 index 000000000000..f7dfd4324796 --- /dev/null +++ b/tests/ui/coercion/vec-macro-coercions.rs @@ -0,0 +1,12 @@ +//@ check-pass + +fn main() { + let functions = &vec![ + |x: i32| -> i32 { x + 3 }, + |x: i32| -> i32 { x + 3 }, + ]; + + let string = String::new(); + let a = vec![&string, "abc"]; + let b = vec!["abc", &string]; +} diff --git a/tests/ui/coherence/coherence-cow.rs b/tests/ui/coherence/coherence-cow.rs index af94964762a9..2fc33e3a3e8f 100644 --- a/tests/ui/coherence/coherence-cow.rs +++ b/tests/ui/coherence/coherence-cow.rs @@ -1,6 +1,6 @@ //@ revisions: re_a re_b re_c -#![cfg_attr(any(), re_a, re_b, re_c)] +#![cfg_attr(false, re_a, re_b, re_c)] //@ aux-build:coherence_lib.rs diff --git a/tests/ui/coherence/conflicting-impl-with-err.rs b/tests/ui/coherence/conflicting-impl-with-err.rs index 3e0234b874d7..49219b4c4a35 100644 --- a/tests/ui/coherence/conflicting-impl-with-err.rs +++ b/tests/ui/coherence/conflicting-impl-with-err.rs @@ -1,8 +1,8 @@ struct ErrorKind; struct Error(ErrorKind); -impl From for Error { //~ ERROR failed to resolve - fn from(_: nope::Thing) -> Self { //~ ERROR failed to resolve +impl From for Error { //~ ERROR cannot find + fn from(_: nope::Thing) -> Self { //~ ERROR cannot find unimplemented!() } } diff --git a/tests/ui/coherence/conflicting-impl-with-err.stderr b/tests/ui/coherence/conflicting-impl-with-err.stderr index 75a201797b55..706798bb0000 100644 --- a/tests/ui/coherence/conflicting-impl-with-err.stderr +++ b/tests/ui/coherence/conflicting-impl-with-err.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nope` +error[E0433]: cannot find module or crate `nope` in this scope --> $DIR/conflicting-impl-with-err.rs:4:11 | LL | impl From for Error { @@ -6,7 +6,7 @@ LL | impl From for Error { | = help: you might be missing a crate named `nope` -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `nope` +error[E0433]: cannot find module or crate `nope` in this scope --> $DIR/conflicting-impl-with-err.rs:5:16 | LL | fn from(_: nope::Thing) -> Self { diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs index c50bbcec5215..b754b1cb5472 100644 --- a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs +++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.rs @@ -3,7 +3,7 @@ use std::cmp::Ordering; use std::marker::PhantomData; #[derive(PartialEq, Default)] -//~^ ERROR conflicting implementations of trait `PartialEq>` for type `Interval<_>` +//~^ ERROR conflicting implementations of trait `PartialEq` for type `Interval<_>` pub(crate) struct Interval(PhantomData); // This impl overlaps with the `derive` unless we reject the nested diff --git a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr index a9a99fb28d84..620694aacf83 100644 --- a/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr +++ b/tests/ui/coherence/warn-when-cycle-is-error-in-coherence.stderr @@ -1,4 +1,4 @@ -error[E0119]: conflicting implementations of trait `PartialEq>` for type `Interval<_>` +error[E0119]: conflicting implementations of trait `PartialEq` for type `Interval<_>` --> $DIR/warn-when-cycle-is-error-in-coherence.rs:5:10 | LL | #[derive(PartialEq, Default)] diff --git a/tests/ui/btreemap/btreemap-index-mut-2.rs b/tests/ui/collections/btreemap/btreemap-index-mut-2.rs similarity index 100% rename from tests/ui/btreemap/btreemap-index-mut-2.rs rename to tests/ui/collections/btreemap/btreemap-index-mut-2.rs diff --git a/tests/ui/btreemap/btreemap-index-mut-2.stderr b/tests/ui/collections/btreemap/btreemap-index-mut-2.stderr similarity index 100% rename from tests/ui/btreemap/btreemap-index-mut-2.stderr rename to tests/ui/collections/btreemap/btreemap-index-mut-2.stderr diff --git a/tests/ui/btreemap/btreemap-index-mut.rs b/tests/ui/collections/btreemap/btreemap-index-mut.rs similarity index 100% rename from tests/ui/btreemap/btreemap-index-mut.rs rename to tests/ui/collections/btreemap/btreemap-index-mut.rs diff --git a/tests/ui/btreemap/btreemap-index-mut.stderr b/tests/ui/collections/btreemap/btreemap-index-mut.stderr similarity index 100% rename from tests/ui/btreemap/btreemap-index-mut.stderr rename to tests/ui/collections/btreemap/btreemap-index-mut.stderr diff --git a/tests/ui/btreemap/btreemap_dropck.rs b/tests/ui/collections/btreemap/btreemap_dropck.rs similarity index 100% rename from tests/ui/btreemap/btreemap_dropck.rs rename to tests/ui/collections/btreemap/btreemap_dropck.rs diff --git a/tests/ui/btreemap/btreemap_dropck.stderr b/tests/ui/collections/btreemap/btreemap_dropck.stderr similarity index 100% rename from tests/ui/btreemap/btreemap_dropck.stderr rename to tests/ui/collections/btreemap/btreemap_dropck.stderr diff --git a/tests/ui/btreemap/btreemap_into_iterator_lifetime.rs b/tests/ui/collections/btreemap/btreemap_into_iterator_lifetime.rs similarity index 100% rename from tests/ui/btreemap/btreemap_into_iterator_lifetime.rs rename to tests/ui/collections/btreemap/btreemap_into_iterator_lifetime.rs diff --git a/tests/ui/hashmap/hashmap-capacity-overflow.rs b/tests/ui/collections/hashmap/hashmap-capacity-overflow.rs similarity index 100% rename from tests/ui/hashmap/hashmap-capacity-overflow.rs rename to tests/ui/collections/hashmap/hashmap-capacity-overflow.rs diff --git a/tests/ui/hashmap/hashmap-index-mut.rs b/tests/ui/collections/hashmap/hashmap-index-mut.rs similarity index 100% rename from tests/ui/hashmap/hashmap-index-mut.rs rename to tests/ui/collections/hashmap/hashmap-index-mut.rs diff --git a/tests/ui/hashmap/hashmap-index-mut.stderr b/tests/ui/collections/hashmap/hashmap-index-mut.stderr similarity index 100% rename from tests/ui/hashmap/hashmap-index-mut.stderr rename to tests/ui/collections/hashmap/hashmap-index-mut.stderr diff --git a/tests/ui/hashmap/hashmap-iter-value-lifetime.rs b/tests/ui/collections/hashmap/hashmap-iter-value-lifetime.rs similarity index 100% rename from tests/ui/hashmap/hashmap-iter-value-lifetime.rs rename to tests/ui/collections/hashmap/hashmap-iter-value-lifetime.rs diff --git a/tests/ui/hashmap/hashmap-iter-value-lifetime.stderr b/tests/ui/collections/hashmap/hashmap-iter-value-lifetime.stderr similarity index 100% rename from tests/ui/hashmap/hashmap-iter-value-lifetime.stderr rename to tests/ui/collections/hashmap/hashmap-iter-value-lifetime.stderr diff --git a/tests/ui/hashmap/hashmap-lifetimes.rs b/tests/ui/collections/hashmap/hashmap-lifetimes.rs similarity index 100% rename from tests/ui/hashmap/hashmap-lifetimes.rs rename to tests/ui/collections/hashmap/hashmap-lifetimes.rs diff --git a/tests/ui/hashmap/hashmap-lifetimes.stderr b/tests/ui/collections/hashmap/hashmap-lifetimes.stderr similarity index 100% rename from tests/ui/hashmap/hashmap-lifetimes.stderr rename to tests/ui/collections/hashmap/hashmap-lifetimes.stderr diff --git a/tests/ui/hashmap/hashmap-memory.rs b/tests/ui/collections/hashmap/hashmap-memory.rs similarity index 100% rename from tests/ui/hashmap/hashmap-memory.rs rename to tests/ui/collections/hashmap/hashmap-memory.rs diff --git a/tests/ui/collections/hashmap/hashmap-path-key.rs b/tests/ui/collections/hashmap/hashmap-path-key.rs new file mode 100644 index 000000000000..0551ba7ea8ee --- /dev/null +++ b/tests/ui/collections/hashmap/hashmap-path-key.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ run-pass + +use std::collections::HashMap; +use std::path::Path; + +fn main() { + let mut map = HashMap::new(); + map.insert(Path::new("a"), 0); + map.get(Path::new("a")); +} diff --git a/tests/ui/hashmap/hashset-enum-variant.rs b/tests/ui/collections/hashmap/hashset-enum-variant.rs similarity index 100% rename from tests/ui/hashmap/hashset-enum-variant.rs rename to tests/ui/collections/hashmap/hashset-enum-variant.rs diff --git a/tests/ui/hashmap/hashset_generics.rs b/tests/ui/collections/hashmap/hashset_generics.rs similarity index 100% rename from tests/ui/hashmap/hashset_generics.rs rename to tests/ui/collections/hashmap/hashset_generics.rs diff --git a/tests/ui/hashmap/hashset_generics.stderr b/tests/ui/collections/hashmap/hashset_generics.stderr similarity index 100% rename from tests/ui/hashmap/hashset_generics.stderr rename to tests/ui/collections/hashmap/hashset_generics.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGS.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGS.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGSPC.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADFLAGSPC.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADTARGET.stderr b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADTARGET.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADTARGET.stderr rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.BADTARGET.stderr diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs b/tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.rs similarity index 100% rename from tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.rs rename to tests/ui/compile-flags/invalid/branch-protection-missing-pac-ret.rs diff --git a/tests/ui/invalid-compile-flags/codegen-option-without-group.rs b/tests/ui/compile-flags/invalid/codegen-option-without-group.rs similarity index 100% rename from tests/ui/invalid-compile-flags/codegen-option-without-group.rs rename to tests/ui/compile-flags/invalid/codegen-option-without-group.rs diff --git a/tests/ui/invalid-compile-flags/codegen-option-without-group.stderr b/tests/ui/compile-flags/invalid/codegen-option-without-group.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/codegen-option-without-group.stderr rename to tests/ui/compile-flags/invalid/codegen-option-without-group.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.empty_crate_type.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.empty_crate_type.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.empty_crate_type.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.proc_underscore_macro.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.proc_underscore_macro.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.proc_underscore_macro.stderr diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.rs b/tests/ui/compile-flags/invalid/crate-type-flag.rs similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.rs rename to tests/ui/compile-flags/invalid/crate-type-flag.rs diff --git a/tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr b/tests/ui/compile-flags/invalid/crate-type-flag.unknown.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/crate-type-flag.unknown.stderr rename to tests/ui/compile-flags/invalid/crate-type-flag.unknown.stderr diff --git a/tests/ui/invalid-compile-flags/debug-option-without-group.rs b/tests/ui/compile-flags/invalid/debug-option-without-group.rs similarity index 100% rename from tests/ui/invalid-compile-flags/debug-option-without-group.rs rename to tests/ui/compile-flags/invalid/debug-option-without-group.rs diff --git a/tests/ui/invalid-compile-flags/debug-option-without-group.stderr b/tests/ui/compile-flags/invalid/debug-option-without-group.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/debug-option-without-group.stderr rename to tests/ui/compile-flags/invalid/debug-option-without-group.stderr diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.rs b/tests/ui/compile-flags/invalid/emit-output-types-without-args.rs similarity index 100% rename from tests/ui/invalid-compile-flags/emit-output-types-without-args.rs rename to tests/ui/compile-flags/invalid/emit-output-types-without-args.rs diff --git a/tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr b/tests/ui/compile-flags/invalid/emit-output-types-without-args.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/emit-output-types-without-args.stderr rename to tests/ui/compile-flags/invalid/emit-output-types-without-args.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.aarch64.stderr b/tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.aarch64.stderr rename to tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs b/tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.rs similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs rename to tests/ui/compile-flags/invalid/function-return/requires-x86-or-x86_64.rs diff --git a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.large.stderr b/tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.large.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.large.stderr rename to tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.large.stderr diff --git a/tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs b/tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.rs similarity index 100% rename from tests/ui/invalid-compile-flags/function-return/thunk-extern-requires-non-large-code-model.rs rename to tests/ui/compile-flags/invalid/function-return/thunk-extern-requires-non-large-code-model.rs diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr b/tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr rename to tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs b/tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs similarity index 100% rename from tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs rename to tests/ui/compile-flags/invalid/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs diff --git a/tests/ui/invalid-compile-flags/invalid-llvm-passes.rs b/tests/ui/compile-flags/invalid/invalid-llvm-passes.rs similarity index 100% rename from tests/ui/invalid-compile-flags/invalid-llvm-passes.rs rename to tests/ui/compile-flags/invalid/invalid-llvm-passes.rs diff --git a/tests/ui/invalid-compile-flags/invalid-llvm-passes.stderr b/tests/ui/compile-flags/invalid/invalid-llvm-passes.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/invalid-llvm-passes.stderr rename to tests/ui/compile-flags/invalid/invalid-llvm-passes.stderr diff --git a/tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.rs b/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.rs similarity index 100% rename from tests/ui/invalid-compile-flags/need-crate-arg-ignore-tidy$x.rs rename to tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.rs diff --git a/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr b/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr new file mode 100644 index 000000000000..3c0c80eae90d --- /dev/null +++ b/tests/ui/compile-flags/invalid/need-crate-arg-ignore-tidy$x.stderr @@ -0,0 +1,4 @@ +error: invalid character '$' in crate name: `need_crate_arg_ignore_tidy$x` + +error: aborting due to 1 previous error + diff --git a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.rs b/tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.rs rename to tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.rs diff --git a/tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr b/tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-crate-name-request-malformed-crate-name.stderr rename to tests/ui/compile-flags/invalid/print-crate-name-request-malformed-crate-name.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-1.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-1.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name-2.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name-2.stderr diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.rs b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.rs rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.rs diff --git a/tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr b/tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-file-names-request-malformed-crate-name.stderr rename to tests/ui/compile-flags/invalid/print-file-names-request-malformed-crate-name.stderr diff --git a/tests/ui/invalid-compile-flags/print-without-arg.rs b/tests/ui/compile-flags/invalid/print-without-arg.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print-without-arg.rs rename to tests/ui/compile-flags/invalid/print-without-arg.rs diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/compile-flags/invalid/print-without-arg.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print-without-arg.stderr rename to tests/ui/compile-flags/invalid/print-without-arg.stderr diff --git a/tests/ui/invalid-compile-flags/print.rs b/tests/ui/compile-flags/invalid/print.rs similarity index 100% rename from tests/ui/invalid-compile-flags/print.rs rename to tests/ui/compile-flags/invalid/print.rs diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/compile-flags/invalid/print.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/print.stderr rename to tests/ui/compile-flags/invalid/print.stderr diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.aarch64.stderr b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.aarch64.stderr rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.rs similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.rs diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.x86_64.stderr b/tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.x86_64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.x86_64.stderr rename to tests/ui/compile-flags/invalid/reg-struct-return/requires-x86.x86_64.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr b/tests/ui/compile-flags/invalid/regparm/regparm-valid-values.regparm4.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/regparm-valid-values.regparm4.stderr rename to tests/ui/compile-flags/invalid/regparm/regparm-valid-values.regparm4.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs b/tests/ui/compile-flags/invalid/regparm/regparm-valid-values.rs similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs rename to tests/ui/compile-flags/invalid/regparm/regparm-valid-values.rs diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr b/tests/ui/compile-flags/invalid/regparm/requires-x86.aarch64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.aarch64.stderr rename to tests/ui/compile-flags/invalid/regparm/requires-x86.aarch64.stderr diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs b/tests/ui/compile-flags/invalid/regparm/requires-x86.rs similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.rs rename to tests/ui/compile-flags/invalid/regparm/requires-x86.rs diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr b/tests/ui/compile-flags/invalid/regparm/requires-x86.x86_64.stderr similarity index 100% rename from tests/ui/invalid-compile-flags/regparm/requires-x86.x86_64.stderr rename to tests/ui/compile-flags/invalid/regparm/requires-x86.x86_64.stderr diff --git a/tests/ui/compile-flags/invalid/remap-path-scope.foo.stderr b/tests/ui/compile-flags/invalid/remap-path-scope.foo.stderr new file mode 100644 index 000000000000..dc72089e0d57 --- /dev/null +++ b/tests/ui/compile-flags/invalid/remap-path-scope.foo.stderr @@ -0,0 +1,2 @@ +error: argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all` + diff --git a/tests/ui/compile-flags/invalid/remap-path-scope.rs b/tests/ui/compile-flags/invalid/remap-path-scope.rs new file mode 100644 index 000000000000..545c8c86cec7 --- /dev/null +++ b/tests/ui/compile-flags/invalid/remap-path-scope.rs @@ -0,0 +1,9 @@ +// Error on invalid --remap-path-scope arguments + +//@ revisions: foo underscore +//@ [foo]compile-flags: --remap-path-scope=foo +//@ [underscore]compile-flags: --remap-path-scope=macro_object + +//~? ERROR argument for `--remap-path-scope + +fn main() {} diff --git a/tests/ui/compile-flags/invalid/remap-path-scope.underscore.stderr b/tests/ui/compile-flags/invalid/remap-path-scope.underscore.stderr new file mode 100644 index 000000000000..dc72089e0d57 --- /dev/null +++ b/tests/ui/compile-flags/invalid/remap-path-scope.underscore.stderr @@ -0,0 +1,2 @@ +error: argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all` + diff --git a/tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs b/tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs new file mode 100644 index 000000000000..d584ec9fd280 --- /dev/null +++ b/tests/ui/compile-flags/run-pass/repeated-debug-opt-flags.rs @@ -0,0 +1,10 @@ +//! regression test for https://github.com/rust-lang/rust/issues/24945 +//@ run-pass +// This test is just checking that we continue to accept `-g -g -O -O` +// as options to the compiler. + +//@ compile-flags:-g -g -O -O + +fn main() { + assert_eq!(1, 1); +} diff --git a/tests/ui/meta/auxiliary/env.rs b/tests/ui/compiletest-self-test/auxiliary/env.rs similarity index 100% rename from tests/ui/meta/auxiliary/env.rs rename to tests/ui/compiletest-self-test/auxiliary/env.rs diff --git a/tests/ui/compiletest-self-test/auxiliary/no_prefer_dynamic_lib.rs b/tests/ui/compiletest-self-test/auxiliary/no_prefer_dynamic_lib.rs new file mode 100644 index 000000000000..6688dadbab24 --- /dev/null +++ b/tests/ui/compiletest-self-test/auxiliary/no_prefer_dynamic_lib.rs @@ -0,0 +1,10 @@ +//@ no-prefer-dynamic + +//! Since this is `no-prefer-dynamic` we expect compiletest to _not_ look for +//! this create as `libno_prefer_dynamic_lib.so`. + +#![crate_type = "rlib"] + +pub fn return_42() -> i32 { + 42 +} diff --git a/tests/ui/meta/dir.with.dots/test.rs b/tests/ui/compiletest-self-test/dir.with.dots/test.rs similarity index 100% rename from tests/ui/meta/dir.with.dots/test.rs rename to tests/ui/compiletest-self-test/dir.with.dots/test.rs diff --git a/tests/ui/meta/expected-error-correct-rev.a.stderr b/tests/ui/compiletest-self-test/expected-error-correct-rev.a.stderr similarity index 100% rename from tests/ui/meta/expected-error-correct-rev.a.stderr rename to tests/ui/compiletest-self-test/expected-error-correct-rev.a.stderr diff --git a/tests/ui/meta/expected-error-correct-rev.rs b/tests/ui/compiletest-self-test/expected-error-correct-rev.rs similarity index 100% rename from tests/ui/meta/expected-error-correct-rev.rs rename to tests/ui/compiletest-self-test/expected-error-correct-rev.rs diff --git a/tests/ui/meta/meta-expected-error-wrong-rev.a.stderr b/tests/ui/compiletest-self-test/meta-expected-error-wrong-rev.a.stderr similarity index 100% rename from tests/ui/meta/meta-expected-error-wrong-rev.a.stderr rename to tests/ui/compiletest-self-test/meta-expected-error-wrong-rev.a.stderr diff --git a/tests/ui/meta/meta-expected-error-wrong-rev.rs b/tests/ui/compiletest-self-test/meta-expected-error-wrong-rev.rs similarity index 100% rename from tests/ui/meta/meta-expected-error-wrong-rev.rs rename to tests/ui/compiletest-self-test/meta-expected-error-wrong-rev.rs diff --git a/tests/ui/compiletest-self-test/no-prefer-dynamic-means-no-so.rs b/tests/ui/compiletest-self-test/no-prefer-dynamic-means-no-so.rs new file mode 100644 index 000000000000..b7e8fae506c3 --- /dev/null +++ b/tests/ui/compiletest-self-test/no-prefer-dynamic-means-no-so.rs @@ -0,0 +1,10 @@ +//! Since we and our `aux-crate` is `no-prefer-dynamic`, we expect compiletest +//! to _not_ look for `libno_prefer_dynamic_lib.so`. + +//@ check-pass +//@ no-prefer-dynamic +//@ aux-crate: no_prefer_dynamic_lib=no_prefer_dynamic_lib.rs + +fn main() { + no_prefer_dynamic_lib::return_42(); +} diff --git a/tests/ui/meta/revision-bad.rs b/tests/ui/compiletest-self-test/revision-bad.rs similarity index 100% rename from tests/ui/meta/revision-bad.rs rename to tests/ui/compiletest-self-test/revision-bad.rs diff --git a/tests/ui/meta/revision-ok.rs b/tests/ui/compiletest-self-test/revision-ok.rs similarity index 100% rename from tests/ui/meta/revision-ok.rs rename to tests/ui/compiletest-self-test/revision-ok.rs diff --git a/tests/ui/meta/rustc-env.rs b/tests/ui/compiletest-self-test/rustc-env.rs similarity index 100% rename from tests/ui/meta/rustc-env.rs rename to tests/ui/compiletest-self-test/rustc-env.rs diff --git a/tests/ui/compiletest-self-test/ui-testing-optout.rs b/tests/ui/compiletest-self-test/ui-testing-optout.rs index 62920a86c3b3..2f2bc54676a8 100644 --- a/tests/ui/compiletest-self-test/ui-testing-optout.rs +++ b/tests/ui/compiletest-self-test/ui-testing-optout.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Z ui-testing=no +//@ compile-flags: -Z ui-testing=no --diagnostic-width=80 // Line number < 10 type A = B; //~ ERROR diff --git a/tests/ui/compiletest-self-test/ui-testing-optout.stderr b/tests/ui/compiletest-self-test/ui-testing-optout.stderr index b0d495edfb62..6a4950c55afd 100644 --- a/tests/ui/compiletest-self-test/ui-testing-optout.stderr +++ b/tests/ui/compiletest-self-test/ui-testing-optout.stderr @@ -11,7 +11,13 @@ error[E0425]: cannot find type `D` in this scope | ----------- similarly named type alias `A` defined here ... 7 | type C = D; - | ^ help: a type alias with a similar name exists: `A` + | ^ + | +help: a type alias with a similar name exists + | +7 - type C = D; +7 + type C = A; + | error[E0425]: cannot find type `F` in this scope --> $DIR/ui-testing-optout.rs:92:10 @@ -20,7 +26,13 @@ error[E0425]: cannot find type `F` in this scope | ----------- similarly named type alias `A` defined here ... 92 | type E = F; - | ^ help: a type alias with a similar name exists: `A` + | ^ + | +help: a type alias with a similar name exists + | +92 - type E = F; +92 + type E = A; + | error: aborting due to 3 previous errors diff --git a/tests/ui/conditional-compilation/cfg-attr-multi-false.rs b/tests/ui/conditional-compilation/cfg-attr-multi-false.rs index cfb430ec5b23..871c1b81acd2 100644 --- a/tests/ui/conditional-compilation/cfg-attr-multi-false.rs +++ b/tests/ui/conditional-compilation/cfg-attr-multi-false.rs @@ -5,7 +5,7 @@ #![warn(unused_must_use)] -#[cfg_attr(any(), deprecated, must_use)] +#[cfg_attr(false, deprecated, must_use)] struct Struct {} impl Struct { diff --git a/tests/ui/conditional-compilation/cfg-attr-multi-true.rs b/tests/ui/conditional-compilation/cfg-attr-multi-true.rs index 424760c2e663..24950c8d4234 100644 --- a/tests/ui/conditional-compilation/cfg-attr-multi-true.rs +++ b/tests/ui/conditional-compilation/cfg-attr-multi-true.rs @@ -6,7 +6,7 @@ #![warn(unused_must_use)] -#[cfg_attr(all(), deprecated, must_use)] +#[cfg_attr(true, deprecated, must_use)] struct MustUseDeprecated {} impl MustUseDeprecated { //~ warning: use of deprecated diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.rs b/tests/ui/conditional-compilation/cfg-attr-parse.rs index b8aaad2685ef..21df51264e2d 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.rs +++ b/tests/ui/conditional-compilation/cfg-attr-parse.rs @@ -5,50 +5,50 @@ struct NoConfigurationPredicate; // Zero attributes, zero trailing comma (comma manatory here) -#[cfg_attr(all())] //~ error: expected `,`, found end of `cfg_attr` +#[cfg_attr(true)] //~ error: expected `,`, found end of `cfg_attr` struct A0C0; // Zero attributes, one trailing comma -#[cfg_attr(all(),)] +#[cfg_attr(true,)] //~^ WARN `#[cfg_attr]` does not expand to any attributes struct A0C1; // Zero attributes, two trailing commas -#[cfg_attr(all(),,)] //~ ERROR expected identifier +#[cfg_attr(true,,)] //~ ERROR expected identifier struct A0C2; // One attribute, no trailing comma -#[cfg_attr(all(), must_use)] // Ok +#[cfg_attr(true, must_use)] // Ok struct A1C0; // One attribute, one trailing comma -#[cfg_attr(all(), must_use,)] // Ok +#[cfg_attr(true, must_use,)] // Ok struct A1C1; // One attribute, two trailing commas -#[cfg_attr(all(), must_use,,)] //~ ERROR expected identifier +#[cfg_attr(true, must_use,,)] //~ ERROR expected identifier struct A1C2; // Two attributes, no trailing comma -#[cfg_attr(all(), must_use, deprecated)] // Ok +#[cfg_attr(true, must_use, deprecated)] // Ok struct A2C0; // Two attributes, one trailing comma -#[cfg_attr(all(), must_use, deprecated,)] // Ok +#[cfg_attr(true, must_use, deprecated,)] // Ok struct A2C1; // Two attributes, two trailing commas -#[cfg_attr(all(), must_use, deprecated,,)] //~ ERROR expected identifier +#[cfg_attr(true, must_use, deprecated,,)] //~ ERROR expected identifier struct A2C2; // Wrong delimiter `[` -#[cfg_attr[all(),,]] +#[cfg_attr[true,,]] //~^ ERROR wrong `cfg_attr` delimiters //~| ERROR expected identifier, found `,` struct BracketZero; // Wrong delimiter `{` -#[cfg_attr{all(),,}] +#[cfg_attr{true,,}] //~^ ERROR wrong `cfg_attr` delimiters //~| ERROR expected identifier, found `,` struct BraceZero; diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.stderr b/tests/ui/conditional-compilation/cfg-attr-parse.stderr index 4d4769b05cda..8dbe8969fd1c 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-parse.stderr @@ -10,45 +10,45 @@ LL | #[cfg_attr()] = note: for more information, visit error: expected `,`, found end of `cfg_attr` input - --> $DIR/cfg-attr-parse.rs:8:17 + --> $DIR/cfg-attr-parse.rs:8:16 | -LL | #[cfg_attr(all())] - | ----------------^- +LL | #[cfg_attr(true)] + | ---------------^- + | | | + | | expected `,` + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error: expected identifier, found `,` + --> $DIR/cfg-attr-parse.rs:17:17 + | +LL | #[cfg_attr(true,,)] + | ----------------^-- | | | - | | expected `,` + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:17:18 + --> $DIR/cfg-attr-parse.rs:29:27 | -LL | #[cfg_attr(all(),,)] - | -----------------^-- - | | | - | | expected identifier +LL | #[cfg_attr(true, must_use,,)] + | --------------------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:29:28 + --> $DIR/cfg-attr-parse.rs:41:39 | -LL | #[cfg_attr(all(), must_use,,)] - | ---------------------------^-- - | | | - | | expected identifier - | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` - | - = note: for more information, visit - -error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:41:40 - | -LL | #[cfg_attr(all(), must_use, deprecated,,)] - | ---------------------------------------^-- - | | | - | | expected identifier +LL | #[cfg_attr(true, must_use, deprecated,,)] + | --------------------------------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit @@ -56,22 +56,22 @@ LL | #[cfg_attr(all(), must_use, deprecated,,)] error: wrong `cfg_attr` delimiters --> $DIR/cfg-attr-parse.rs:45:11 | -LL | #[cfg_attr[all(),,]] - | ^^^^^^^^^ +LL | #[cfg_attr[true,,]] + | ^^^^^^^^ | help: the delimiters should be `(` and `)` | -LL - #[cfg_attr[all(),,]] -LL + #[cfg_attr(all(),,)] +LL - #[cfg_attr[true,,]] +LL + #[cfg_attr(true,,)] | error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:45:18 + --> $DIR/cfg-attr-parse.rs:45:17 | -LL | #[cfg_attr[all(),,]] - | -----------------^-- - | | | - | | expected identifier +LL | #[cfg_attr[true,,]] + | ----------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit @@ -79,22 +79,22 @@ LL | #[cfg_attr[all(),,]] error: wrong `cfg_attr` delimiters --> $DIR/cfg-attr-parse.rs:51:11 | -LL | #[cfg_attr{all(),,}] - | ^^^^^^^^^ +LL | #[cfg_attr{true,,}] + | ^^^^^^^^ | help: the delimiters should be `(` and `)` | -LL - #[cfg_attr{all(),,}] -LL + #[cfg_attr(all(),,)] +LL - #[cfg_attr{true,,}] +LL + #[cfg_attr(true,,)] | error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:51:18 + --> $DIR/cfg-attr-parse.rs:51:17 | -LL | #[cfg_attr{all(),,}] - | -----------------^-- - | | | - | | expected identifier +LL | #[cfg_attr{true,,}] + | ----------------^-- + | | | + | | expected identifier | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit @@ -102,8 +102,8 @@ LL | #[cfg_attr{all(),,}] warning: `#[cfg_attr]` does not expand to any attributes --> $DIR/cfg-attr-parse.rs:12:1 | -LL | #[cfg_attr(all(),)] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[cfg_attr(true,)] + | ^^^^^^^^^^^^^^^^^^ | = note: requested on the command line with `-W unused-attributes` diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index e73b20f2d5d3..1be52de708e5 100644 --- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -13,9 +13,9 @@ error[E0539]: malformed `cfg` attribute input --> $DIR/cfg-attr-syntax-validation.rs:7:1 | LL | #[cfg = 10] - | ^^^^^^^^^^^ - | | - | expected this to be a list + | ^^^^^^----^ + | | | + | | expected this to be a list | help: must be of the form: `#[cfg(predicate)]` | = note: for more information, visit diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs index 45b757e92830..0305be5d24e6 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs @@ -1,6 +1,6 @@ macro_rules! foo { () => { - #[cfg_attr(all(), unknown)] + #[cfg_attr(true, unknown)] //~^ ERROR cannot find attribute `unknown` in this scope fn foo() {} } diff --git a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr index c91ad128d6e5..bdddbd68cdaf 100644 --- a/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr @@ -1,8 +1,8 @@ error: cannot find attribute `unknown` in this scope - --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27 + --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:26 | -LL | #[cfg_attr(all(), unknown)] - | ^^^^^^^ +LL | #[cfg_attr(true, unknown)] + | ^^^^^^^ ... LL | foo!(); | ------ in this macro invocation diff --git a/tests/ui/conditional-compilation/cfg-empty-any-all.rs b/tests/ui/conditional-compilation/cfg-empty-any-all.rs new file mode 100644 index 000000000000..48ed4342235c --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-empty-any-all.rs @@ -0,0 +1,12 @@ +//! Test the behaviour of `cfg(any())` and `cfg(all())` + +#[cfg(any())] // Equivalent to cfg(false) +struct Disabled; + +#[cfg(all())] // Equivalent to cfg(true) +struct Enabled; + +fn main() { + let _ = Disabled; //~ ERROR: cannot find value `Disabled` + let _ = Enabled; // ok +} diff --git a/tests/ui/conditional-compilation/cfg-empty-any-all.stderr b/tests/ui/conditional-compilation/cfg-empty-any-all.stderr new file mode 100644 index 000000000000..1674f2def23a --- /dev/null +++ b/tests/ui/conditional-compilation/cfg-empty-any-all.stderr @@ -0,0 +1,21 @@ +error[E0425]: cannot find value `Disabled` in this scope + --> $DIR/cfg-empty-any-all.rs:10:13 + | +LL | let _ = Disabled; + | ^^^^^^^^ not found in this scope + | +note: found an item that was configured out + --> $DIR/cfg-empty-any-all.rs:4:8 + | +LL | #[cfg(any())] // Equivalent to cfg(false) + | -- the item is gated here +LL | struct Disabled; + | ^^^^^^^^ +help: consider importing this unit variant + | +LL + use std::backtrace::BacktraceStatus::Disabled; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/conditional-compilation/cfg_attr_path.rs b/tests/ui/conditional-compilation/cfg_attr_path.rs index 00e07761977a..f300e02932b7 100644 --- a/tests/ui/conditional-compilation/cfg_attr_path.rs +++ b/tests/ui/conditional-compilation/cfg_attr_path.rs @@ -3,8 +3,8 @@ #![deny(unused_attributes)] // c.f #35584 mod auxiliary { - #[cfg_attr(any(), path = "nonexistent_file.rs")] pub mod namespaced_enums; - #[cfg_attr(all(), path = "namespaced_enums.rs")] pub mod nonexistent_file; + #[cfg_attr(false, path = "nonexistent_file.rs")] pub mod namespaced_enums; + #[cfg_attr(true, path = "namespaced_enums.rs")] pub mod nonexistent_file; } fn main() { diff --git a/tests/ui/conditional-compilation/issue-34028.rs b/tests/ui/conditional-compilation/issue-34028.rs index 3ee43cb4b322..d6f3f7a9abce 100644 --- a/tests/ui/conditional-compilation/issue-34028.rs +++ b/tests/ui/conditional-compilation/issue-34028.rs @@ -1,7 +1,7 @@ //@ check-pass macro_rules! m { - () => { #[cfg(any())] fn f() {} } + () => { #[cfg(false)] fn f() {} } } trait T {} diff --git a/tests/ui/conditional-compilation/module_with_cfg.rs b/tests/ui/conditional-compilation/module_with_cfg.rs index a96f8a3e6e96..32486bdb43d6 100644 --- a/tests/ui/conditional-compilation/module_with_cfg.rs +++ b/tests/ui/conditional-compilation/module_with_cfg.rs @@ -1,3 +1,3 @@ //@ ignore-auxiliary (used by `./inner-cfg-non-inline-mod.rs`) -#![cfg_attr(all(), cfg(false))] +#![cfg_attr(true, cfg(false))] diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs new file mode 100644 index 000000000000..d49fb49d253c --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.rs @@ -0,0 +1,20 @@ +// Check that a byte string literal to a const parameter with a non-u8 +// element type isn't lowered to a ValTree with an incorrect type + +#![feature(adt_const_params)] +#![feature(rustc_attrs)] + +#[rustc_dump_predicates] +struct ConstBytes +//~^ ERROR rustc_dump_predicates +//~| NOTE Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } +//~| NOTE Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } + +where + ConstBytes: Sized; +//~^ ERROR mismatched types +//~| NOTE expected `&[*mut u8; 3]`, found `&[u8; 3]` +//~| NOTE expected reference `&'static [*mut u8; 3]` +//~| NOTE found reference `&'static [u8; 3]` + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr new file mode 100644 index 000000000000..1273a74102a2 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/byte-string-u8-validation.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/byte-string-u8-validation.rs:14:16 + | +LL | ConstBytes: Sized; + | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` + | + = note: expected reference `&'static [*mut u8; 3]` + found reference `&'static [u8; 3]` + +error: rustc_dump_predicates + --> $DIR/byte-string-u8-validation.rs:8:1 + | +LL | struct ConstBytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: Binder { value: ConstArgHasType(T/#0, &'static [*mut u8; 3_usize]), bound_vars: [] } + = note: Binder { value: TraitPredicate( as std::marker::Sized>, polarity:Positive), bound_vars: [] } + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr index 75718fbbba0a..be63c9e5c046 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -2,7 +2,7 @@ error[E0277]: `fn() {main}` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:7:11 | LL | check(main); - | ----- ^^^^ the trait `ConstParamTy_` is not implemented for fn item `fn() {main}` + | ----- ^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for fn item `fn() {main}` | | | required by a bound introduced by this call | @@ -24,7 +24,7 @@ LL | check(|| {}); | | | required by a bound introduced by this call | - = help: the trait `ConstParamTy_` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}` + = help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | @@ -40,7 +40,7 @@ error[E0277]: `fn()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:9:11 | LL | check(main as fn()); - | ----- ^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `fn()` + | ----- ^^^^^^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `fn()` | | | required by a bound introduced by this call | @@ -58,7 +58,7 @@ error[E0277]: `&mut ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:10:11 | LL | check(&mut ()); - | ----- ^^^^^^^ the trait `ConstParamTy_` is not implemented for `&mut ()` + | ----- ^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `&mut ()` | | | required by a bound introduced by this call | @@ -78,12 +78,15 @@ error[E0277]: `*mut ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:11:11 | LL | check(&mut () as *mut ()); - | ----- ^^^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*mut ()` + | ----- ^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `*mut ()` | | | required by a bound introduced by this call | help: the trait `ConstParamTy_` is implemented for `()` --> $SRC_DIR/core/src/marker.rs:LL:COL + ::: $SRC_DIR/core/src/marker.rs:LL:COL + | + = note: in this macro invocation note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | @@ -95,12 +98,15 @@ error[E0277]: `*const ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:12:11 | LL | check(&() as *const ()); - | ----- ^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*const ()` + | ----- ^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `ConstParamTy_` is not implemented for `*const ()` | | | required by a bound introduced by this call | help: the trait `ConstParamTy_` is implemented for `()` --> $SRC_DIR/core/src/marker.rs:LL:COL + ::: $SRC_DIR/core/src/marker.rs:LL:COL + | + = note: in this macro invocation note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr index 373ac9435daf..460b7420e8c0 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad_empty_array.stderr @@ -4,7 +4,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type LL | check::<[NotParam; 0]>(); | ^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `ConstParamTy_` is not implemented for `NotParam` +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam` --> $DIR/const_param_ty_bad_empty_array.rs:5:1 | LL | struct NotParam; diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr index ca2aa3adcb7a..fd1162fe08e3 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr @@ -4,7 +4,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type LL | check::<&NotParam>(); | ^^^^^^^^^ unsatisfied trait bound | -help: the trait `ConstParamTy_` is not implemented for `NotParam` +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1 | LL | struct NotParam; @@ -22,7 +22,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type LL | check::<[NotParam]>(); | ^^^^^^^^^^ unsatisfied trait bound | -help: the trait `ConstParamTy_` is not implemented for `NotParam` +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1 | LL | struct NotParam; @@ -40,7 +40,7 @@ error[E0277]: `NotParam` can't be used as a const parameter type LL | check::<[NotParam; 17]>(); | ^^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `ConstParamTy_` is not implemented for `NotParam` +help: the nightly-only, unstable trait `ConstParamTy_` is not implemented for `NotParam` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1 | LL | struct NotParam; diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs index 0614ea97b1ad..1900931b3f35 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs @@ -8,10 +8,10 @@ struct NotParam; struct CantParam(NotParam); impl std::marker::ConstParamTy_ for CantParam {} -//~^ error: the trait `ConstParamTy_` cannot be implemented for this type +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type #[derive(std::marker::ConstParamTy, Eq, PartialEq)] -//~^ error: the trait `ConstParamTy_` cannot be implemented for this type struct CantParamDerive(NotParam); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr index fd1836802c4a..084c64d27335 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr @@ -8,13 +8,12 @@ LL | impl std::marker::ConstParamTy_ for CantParam {} | ^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/const_param_ty_impl_bad_field.rs:13:10 + --> $DIR/const_param_ty_impl_bad_field.rs:14:8 | LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | + | ------------------------- in this derive macro expansion LL | struct CantParamDerive(NotParam); - | -------- this field does not implement `ConstParamTy_` + | ^^^^^^^^^^^^^^^ -------- this field does not implement `ConstParamTy_` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index a1c8eccfb095..a8f190609c04 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -8,13 +8,13 @@ impl std::marker::ConstParamTy_ for ImplementsConstParamTy {} struct CantParam(ImplementsConstParamTy); impl std::marker::ConstParamTy_ for CantParam {} -//~^ error: the type `CantParam` does not `#[derive(PartialEq)]` -//~| ERROR the trait bound `CantParam: Eq` is not satisfied +//~^ ERROR: the type `CantParam` does not `#[derive(PartialEq)]` +//~| ERROR: the trait bound `CantParam: Eq` is not satisfied #[derive(std::marker::ConstParamTy)] -//~^ error: the type `CantParamDerive` does not `#[derive(PartialEq)]` -//~| ERROR the trait bound `CantParamDerive: Eq` is not satisfied struct CantParamDerive(ImplementsConstParamTy); +//~^ ERROR: the type `CantParamDerive` does not `#[derive(PartialEq)]` +//~| ERROR: the trait bound `CantParamDerive: Eq` is not satisfied fn check() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr index c6b791ed9674..1219d5f04380 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -18,7 +18,7 @@ error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]` LL | impl std::marker::ConstParamTy_ for CantParam {} | ^^^^^^^^^ unsatisfied trait bound | -help: the trait `StructuralPartialEq` is not implemented for `CantParam` +help: the nightly-only, unstable trait `StructuralPartialEq` is not implemented for `CantParam` --> $DIR/const_param_ty_impl_no_structural_eq.rs:8:1 | LL | struct CantParam(ImplementsConstParamTy); @@ -27,10 +27,12 @@ note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL error[E0277]: the trait bound `CantParamDerive: Eq` is not satisfied - --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:8 | LL | #[derive(std::marker::ConstParamTy)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive` + | ------------------------- in this derive macro expansion +LL | struct CantParamDerive(ImplementsConstParamTy); + | ^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive` | note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL @@ -41,13 +43,15 @@ LL | struct CantParamDerive(ImplementsConstParamTy); | error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:8 | LL | #[derive(std::marker::ConstParamTy)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound + | ------------------------- in this derive macro expansion +LL | struct CantParamDerive(ImplementsConstParamTy); + | ^^^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `StructuralPartialEq` is not implemented for `CantParamDerive` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:17:1 +help: the nightly-only, unstable trait `StructuralPartialEq` is not implemented for `CantParamDerive` + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:1 | LL | struct CantParamDerive(ImplementsConstParamTy); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.rs b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.rs new file mode 100644 index 000000000000..d1658bf20a74 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.rs @@ -0,0 +1,12 @@ +//! Regression test for + +#![feature(adt_const_params)] + +struct ConstBytes; +//~^ ERROR `&'static [*mut u8; 3]` can't be used as a const parameter type + +pub fn main() { + let _: ConstBytes = ConstBytes::; + //~^ ERROR mismatched types + //~| ERROR mismatched types +} diff --git a/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr new file mode 100644 index 000000000000..d7eec45bae0f --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/mismatch-raw-ptr-in-adt.stderr @@ -0,0 +1,31 @@ +error[E0741]: `&'static [*mut u8; 3]` can't be used as a const parameter type + --> $DIR/mismatch-raw-ptr-in-adt.rs:5:28 + | +LL | struct ConstBytes; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `*mut u8` must implement `ConstParamTy_`, but it does not + = note: `[*mut u8; 3]` must implement `ConstParamTy_`, but it does not + +error[E0308]: mismatched types + --> $DIR/mismatch-raw-ptr-in-adt.rs:9:23 + | +LL | let _: ConstBytes = ConstBytes::; + | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` + | + = note: expected reference `&'static [*mut u8; 3]` + found reference `&'static [u8; 3]` + +error[E0308]: mismatched types + --> $DIR/mismatch-raw-ptr-in-adt.rs:9:46 + | +LL | let _: ConstBytes = ConstBytes::; + | ^^^^^^ expected `&[*mut u8; 3]`, found `&[u8; 3]` + | + = note: expected reference `&'static [*mut u8; 3]` + found reference `&'static [u8; 3]` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0741. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs index d42ef90e1b18..e8a16be2197b 100644 --- a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs @@ -4,15 +4,15 @@ use std::marker::ConstParamTy; #[derive(ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo([*const u8; 1]); +//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty #[derive(ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo2([*mut u8; 1]); +//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty #[derive(ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo3([fn(); 1]); +//~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr index 442ec6b96cef..6c8a506d1f40 100644 --- a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr @@ -1,44 +1,41 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:6:10 + --> $DIR/nested_bad_const_param_ty.rs:7:8 | LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct Foo([*const u8; 1]); - | -------------- this field does not implement `ConstParamTy_` + | ^^^ -------------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[*const u8; 1]` requires that `*const u8: ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:8:12 + --> $DIR/nested_bad_const_param_ty.rs:7:12 | LL | struct Foo([*const u8; 1]); | ^^^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:10:10 + --> $DIR/nested_bad_const_param_ty.rs:11:8 | LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct Foo2([*mut u8; 1]); - | ------------ this field does not implement `ConstParamTy_` + | ^^^^ ------------ this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[*mut u8; 1]` requires that `*mut u8: ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:12:13 + --> $DIR/nested_bad_const_param_ty.rs:11:13 | LL | struct Foo2([*mut u8; 1]); | ^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:14:10 + --> $DIR/nested_bad_const_param_ty.rs:15:8 | LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct Foo3([fn(); 1]); - | --------- this field does not implement `ConstParamTy_` + | ^^^^ --------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[fn(); 1]` requires that `fn(): ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:16:13 + --> $DIR/nested_bad_const_param_ty.rs:15:13 | LL | struct Foo3([fn(); 1]); | ^^^^^^^^^ diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs index 6b87ad86d4bc..e364368b8a4c 100644 --- a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs +++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs @@ -1,4 +1,4 @@ -#![feature(generic_const_exprs, unsized_const_params)] +#![feature(adt_const_params, generic_const_exprs, unsized_const_params)] #![allow(incomplete_features)] // Regression test for 128232 diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr index 72dfda50ea5c..b13f76eabadb 100644 --- a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr +++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr @@ -9,13 +9,11 @@ help: you might be missing a const parameter LL | impl Wrapper<{ bar() }> { | +++++++++++++++++++++++ -error: using function pointers as const generic parameters is forbidden +error[E0741]: using function pointers as const generic parameters is forbidden --> $DIR/non_valtreeable_const_arg-2.rs:8:25 | LL | struct Wrapper; | ^^^^ - | - = note: the only supported types are integers, `bool`, and `char` error[E0599]: the function or associated item `call` exists for struct `Wrapper`, but its trait bounds were not satisfied --> $DIR/non_valtreeable_const_arg-2.rs:17:26 @@ -37,5 +35,5 @@ note: the trait `Fn` must be implemented error: aborting due to 3 previous errors -Some errors have detailed explanations: E0425, E0599. +Some errors have detailed explanations: E0425, E0599, E0741. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.rs new file mode 100644 index 000000000000..17910d52d3d7 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.rs @@ -0,0 +1,22 @@ +// regression test for issue #137582, where constant evaluating an unsized AnonConst would ICE + +#![feature(adt_const_params)] + +mod lib { + pub type Matrix = [&'static u32]; + + const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + //~^ ERROR the size for values of type `[&'static u32]` cannot be known at compilation time + //~| ERROR mismatched types + //~| ERROR mismatched types + + pub struct Walk { + //~^ ERROR use of unstable library feature `unsized_const_params` + _p: (), + } + + impl Walk {} + //~^ ERROR the size for values of type `[&'static u32]` cannot be known at compilation time +} + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.stderr new file mode 100644 index 000000000000..daea55efbbc7 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-1.stderr @@ -0,0 +1,44 @@ +error[E0277]: the size for values of type `[&'static u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-1.rs:8:25 + | +LL | const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + | ^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[&'static u32]` + = note: statics and constants must have a statically known size + +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/unsized-anon-const-err-1.rs:13:43 + | +LL | pub struct Walk { + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `[&'static u32]` to implement `ConstParamTy_` + +error[E0277]: the size for values of type `[&'static u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-1.rs:18:46 + | +LL | impl Walk {} + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[&'static u32]` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-err-1.rs:8:35 + | +LL | const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + | ^^^^^^ expected `&u32`, found `[{integer}; 4]` + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-err-1.rs:8:34 + | +LL | const EMPTY_MATRIX: Matrix = [[0; 4]; 4]; + | ^^^^^^^^^^^ expected `[&u32]`, found `[&u32; 4]` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs new file mode 100644 index 000000000000..81b1ec6a7719 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.rs @@ -0,0 +1,21 @@ +// regression test for issue #151591, where constant evaluating an unsized AnonConst would ICE + +#![feature(adt_const_params)] +#![feature(unsized_const_params)] +//~^ WARN the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + +#[derive(Clone)] +struct S; + +const A: [u8]; +//~^ ERROR free constant item without body +//~| ERROR the size for values of type `[u8]` cannot be known at compilation time + +impl Copy for S {} +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR the const parameter `N` is not constrained by the impl trait, self type, or predicates +impl Copy for S {} +//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR the const parameter `M` is not constrained by the impl trait, self type, or predicates + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr new file mode 100644 index 000000000000..d538bb0af09a --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-err-2.stderr @@ -0,0 +1,66 @@ +error: free constant item without body + --> $DIR/unsized-anon-const-err-2.rs:10:1 + | +LL | const A: [u8]; + | ^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` + +warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/unsized-anon-const-err-2.rs:4:12 + | +LL | #![feature(unsized_const_params)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #95174 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-2.rs:10:10 + | +LL | const A: [u8]; + | ^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: statics and constants must have a statically known size + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-2.rs:14:31 + | +LL | impl Copy for S {} + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: statics and constants must have a statically known size + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/unsized-anon-const-err-2.rs:17:33 + | +LL | impl Copy for S {} + | ^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: statics and constants must have a statically known size + +error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates + --> $DIR/unsized-anon-const-err-2.rs:14:6 + | +LL | impl Copy for S {} + | ^^^^^^^^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error[E0207]: the const parameter `M` is not constrained by the impl trait, self type, or predicates + --> $DIR/unsized-anon-const-err-2.rs:17:6 + | +LL | impl Copy for S {} + | ^^^^^^^^^^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error: aborting due to 6 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0277. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.rs new file mode 100644 index 000000000000..a299cc29fcc5 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.rs @@ -0,0 +1,16 @@ +// manually reduced reproduction of issue #137582, where constant evaluating an unsized AnonConst +// would ICE + +#![feature(adt_const_params)] + +fn func() {} +//~^ ERROR use of unstable library feature `unsized_const_params` + +const VALUE: [u32] = [0; 4]; +//~^ ERROR mismatched types +//~| ERROR the size for values of type `[u32]` cannot be known at compilation time + +fn main() { + func::(); + //~^ ERROR the size for values of type `[u32]` cannot be known at compilation time +} diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.stderr new file mode 100644 index 000000000000..14a41e87e4aa --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-func-err.stderr @@ -0,0 +1,38 @@ +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/unsized-anon-const-func-err.rs:6:9 + | +LL | fn func() {} + | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `[u32]` to implement `ConstParamTy_` + +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-func-err.rs:9:14 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-func-err.rs:9:22 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^^ expected `[u32]`, found `[u32; 4]` + +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-func-err.rs:14:12 + | +LL | func::(); + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.rs b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.rs new file mode 100644 index 000000000000..35407d02f6ef --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.rs @@ -0,0 +1,16 @@ +// manually reduced reproduction of issue #137582, where constant evaluating an unsized AnonConst +// would ICE + +#![feature(adt_const_params)] + +const VALUE: [u32] = [0; 4]; +//~^ ERROR the size for values of type `[u32]` cannot be known at compilation time +//~| ERROR mismatched types + +struct SomeStruct {} +//~^ ERROR use of unstable library feature `unsized_const_params` + +impl SomeStruct {} +//~^ ERROR the size for values of type `[u32]` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.stderr b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.stderr new file mode 100644 index 000000000000..d9a13976d68a --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsized-anon-const-struct-err.stderr @@ -0,0 +1,38 @@ +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-struct-err.rs:6:14 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/unsized-anon-const-struct-err.rs:10:19 + | +LL | struct SomeStruct {} + | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `[u32]` to implement `ConstParamTy_` + +error[E0277]: the size for values of type `[u32]` cannot be known at compilation time + --> $DIR/unsized-anon-const-struct-err.rs:13:17 + | +LL | impl SomeStruct {} + | ^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u32]` + = note: statics and constants must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized-anon-const-struct-err.rs:6:22 + | +LL | const VALUE: [u32] = [0; 4]; + | ^^^^^^ expected `[u32]`, found `[u32; 4]` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308, E0658. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-1.rs b/tests/ui/const-generics/adt_const_params/unsized_field-1.rs index 5db031cb900f..f2d972612dc6 100644 --- a/tests/ui/const-generics/adt_const_params/unsized_field-1.rs +++ b/tests/ui/const-generics/adt_const_params/unsized_field-1.rs @@ -6,18 +6,18 @@ extern crate unsized_const_param; use std::marker::ConstParamTy; #[derive(ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type struct A([u8]); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type #[derive(ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type struct B(&'static [u8]); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type #[derive(ConstParamTy, Eq, PartialEq)] struct C(unsized_const_param::Foo); #[derive(std::marker::ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr b/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr index 134dbba0d63a..2538b811618b 100644 --- a/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr +++ b/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr @@ -1,44 +1,41 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-1.rs:8:10 + --> $DIR/unsized_field-1.rs:9:8 | LL | #[derive(ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct A([u8]); - | ---- this field does not implement `ConstParamTy_` + | ^ ---- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[u8]` requires that `feature(unsized_const_params) is enabled` - --> $DIR/unsized_field-1.rs:10:10 + --> $DIR/unsized_field-1.rs:9:10 | LL | struct A([u8]); | ^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-1.rs:12:10 + --> $DIR/unsized_field-1.rs:13:8 | LL | #[derive(ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^ -LL | + | ------------ in this derive macro expansion LL | struct B(&'static [u8]); - | ------------- this field does not implement `ConstParamTy_` + | ^ ------------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `&'static [u8]` requires that `feature(unsized_const_params) is enabled` - --> $DIR/unsized_field-1.rs:14:10 + --> $DIR/unsized_field-1.rs:13:10 | LL | struct B(&'static [u8]); | ^^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-1.rs:19:10 + --> $DIR/unsized_field-1.rs:20:8 | LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | + | ------------------------- in this derive macro expansion LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); - | ---------------------------------------------------------- this field does not implement `ConstParamTy_` + | ^ ---------------------------------------------------------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `GenericNotUnsizedParam<&'static [u8]>` requires that `feature(unsized_const_params) is enabled` - --> $DIR/unsized_field-1.rs:21:10 + --> $DIR/unsized_field-1.rs:20:10 | LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs index 500e8e22b0e3..71ac662cf580 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs @@ -6,8 +6,8 @@ use std::marker::ConstParamTy; #[derive(Debug, PartialEq, Eq, ConstParamTy)] -//~^ ERROR the trait `ConstParamTy_` struct Foo { +//~^ ERROR the trait `ConstParamTy_` nested: &'static Bar, //~^ ERROR the size for values //~| ERROR the size for values diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index af29eaa35cb6..f520413927c3 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -19,11 +19,13 @@ LL | struct Bar(T); | this could be changed to `T: ?Sized`... error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsizing-wfcheck-issue-126272.rs:8:32 + --> $DIR/unsizing-wfcheck-issue-126272.rs:9:8 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^^^^^^^^^^^ -... + | ------------ in this derive macro expansion +LL | struct Foo { + | ^^^ +LL | LL | nested: &'static Bar, | ----------------------------------------- this field does not implement `ConstParamTy_` | @@ -59,12 +61,13 @@ help: the trait `Debug` is implemented for `Bar` LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^^^^ note: required for `Bar<(dyn Debug + 'static)>` to implement `Debug` - --> $DIR/unsizing-wfcheck-issue-126272.rs:19:10 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:8 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^^^^ + | ----- in this derive macro expansion LL | struct Bar(T); - | - unsatisfied trait bound introduced in this `derive` macro + | ^^^ - unsatisfied trait bound + = help: consider manually implementing `Debug` to avoid undesired bounds = note: 2 redundant requirements hidden = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` = note: required for the cast from `&&&'static Bar<(dyn Debug + 'static)>` to `&dyn Debug` @@ -93,13 +96,16 @@ help: the trait `Eq` is implemented for `Bar` LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^ note: required for `Bar` to implement `Eq` - --> $DIR/unsizing-wfcheck-issue-126272.rs:19:28 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:8 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^ unsatisfied trait bound introduced in this `derive` macro + | -- in this derive macro expansion +LL | struct Bar(T); + | ^^^ - type parameter would need to implement `Eq` + = help: consider manually implementing `Eq` to avoid undesired bounds = note: 1 redundant requirement hidden = note: required for `&'static Bar` to implement `Eq` -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs b/tests/ui/const-generics/assoc_const_eq_diagnostic.rs deleted file mode 100644 index 6ab82f45e684..000000000000 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ edition:2015 -#![feature(associated_const_equality)] - -pub enum Mode { - Cool, -} - -pub trait Parse { - const MODE: Mode; -} - -pub trait CoolStuff: Parse {} -//~^ ERROR expected constant, found type -//~| ERROR expected constant, found type -//~| ERROR expected constant, found type -//~| ERROR expected type - -fn no_help() -> Mode::Cool {} -//~^ ERROR expected type, found variant - -fn main() {} diff --git a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr b/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr deleted file mode 100644 index bcfad9d1538c..000000000000 --- a/tests/ui/const-generics/assoc_const_eq_diagnostic.stderr +++ /dev/null @@ -1,77 +0,0 @@ -error[E0573]: expected type, found variant `Mode::Cool` - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 - | -LL | pub trait CoolStuff: Parse {} - | ^^^^^^^^^^ - | | - | not a type - | help: try using the variant's enum: `Mode` - -error[E0573]: expected type, found variant `Mode::Cool` - --> $DIR/assoc_const_eq_diagnostic.rs:18:17 - | -LL | fn no_help() -> Mode::Cool {} - | ^^^^^^^^^^ - | | - | not a type - | help: try using the variant's enum: `Mode` - -error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 - | -LL | pub trait CoolStuff: Parse {} - | ---- ^^^^^^^^^^ unexpected type - | | - | expected a constant because of this associated constant - | -note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:9:5 - | -LL | const MODE: Mode; - | ^^^^^^^^^^^^^^^^ -help: consider adding braces here - | -LL | pub trait CoolStuff: Parse {} - | + + - -error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 - | -LL | pub trait CoolStuff: Parse {} - | ---- ^^^^^^^^^^ unexpected type - | | - | expected a constant because of this associated constant - | -note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:9:5 - | -LL | const MODE: Mode; - | ^^^^^^^^^^^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider adding braces here - | -LL | pub trait CoolStuff: Parse {} - | + + - -error: expected constant, found type - --> $DIR/assoc_const_eq_diagnostic.rs:12:35 - | -LL | pub trait CoolStuff: Parse {} - | ---- ^^^^^^^^^^ unexpected type - | | - | expected a constant because of this associated constant - | -note: the associated constant is defined here - --> $DIR/assoc_const_eq_diagnostic.rs:9:5 - | -LL | const MODE: Mode; - | ^^^^^^^^^^^^^^^^ - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -help: consider adding braces here - | -LL | pub trait CoolStuff: Parse {} - | + + - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/const-generics/associated-const-bindings/ambiguity.rs b/tests/ui/const-generics/associated-const-bindings/ambiguity.rs new file mode 100644 index 000000000000..6871a028de5f --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/ambiguity.rs @@ -0,0 +1,26 @@ +// We used to say "ambiguous associated type" on ambiguous associated consts. +// Ensure that we now use the correct label. + +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] +#![allow(incomplete_features)] + +trait Trait0: Parent0 + Parent0 {} +trait Parent0 { + type const K: (); +} + +fn take0(_: impl Trait0) {} +//~^ ERROR ambiguous associated constant `K` in bounds of `Trait0` + +trait Trait1: Parent1 + Parent2 {} +trait Parent1 { + type const C: i32; +} +trait Parent2 { + type const C: &'static str; +} + +fn take1(_: impl Trait1) {} +//~^ ERROR ambiguous associated constant `C` in bounds of `Trait1` + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr new file mode 100644 index 000000000000..9dcb30d6b737 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/ambiguity.stderr @@ -0,0 +1,39 @@ +error[E0222]: ambiguous associated constant `K` in bounds of `Trait0` + --> $DIR/ambiguity.rs:12:25 + | +LL | type const K: (); + | ---------------- + | | + | ambiguous `K` from `Parent0` + | ambiguous `K` from `Parent0` +... +LL | fn take0(_: impl Trait0) {} + | ^^^^^^^^^^^^^ ambiguous associated constant `K` + | + = help: consider introducing a new type parameter `T` and adding `where` constraints: + where + T: Trait0, + T: Parent0::K = const { }, + T: Parent0::K = const { } + +error[E0222]: ambiguous associated constant `C` in bounds of `Trait1` + --> $DIR/ambiguity.rs:23:25 + | +LL | type const C: i32; + | ----------------- ambiguous `C` from `Parent1` +... +LL | type const C: &'static str; + | -------------------------- ambiguous `C` from `Parent2` +... +LL | fn take1(_: impl Trait1) {} + | ^^^^^^^ ambiguous associated constant `C` + | + = help: consider introducing a new type parameter `T` and adding `where` constraints: + where + T: Trait1, + T: Parent2::C = "?", + T: Parent1::C = "?" + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0222`. diff --git a/tests/ui/associated-consts/assoc-const-ty-mismatch.rs b/tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.rs similarity index 83% rename from tests/ui/associated-consts/assoc-const-ty-mismatch.rs rename to tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.rs index 7211637659bd..1092733a8e2e 100644 --- a/tests/ui/associated-consts/assoc-const-ty-mismatch.rs +++ b/tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.rs @@ -1,5 +1,5 @@ -#![feature(associated_const_equality)] -#![allow(unused)] +#![feature(min_generic_const_args)] +#![allow(incomplete_features, unused)] pub trait Foo { const N: usize; diff --git a/tests/ui/associated-consts/assoc-const-ty-mismatch.stderr b/tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.stderr similarity index 100% rename from tests/ui/associated-consts/assoc-const-ty-mismatch.stderr rename to tests/ui/const-generics/associated-const-bindings/assoc-const-ty-mismatch.stderr diff --git a/tests/ui/const-generics/associated-const-bindings/assoc-const.rs b/tests/ui/const-generics/associated-const-bindings/assoc-const.rs new file mode 100644 index 000000000000..3f8353b6914d --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/assoc-const.rs @@ -0,0 +1,22 @@ +//@ run-pass +#![feature(min_generic_const_args)] +#![allow(unused, incomplete_features)] + +pub trait Foo { + type const N: usize; +} + +pub struct Bar; + +impl Foo for Bar { + type const N: usize = 3; +} + +const TEST: usize = 3; + + +fn foo>() {} + +fn main() { + foo::() +} diff --git a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs new file mode 100644 index 000000000000..53f65319db9d --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.rs @@ -0,0 +1,32 @@ +// Check that we eventually catch types of assoc const bounds +// (containing late-bound vars) that are ill-formed. +#![feature( + min_generic_const_args, + adt_const_params, + unsized_const_params, + generic_const_parameter_types, +)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +trait Trait { + type const K: T; +} + +fn take( + _: impl Trait< + < fn(&'a str) -> &'a str as Project>::Out as Discard>::Out, + K = const { () } + >, +) {} +//~^^^ ERROR higher-ranked subtype error +//~| ERROR higher-ranked subtype error + +trait Project { type Out; } +impl Project for fn(T) -> T { type Out = T; } + +trait Discard { type Out; } +impl Discard for T { type Out = (); } + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr new file mode 100644 index 000000000000..f2f69aad4ee6 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty-not-wf.stderr @@ -0,0 +1,16 @@ +error: higher-ranked subtype error + --> $DIR/bound-var-in-ty-not-wf.rs:20:13 + | +LL | K = const { () } + | ^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/bound-var-in-ty-not-wf.rs:20:13 + | +LL | K = const { () } + | ^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs new file mode 100644 index 000000000000..a509fe0d52e3 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/bound-var-in-ty.rs @@ -0,0 +1,30 @@ +// Check that we don't reject non-escaping late-bound vars in the type of assoc const bindings. +// There's no reason why we should disallow them. +// +//@ check-pass + +#![feature( + min_generic_const_args, + adt_const_params, + unsized_const_params, + generic_const_parameter_types, +)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +trait Trait { + type const K: T; +} + +fn take( + _: impl Trait< + fn(&'a str) -> &'a str as Discard>::Out, + K = const { } + >, +) {} + +trait Discard { type Out; } +impl Discard for T { type Out = (); } + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs b/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs new file mode 100644 index 000000000000..149755bad4ca --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/coexisting-with-type-binding.rs @@ -0,0 +1,26 @@ +// Regression test for issue #112560. +// Respect the fact that (associated) types and constants live in different namespaces and +// therefore equality bounds involving identically named associated items don't conflict if +// their kind (type vs. const) differs. This obviously extends to supertraits. + +//@ check-pass + +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] +#![allow(incomplete_features)] + +trait Trait: SuperTrait { + type N; + type Q; + + type const N: usize; +} + +trait SuperTrait { + type const Q: &'static str; +} + +fn take0(_: impl Trait) {} + +fn take1(_: impl Trait) {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/coherence.rs b/tests/ui/const-generics/associated-const-bindings/coherence.rs new file mode 100644 index 000000000000..e9296f3a8df0 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/coherence.rs @@ -0,0 +1,16 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +pub trait IsVoid { + type const IS_VOID: bool; +} +impl IsVoid for () { + type const IS_VOID: bool = true; +} + +pub trait Maybe {} +impl Maybe for () {} +impl Maybe for () where (): IsVoid {} +//~^ ERROR conflicting implementations of trait `Maybe` for type `()` + +fn main() {} diff --git a/tests/ui/const-generics/associated_const_equality/coherence.stderr b/tests/ui/const-generics/associated-const-bindings/coherence.stderr similarity index 93% rename from tests/ui/const-generics/associated_const_equality/coherence.stderr rename to tests/ui/const-generics/associated-const-bindings/coherence.stderr index 23d6495a16a4..df6781f2f9a2 100644 --- a/tests/ui/const-generics/associated_const_equality/coherence.stderr +++ b/tests/ui/const-generics/associated-const-bindings/coherence.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `Maybe` for type `()` - --> $DIR/coherence.rs:15:1 + --> $DIR/coherence.rs:13:1 | LL | impl Maybe for () {} | ----------------- first implementation here diff --git a/tests/ui/associated-type-bounds/issue-99828.rs b/tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.rs similarity index 100% rename from tests/ui/associated-type-bounds/issue-99828.rs rename to tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.rs diff --git a/tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.stderr b/tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.stderr new file mode 100644 index 000000000000..692e511fb469 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/const-bound-to-assoc-ty-99828.stderr @@ -0,0 +1,36 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/const-bound-to-assoc-ty-99828.rs:1:43 + | +LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { + | ^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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: expected type, found constant + --> $DIR/const-bound-to-assoc-ty-99828.rs:1:50 + | +LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { + | ---- ^^ unexpected constant + | | + | expected a type because of this associated type + | +note: the associated type is defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: expected type, found constant + --> $DIR/const-bound-to-assoc-ty-99828.rs:1:50 + | +LL | fn get_iter(vec: &[i32]) -> impl Iterator + '_ { + | ---- ^^ unexpected constant + | | + | expected a type because of this associated type + | +note: the associated type is defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs b/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs new file mode 100644 index 000000000000..8e871ddf90ce --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/const-projection-err.rs @@ -0,0 +1,15 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +trait TraitWAssocConst { + type const A: usize; +} + +fn foo>() {} + +fn bar>() { + foo::(); + //~^ ERROR type mismatch resolving `::A == 1` +} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr b/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr new file mode 100644 index 000000000000..c533a7d65b90 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/const-projection-err.stderr @@ -0,0 +1,17 @@ +error[E0271]: type mismatch resolving `::A == 1` + --> $DIR/const-projection-err.rs:11:11 + | +LL | foo::(); + | ^ expected `1`, found `0` + | + = note: expected constant `1` + found constant `0` +note: required by a bound in `foo` + --> $DIR/const-projection-err.rs:8:28 + | +LL | fn foo>() {} + | ^^^^^ required by this bound in `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs b/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs new file mode 100644 index 000000000000..578904ea1891 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/const_evaluatable_unchecked.rs @@ -0,0 +1,20 @@ +// The impl of lint `const_evaluatable_unchecked` used to wrongly assume and `assert!` that +// successfully evaluating a type-system constant that has non-region args had to be an anon const. +// In the case below however we have a type-system assoc const (here: `<() as TraitA>::K`). +// +// issue: +//@ check-pass +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +pub trait TraitA { + type const K: u8 = 0; +} +pub trait TraitB {} + +impl TraitA for () {} +impl TraitB for () where (): TraitA {} + +fn check() where (): TraitB {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs new file mode 100644 index 000000000000..771f48cba068 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.rs @@ -0,0 +1,37 @@ +// Ensure that we consider traits dyn *in*compatible if the type of any (type) assoc const +// mentions `Self` (barring "`Self` projections") + +//@ dont-require-annotations: NOTE + +#![feature(adt_const_params)] +#![feature(generic_const_items)] +#![feature(generic_const_parameter_types)] +#![feature(min_generic_const_args)] +#![feature(unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + // NOTE: The `ConstParamTy_` bound is intentionally on the assoc const and not on the trait as + // doing the latter would already render the trait dyn incompatible due to it being + // bounded by `PartialEq` and supertrait bounds cannot mention `Self` like this. + type const K: Self where Self: std::marker::ConstParamTy_; + //~^ NOTE it contains associated const `K` whose type references the `Self` type + + // This is not a "`Self` projection" in our sense (which would be allowed) + // since the trait is not the principal trait or a supertrait thereof. + type const Q: ::Output; + //~^ NOTE it contains associated const `Q` whose type references the `Self` type +} + +trait SomeOtherTrait { + type Output: std::marker::ConstParamTy_; +} + +// You could imagine this impl being more interesting and mention `T` somewhere in `Output`... +impl SomeOtherTrait for T { + type Output = (); +} + +fn main() { + let _: dyn Trait; //~ ERROR the trait `Trait` is not dyn compatible +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr new file mode 100644 index 000000000000..19cd8bf5af99 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-assoc-const-ty-mentions-self.stderr @@ -0,0 +1,24 @@ +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:36:16 + | +LL | let _: dyn Trait; + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-compat-assoc-const-ty-mentions-self.rs:17:16 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +... +LL | type const K: Self where Self: std::marker::ConstParamTy_; + | ^ ...because it contains associated const `K` whose type references the `Self` type +... +LL | type const Q: ::Output; + | ^ ...because it contains associated const `Q` whose type references the `Self` type + = help: consider moving `K` to another trait + = help: consider moving `Q` to another trait + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-basic.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-basic.rs new file mode 100644 index 000000000000..8de8cb1a60db --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-basic.rs @@ -0,0 +1,33 @@ +// Traits with type associated consts are dyn compatible. +// Check that we allow the corresp. trait object types if all assoc consts are specified. + +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait: SuperTrait { + type const K: usize; +} + +trait SuperTrait { + type const Q: usize; + type const C: usize; +} + +trait Bound { + type const N: usize; +} + +impl Bound for () { + type const N: usize = 10; +} + +fn main() { + let _: dyn Trait; + + let obj: &dyn Bound = &(); + _ = identity(obj); + + fn identity(x: &(impl ?Sized + Bound)) -> &(impl ?Sized + Bound) { x } +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.rs new file mode 100644 index 000000000000..ad5c4b679117 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.rs @@ -0,0 +1,16 @@ +// Ensure that we actually enforce equality constraints found in trait object types. + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + type const N: usize; +} + +impl Trait for () { + type const N: usize = 1; +} + +fn main() { + let _: &dyn Trait = &(); //~ ERROR type mismatch resolving `<() as Trait>::N == 0` +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.stderr new file mode 100644 index 000000000000..282504e3bc35 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-mismatch.stderr @@ -0,0 +1,13 @@ +error[E0271]: type mismatch resolving `<() as Trait>::N == 0` + --> $DIR/dyn-compat-const-mismatch.rs:15:32 + | +LL | let _: &dyn Trait = &(); + | ^^^ expected `0`, found `1` + | + = note: expected constant `0` + found constant `1` + = note: required for the cast from `&()` to `&dyn Trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.rs new file mode 100644 index 000000000000..8130960195d9 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.rs @@ -0,0 +1,19 @@ +// Test that we force users to explicitly specify const arguments for const parameters that +// have defaults if the default mentions the `Self` type parameter. + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait X::N }> {} + +trait Y { + type const N: usize; +} + +impl Y for T { + type const N: usize = 1; +} + +fn main() { + let _: dyn X; //~ ERROR the const parameter `N` must be explicitly specified +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.stderr new file mode 100644 index 000000000000..a22545fcd8d2 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-param-default-mentions-self.stderr @@ -0,0 +1,18 @@ +error[E0393]: the const parameter `N` must be explicitly specified + --> $DIR/dyn-compat-const-param-default-mentions-self.rs:18:16 + | +LL | trait X::N }> {} + | -------------------------------------------- const parameter `N` must be specified for this +... +LL | let _: dyn X; + | ^ + | + = note: because the parameter default references `Self`, the parameter must be specified on the trait object type +help: explicitly specify the const parameter + | +LL | let _: dyn X; + | +++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0393`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs new file mode 100644 index 000000000000..9564903dce5b --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs @@ -0,0 +1,22 @@ +// Check that we reject const projections behind trait aliases that mention `Self`. +// The code below is pretty artifical and contains a type mismatch anyway but we still need to +// reject it & lower the `Self` ty param to a `{type error}` to avoid ICEs down the line. +// +// The author of the trait object type can't fix this unlike the supertrait bound +// equivalent where they just need to explicitly specify the assoc const. + +#![feature(min_generic_const_args, trait_alias)] +#![expect(incomplete_features)] + +trait Trait { + type const Y: i32; +} + +struct Hold(T); + +trait Bound = Trait }>; +//~^ ERROR the constant `Hold::` is not of type `i32` + +fn main() { + let _: dyn Bound; //~ ERROR associated constant binding in trait object type mentions `Self` +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr new file mode 100644 index 000000000000..699b9192cf93 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-behind-trait-alias-mentions-self.stderr @@ -0,0 +1,23 @@ +error: the constant `Hold::` is not of type `i32` + --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:17:21 + | +LL | trait Bound = Trait }>; + | ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found struct constructor + | +note: required by a const generic parameter in `Bound` + --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:17:21 + | +LL | trait Bound = Trait }>; + | ^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Bound` + +error: associated constant binding in trait object type mentions `Self` + --> $DIR/dyn-compat-const-projection-behind-trait-alias-mentions-self.rs:21:12 + | +LL | trait Bound = Trait }>; + | -------------------- this binding mentions `Self` +... +LL | let _: dyn Bound; + | ^^^^^^^^^ contains a mention of `Self` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.rs new file mode 100644 index 000000000000..560a1b7f3f7a --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.rs @@ -0,0 +1,18 @@ +// Test that we force users to explicitly specify associated constants (via bindings) +// which reference the `Self` type parameter. + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait X: Y { + type const Q: usize; +} + +trait Y { + type const K: usize; +} + +fn main() { + let _: dyn X; + //~^ ERROR the value of the associated constant `K` in `Y` must be specified +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.stderr new file mode 100644 index 000000000000..dae9e3d8c22b --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-const-projection-from-supertrait-mentions-self.stderr @@ -0,0 +1,12 @@ +error[E0191]: the value of the associated constant `K` in `Y` must be specified + --> $DIR/dyn-compat-const-projection-from-supertrait-mentions-self.rs:16:16 + | +LL | type const K: usize; + | ------------------- `K` defined here +... +LL | let _: dyn X; + | ^^^^^^^^^ help: specify the associated constant: `X` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-generic-assoc-const.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-generic-assoc-const.rs new file mode 100644 index 000000000000..05e8aeea5ed5 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-generic-assoc-const.rs @@ -0,0 +1,16 @@ +// Ensure that traits with generic associated consts (GACs) are dyn *in*compatible. +// It would be very hard to make dyn Trait with GACs sound just like with GATs. + +//@ dont-require-annotations: NOTE + +#![feature(min_generic_const_args, generic_const_items)] +#![expect(incomplete_features)] + +trait Trait { + const POLY: T; + //~^ NOTE it contains generic associated const `POLY` +} + +fn main() { + let _: dyn Trait; //~ ERROR the trait `Trait` is not dyn compatible +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-generic-assoc-const.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-generic-assoc-const.stderr new file mode 100644 index 000000000000..ed187e0287e9 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-generic-assoc-const.stderr @@ -0,0 +1,19 @@ +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/dyn-compat-generic-assoc-const.rs:15:16 + | +LL | let _: dyn Trait; + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-compat-generic-assoc-const.rs:10:11 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +LL | const POLY: T; + | ^^^^ ...because it contains generic associated const `POLY` + = help: consider moving `POLY` to another trait + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.rs new file mode 100644 index 000000000000..38d593984724 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.rs @@ -0,0 +1,20 @@ +// Ensure that traits with non-type associated consts are dyn *in*compatible. + +//@ dont-require-annotations: NOTE + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + const K: usize; + //~^ NOTE it contains associated const `K` that's not defined as `type const` +} + +fn main() { + let _: dyn Trait; //~ ERROR the trait `Trait` is not dyn compatible + + // Check that specifying the non-type assoc const doesn't "magically make it work". + let _: dyn Trait; + //~^ ERROR the trait `Trait` is not dyn compatible + //~| ERROR use of trait associated const not defined as `type const` +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.stderr new file mode 100644 index 000000000000..5bc072e98c0f --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-non-type-assoc-const.stderr @@ -0,0 +1,43 @@ +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/dyn-compat-non-type-assoc-const.rs:14:16 + | +LL | let _: dyn Trait; + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-compat-non-type-assoc-const.rs:9:11 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +LL | const K: usize; + | ^ ...because it contains associated const `K` that's not defined as `type const` + = help: consider moving `K` to another trait + +error: use of trait associated const not defined as `type const` + --> $DIR/dyn-compat-non-type-assoc-const.rs:17:22 + | +LL | let _: dyn Trait; + | ^^^^^ + | + = note: the declaration in the trait must begin with `type const` not just `const` alone + +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/dyn-compat-non-type-assoc-const.rs:17:16 + | +LL | let _: dyn Trait; + | ^^^^^^^^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-compat-non-type-assoc-const.rs:9:11 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +LL | const K: usize; + | ^ ...because it contains associated const `K` that's not defined as `type const` + = help: consider moving `K` to another trait + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs new file mode 100644 index 000000000000..03f1a526b73a --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs @@ -0,0 +1,22 @@ +// Ensure that the where-clause of assoc consts in dyn-compatible traits are allowed to freely +// reference the `Self` type parameter (contrary to methods) and that such where clauses are +// actually enforced. + +#![feature(min_generic_const_args, generic_const_items)] +#![expect(incomplete_features)] + +trait Trait { + type const N: i32 where Self: Bound; +} + +impl Trait for () { + type const N: i32 = 0; +} + +trait Bound {} + +fn main() { + let _: dyn Trait; // OK + + let _: &dyn Trait = &(); //~ ERROR the trait bound `(): Bound` is not satisfied +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.stderr new file mode 100644 index 000000000000..21e407f8a861 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `(): Bound` is not satisfied + --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:21:32 + | +LL | let _: &dyn Trait = &(); + | ^^^ the trait `Bound` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:16:1 + | +LL | trait Bound {} + | ^^^^^^^^^^^ +note: required by a bound in `Trait::N` + --> $DIR/dyn-compat-self-bound-on-assoc-const-allowed-and-enforced.rs:9:35 + | +LL | type const N: i32 where Self: Bound; + | ^^^^^ required by this bound in `Trait::N` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs new file mode 100644 index 000000000000..623769f5d12f --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.rs @@ -0,0 +1,35 @@ +// FIXME(mgca): Ideally this would compile -- at least if the user annotated the instantiated type +// of the assoc const (but we don't have the syntax for this (yet)). In any case, we +// should not leak `trait_object_dummy_self` (defined as `FreshTy(0)` under the hood) +// to the rest of the compiler and by extension the user via diagnostics. +//@ known-bug: unknown + +#![feature( + adt_const_params, + min_generic_const_args, + unsized_const_params, + generic_const_parameter_types +)] +#![expect(incomplete_features)] + +trait A { + type Ty: std::marker::ConstParamTy_; + type const CT: Self::Ty; +} + +impl A for () { + type Ty = i32; + type const CT: i32 = 0; +} + +fn main() { + // NOTE: As alluded to above, if we can't get the examples below to compile as written, + // we might want to allow the user to manually specify the instantiated type somehow. + // The hypothetical syntax for that *might* look sth. like + // * `dyn A i32 { 0 }>` + // * `dyn A` + + let _: dyn A; + + let _: &dyn A = &(); +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr new file mode 100644 index 000000000000..cc08c25906b6 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-assoc-const-ty.stderr @@ -0,0 +1,27 @@ +error[E0277]: the trait bound `FreshTy(0): A` is not satisfied + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:32:33 + | +LL | let _: dyn A; + | ^ the trait `A` is not implemented for `FreshTy(0)` + | +help: the trait `A` is implemented for `()` + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1 + | +LL | impl A for () { + | ^^^^^^^^^^^^^ + +error[E0277]: the trait bound `FreshTy(0): A` is not satisfied + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:34:34 + | +LL | let _: &dyn A = &(); + | ^ the trait `A` is not implemented for `FreshTy(0)` + | +help: the trait `A` is implemented for `()` + --> $DIR/dyn-compat-self-const-projections-in-assoc-const-ty.rs:20:1 + | +LL | impl A for () { + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-methods.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-methods.rs new file mode 100644 index 000000000000..9886213743c8 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-methods.rs @@ -0,0 +1,53 @@ +// While mentioning `Self` in the method signature of dyn compatible traits is generally forbidden +// due to type erasure, we can make an exception for const projections from `Self` where the trait +// is the principal trait or a supertrait thereof. That's sound because we force users to specify +// all associated consts in the trait object type, so the projections are all normalizable. +// +// Check that we can define & use dyn compatible traits that reference `Self` const projections. + +// This is a run-pass test to ensure that codegen can actually deal with such method instances +// (e.g., const projections normalize flawlessly to something concrete, symbols get mangled +// properly, the vtable is fine) and simply to ensure that the generated code "received" the +// correct values from the type assoc consts). +//@ run-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + type const N: usize; + + fn process(&self, _: [u8; Self::N]) -> [u8; Self::N]; +} + +impl Trait for u8 { + type const N: usize = 2; + + fn process(&self, [x, y]: [u8; Self::N]) -> [u8; Self::N] { + [self * x, self + y] + } +} + +impl Trait for [u8; N] { + type const N: usize = N; + + fn process(&self, other: [u8; Self::N]) -> [u8; Self::N] { + let mut result = [0; _]; + for i in 0..Self::N { + result[i] = self[i] + other[i]; + } + result + } +} + +fn main() { + let ops: [Box>; _] = [Box::new(3), Box::new([1, 1])]; + + let mut data = [16, 32]; + + for op in ops { + data = op.process(data); + } + + assert_eq!(data, [49, 36]); +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.rs new file mode 100644 index 000000000000..f2ae98accda5 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.rs @@ -0,0 +1,19 @@ +// Ensure that we reject the `Self` type parameter in supertrait bounds of dyn-compatible traits +// even if they're part of a "`Self` projection" (contrary to method signatures and the type of +// assoc consts). + +//@ dont-require-annotations: NOTE + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait: SuperTrait<{ Self::N }> { +//~^ NOTE it uses `Self` as a type parameter + type const N: usize; +} + +trait SuperTrait {} + +fn main() { + let _: dyn Trait; //~ ERROR the trait `Trait` is not dyn compatible +} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.stderr new file mode 100644 index 000000000000..38c928fd58d7 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-self-const-projections-in-supertrait-bounds.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/dyn-compat-self-const-projections-in-supertrait-bounds.rs:18:16 + | +LL | let _: dyn Trait; + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/dyn-compat-self-const-projections-in-supertrait-bounds.rs:10:14 + | +LL | trait Trait: SuperTrait<{ Self::N }> { + | ----- ^^^^^^^^^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait is not dyn compatible... + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.rs new file mode 100644 index 000000000000..52ecd42b191d --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.rs @@ -0,0 +1,27 @@ +// Ensure that we can successfully mangle & demangle trait object types w/ assoc const bindings. + +// FIXME(mgca): Legacy mangling still crashes: +// "finding type for [impl], encountered [crate root] with no parent" + +//@ build-fail +//@ revisions: v0 +//\@[legacy] compile-flags: -C symbol-mangling-version=legacy -Z unstable-options +//@ [v0] compile-flags: -C symbol-mangling-version=v0 +//\@[legacy] normalize-stderr: "h[[:xdigit:]]{16}" -> "h[HASH]" +//@ [v0] normalize-stderr: "sym\[.*?\]" -> "sym[HASH]" + +#![feature(min_generic_const_args, rustc_attrs)] +#![expect(incomplete_features)] +#![crate_name = "sym"] + +trait Trait { + type const N: usize; +} + +#[rustc_symbol_name] +//~^ ERROR symbol-name(_RMCs +//~| ERROR demangling(>) +impl dyn Trait {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.v0.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.v0.stderr new file mode 100644 index 000000000000..8ca0f73494d3 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-symbol-mangling.v0.stderr @@ -0,0 +1,20 @@ +error: symbol-name(_RMCsCRATE_HASH_3symDNtB_5Traitp1NKj0_EL_) + --> $DIR/dyn-compat-symbol-mangling.rs:21:1 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/dyn-compat-symbol-mangling.rs:21:1 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/dyn-compat-symbol-mangling.rs:21:1 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs new file mode 100644 index 000000000000..5bd8aa609420 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.rs @@ -0,0 +1,24 @@ +// Traits with type associated consts are dyn compatible. However, all associated consts must +// be specified in the corresp. trait object type (barring exceptions) similiar to associated +// types. Check that we reject code that doesn't provide the necessary bindings. + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { + type const K: usize; +} + +// fn ctxt / body +fn main() { + let _: dyn Trait; + //~^ ERROR the value of the associated constant `K` in `Trait` must be specified +} + +// item ctxt / signature / non-body +struct Store(dyn Trait); +//~^ ERROR the value of the associated constant `K` in `Trait` must be specified + +// item ctxt & no wfcking (eager ty alias) +type DynTrait = dyn Trait; +//~^ ERROR the value of the associated constant `K` in `Trait` must be specified diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.stderr b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.stderr new file mode 100644 index 000000000000..35fdd7f2751e --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-compat-unspecified-assoc-consts.stderr @@ -0,0 +1,30 @@ +error[E0191]: the value of the associated constant `K` in `Trait` must be specified + --> $DIR/dyn-compat-unspecified-assoc-consts.rs:19:18 + | +LL | type const K: usize; + | ------------------- `K` defined here +... +LL | struct Store(dyn Trait); + | ^^^^^ help: specify the associated constant: `Trait` + +error[E0191]: the value of the associated constant `K` in `Trait` must be specified + --> $DIR/dyn-compat-unspecified-assoc-consts.rs:23:21 + | +LL | type const K: usize; + | ------------------- `K` defined here +... +LL | type DynTrait = dyn Trait; + | ^^^^^ help: specify the associated constant: `Trait` + +error[E0191]: the value of the associated constant `K` in `Trait` must be specified + --> $DIR/dyn-compat-unspecified-assoc-consts.rs:14:16 + | +LL | type const K: usize; + | ------------------- `K` defined here +... +LL | let _: dyn Trait; + | ^^^^^ help: specify the associated constant: `Trait` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/const-generics/associated-const-bindings/dyn-const-projection-escaping-bound-vars.rs b/tests/ui/const-generics/associated-const-bindings/dyn-const-projection-escaping-bound-vars.rs new file mode 100644 index 000000000000..c2ae86232a02 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/dyn-const-projection-escaping-bound-vars.rs @@ -0,0 +1,11 @@ +//! Check associated const binding with escaping bound vars doesn't cause ICE +//! (#151642) +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait2<'a> { type const ASSOC: i32; } +fn g(_: for<'a> fn(Box>)) {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs b/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs new file mode 100644 index 000000000000..f42589f91d15 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/equality-unused-issue-126729.rs @@ -0,0 +1,45 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] +#![deny(dead_code)] + +trait Tr { + type const I: i32; +} + +impl Tr for () { + type const I: i32 = 1; +} + +fn foo() -> impl Tr {} + +trait Tr2 { + type const J: i32; + type const K: i32; +} + +impl Tr2 for () { + type const J: i32 = 1; + type const K: i32 = 1; +} + +fn foo2() -> impl Tr2 {} + +mod t { + pub trait Tr3 { + type const L: i32; + } + + impl Tr3 for () { + type const L: i32 = 1; + } +} + +fn foo3() -> impl t::Tr3 {} + +fn main() { + foo(); + foo2(); + foo3(); +} diff --git a/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs b/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs new file mode 100644 index 000000000000..e50c13b5d3b5 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/equality_bound_with_infer.rs @@ -0,0 +1,21 @@ +//@ check-pass + +#![feature(min_generic_const_args, generic_const_items)] +#![expect(incomplete_features)] + +// Regression test for #133066 where we would try to evaluate `<() as Foo>::ASSOC<_>` even +// though it contained inference variables, which would cause ICEs. + +trait Foo { + type const ASSOC: u32; +} + +impl Foo for () { + type const ASSOC: u32 = N; +} + +fn bar = 10>>() {} + +fn main() { + bar::<_, ()>(); +} diff --git a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs new file mode 100644 index 000000000000..de888c5a7939 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.rs @@ -0,0 +1,21 @@ +// Detect and reject escaping late-bound generic params in +// the type of assoc consts used in an equality bound. +#![feature( + adt_const_params, + min_generic_const_args, + unsized_const_params, + generic_const_parameter_types, +)] +#![allow(incomplete_features)] + +trait Trait<'a> { + type const K: &'a (); +} + +fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} +//~^ ERROR the type of the associated constant `K` cannot capture late-bound generic parameters +//~| NOTE its type cannot capture the late-bound lifetime parameter `'r` +//~| NOTE the late-bound lifetime parameter `'r` is defined here +//~| NOTE `K` has type `&'r ()` + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr new file mode 100644 index 000000000000..122893662933 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/esc-bound-var-in-ty.stderr @@ -0,0 +1,12 @@ +error: the type of the associated constant `K` cannot capture late-bound generic parameters + --> $DIR/esc-bound-var-in-ty.rs:15:35 + | +LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {} + | -- ^ its type cannot capture the late-bound lifetime parameter `'r` + | | + | the late-bound lifetime parameter `'r` is defined here + | + = note: `K` has type `&'r ()` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs b/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs new file mode 100644 index 000000000000..1663cad13c7c --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/issue-102335-const.rs @@ -0,0 +1,14 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +trait T { + type A: S = 34>; + //~^ ERROR associated item constraints are not allowed here + //~| ERROR associated item constraints are not allowed here +} + +trait S { + type const C: i32; +} + +fn main() {} diff --git a/tests/ui/associated-consts/issue-102335-const.stderr b/tests/ui/const-generics/associated-const-bindings/issue-102335-const.stderr similarity index 100% rename from tests/ui/associated-consts/issue-102335-const.stderr rename to tests/ui/const-generics/associated-const-bindings/issue-102335-const.stderr diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/const-generics/associated-const-bindings/issue-105330.rs similarity index 100% rename from tests/ui/associated-consts/issue-105330.rs rename to tests/ui/const-generics/associated-const-bindings/issue-105330.rs diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/const-generics/associated-const-bindings/issue-105330.stderr similarity index 89% rename from tests/ui/associated-consts/issue-105330.stderr rename to tests/ui/const-generics/associated-const-bindings/issue-105330.stderr index 5d6dc48e36c0..06900404ec34 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/const-generics/associated-const-bindings/issue-105330.stderr @@ -21,8 +21,8 @@ error[E0658]: associated const equality is incomplete LL | fn foo>() { | ^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -31,8 +31,8 @@ error[E0658]: associated const equality is incomplete LL | fn main>() { | ^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0562]: `impl Trait` is not allowed in impl headers diff --git a/tests/ui/const-generics/associated-const-bindings/issue-93835.rs b/tests/ui/const-generics/associated-const-bindings/issue-93835.rs new file mode 100644 index 000000000000..26d0bbe3a40f --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/issue-93835.rs @@ -0,0 +1,12 @@ +#![feature(type_ascription)] + +fn e() { + type_ascribe!(p, a>); + //~^ ERROR cannot find type `a` in this scope + //~| ERROR cannot find value + //~| ERROR associated const equality is incomplete + //~| ERROR cannot find trait `p` in this scope + //~| ERROR associated const equality is incomplete +} + +fn main() {} diff --git a/tests/ui/associated-consts/issue-93835.stderr b/tests/ui/const-generics/associated-const-bindings/issue-93835.stderr similarity index 77% rename from tests/ui/associated-consts/issue-93835.stderr rename to tests/ui/const-generics/associated-const-bindings/issue-93835.stderr index 3f1679890130..990d22bba4de 100644 --- a/tests/ui/associated-consts/issue-93835.stderr +++ b/tests/ui/const-generics/associated-const-bindings/issue-93835.stderr @@ -22,8 +22,8 @@ error[E0658]: associated const equality is incomplete LL | type_ascribe!(p, a>); | ^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: associated const equality is incomplete @@ -32,8 +32,8 @@ error[E0658]: associated const equality is incomplete LL | type_ascribe!(p, a>); | ^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.rs similarity index 100% rename from tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.rs rename to tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.rs diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.stderr similarity index 83% rename from tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr rename to tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.stderr index 0b487b6a7aa0..d2f28a62e04e 100644 --- a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace-no-feature-gate.stderr +++ b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace-no-feature-gate.stderr @@ -1,13 +1,3 @@ -error[E0658]: associated const equality is incomplete - --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:7:38 - | -LL | fn take0(_: impl Owner = { N }>) {} - | ^^^^^^^^^^^^ - | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` 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[E0658]: generic const items are experimental --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:2:12 | @@ -18,6 +8,16 @@ LL | const C: u32 = N; = help: add `#![feature(generic_const_items)]` 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[E0658]: associated const equality is incomplete + --> $DIR/mismatched-types-with-generic-in-ace-no-feature-gate.rs:7:38 + | +LL | fn take0(_: impl Owner = { N }>) {} + | ^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs new file mode 100644 index 000000000000..1c6e873b98c3 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.rs @@ -0,0 +1,18 @@ +#![feature(generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] + +trait Foo { + type const ASSOC: u32; +} + +impl Foo for () { + type const ASSOC: u32 = N; +} + +fn bar = { N }>>() {} +//~^ ERROR: the constant `N` is not of type `u32` + +fn main() { + bar::<10_u64, ()>(); + //~^ ERROR: the constant `10` is not of type `u32` +} diff --git a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr new file mode 100644 index 000000000000..b447cd08a214 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr @@ -0,0 +1,26 @@ +error: the constant `N` is not of type `u32` + --> $DIR/mismatched-types-with-generic-in-ace.rs:12:29 + | +LL | fn bar = { N }>>() {} + | ^^^^^^^^^^^^^^^^ expected `u32`, found `u64` + | +note: required by a const generic parameter in `Foo::ASSOC` + --> $DIR/mismatched-types-with-generic-in-ace.rs:5:22 + | +LL | type const ASSOC: u32; + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` + +error: the constant `10` is not of type `u32` + --> $DIR/mismatched-types-with-generic-in-ace.rs:16:5 + | +LL | bar::<10_u64, ()>(); + | ^^^^^^^^^^^^^^^^^^^ expected `u32`, found `u64` + | +note: required by a const generic parameter in `Foo::ASSOC` + --> $DIR/mismatched-types-with-generic-in-ace.rs:5:22 + | +LL | type const ASSOC: u32; + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/associated-const-bindings/missing.rs b/tests/ui/const-generics/associated-const-bindings/missing.rs new file mode 100644 index 000000000000..22b565cb27d2 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/missing.rs @@ -0,0 +1,25 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features, unused)] + +pub trait Foo { + const N: usize; +} + +pub struct Bar; + +impl Foo for Bar { + const N: usize = 3; +} + +fn foo1>() {} +//~^ ERROR associated constant `Z` not found for `Foo` +fn foo2>() {} +//~^ ERROR associated type `Z` not found for `Foo` +fn foo3>() {} +//~^ ERROR associated constant `Z` not found for `Foo` + +fn main() { + foo1::(); + foo2::(); + foo3::(); +} diff --git a/tests/ui/const-generics/associated-const-bindings/missing.stderr b/tests/ui/const-generics/associated-const-bindings/missing.stderr new file mode 100644 index 000000000000..cbcfcf4c62d1 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/missing.stderr @@ -0,0 +1,21 @@ +error[E0220]: associated constant `Z` not found for `Foo` + --> $DIR/missing.rs:14:16 + | +LL | fn foo1>() {} + | ^ help: there is an associated constant with a similar name: `N` + +error[E0220]: associated type `Z` not found for `Foo` + --> $DIR/missing.rs:16:16 + | +LL | fn foo2>() {} + | ^ associated type `Z` not found + +error[E0220]: associated constant `Z` not found for `Foo` + --> $DIR/missing.rs:18:16 + | +LL | fn foo3>() {} + | ^ help: there is an associated constant with a similar name: `N` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs new file mode 100644 index 000000000000..a1efa74090bb --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/normalization-via-param-env.rs @@ -0,0 +1,17 @@ +//@ check-pass +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +// Regression test for normalizing const projections +// with associated const equality bounds. + +trait Trait { + type const C: usize; +} + +fn f>() { + // This must normalize ::C to 1 + let _: [(); T::C] = [()]; +} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs b/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs new file mode 100644 index 000000000000..4d67186f71f9 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/param-in-ty.rs @@ -0,0 +1,79 @@ +// Regression test for issue #108271. +// Detect and reject generic params in the type of assoc consts used in an equality bound. +#![feature( + min_generic_const_args, + adt_const_params, + unsized_const_params, + generic_const_parameter_types, +)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> { + type const K: &'a [T; N]; +} + +fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + //~^ NOTE the lifetime parameter `'r` is defined here + //~| NOTE the type parameter `A` is defined here + //~| NOTE the const parameter `Q` is defined here + _: impl Trait<'r, A, Q, K = const { loop {} }> + //~^ ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the lifetime parameter `'r` + //~| NOTE `K` has type `&'r [A; Q]` + //~| ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the type parameter `A` + //~| NOTE `K` has type `&'r [A; Q]` + //~| ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the const parameter `Q` + //~| NOTE `K` has type `&'r [A; Q]` +) {} + +trait Project: ConstParamTy_ { + type const SELF: Self; +} + +fn take1(_: impl Project) {} +//~^ ERROR the type of the associated constant `SELF` must not depend on `impl Trait` +//~| NOTE its type must not depend on `impl Trait` +//~| NOTE the `impl Trait` is specified here + +fn take2>(_: P) {} +//~^ ERROR the type of the associated constant `SELF` must not depend on generic parameters +//~| NOTE its type must not depend on the type parameter `P` +//~| NOTE the type parameter `P` is defined here +//~| NOTE `SELF` has type `P` + +trait Iface<'r>: ConstParamTy_ { + //~^ NOTE the lifetime parameter `'r` is defined here + //~| NOTE the lifetime parameter `'r` is defined here + type Assoc: Trait<'r, Self, Q, K = const { loop {} }> + //~^ ERROR the type of the associated constant `K` must not depend on generic parameters + //~| ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the lifetime parameter `'r` + //~| NOTE `K` has type `&'r [Self; Q]` + //~| ERROR the type of the associated constant `K` must not depend on `Self` + //~| NOTE its type must not depend on `Self` + //~| NOTE `K` has type `&'r [Self; Q]` + //~| ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the const parameter `Q` + //~| NOTE the const parameter `Q` is defined here + //~| NOTE `K` has type `&'r [Self; Q]` + //~| NOTE its type must not depend on the lifetime parameter `'r` + //~| NOTE `K` has type `&'r [Self; Q]` + //~| ERROR the type of the associated constant `K` must not depend on `Self` + //~| NOTE its type must not depend on `Self` + //~| NOTE `K` has type `&'r [Self; Q]` + //~| ERROR the type of the associated constant `K` must not depend on generic parameters + //~| NOTE its type must not depend on the const parameter `Q` + //~| NOTE the const parameter `Q` is defined here + //~| NOTE `K` has type `&'r [Self; Q]` + //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + where + Self: Sized + 'r; +} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr b/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr new file mode 100644 index 000000000000..2ef3fab7e5ff --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/param-in-ty.stderr @@ -0,0 +1,115 @@ +error: the type of the associated constant `K` must not depend on generic parameters + --> $DIR/param-in-ty.rs:21:29 + | +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + | -- the lifetime parameter `'r` is defined here +... +LL | _: impl Trait<'r, A, Q, K = const { loop {} }> + | ^ its type must not depend on the lifetime parameter `'r` + | + = note: `K` has type `&'r [A; Q]` + +error: the type of the associated constant `K` must not depend on generic parameters + --> $DIR/param-in-ty.rs:21:29 + | +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + | - the type parameter `A` is defined here +... +LL | _: impl Trait<'r, A, Q, K = const { loop {} }> + | ^ its type must not depend on the type parameter `A` + | + = note: `K` has type `&'r [A; Q]` + +error: the type of the associated constant `K` must not depend on generic parameters + --> $DIR/param-in-ty.rs:21:29 + | +LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>( + | - the const parameter `Q` is defined here +... +LL | _: impl Trait<'r, A, Q, K = const { loop {} }> + | ^ its type must not depend on the const parameter `Q` + | + = note: `K` has type `&'r [A; Q]` + +error: the type of the associated constant `SELF` must not depend on `impl Trait` + --> $DIR/param-in-ty.rs:37:26 + | +LL | fn take1(_: impl Project) {} + | -------------^^^^------------ + | | | + | | its type must not depend on `impl Trait` + | the `impl Trait` is specified here + +error: the type of the associated constant `SELF` must not depend on generic parameters + --> $DIR/param-in-ty.rs:42:21 + | +LL | fn take2>(_: P) {} + | - ^^^^ its type must not depend on the type parameter `P` + | | + | the type parameter `P` is defined here + | + = note: `SELF` has type `P` + +error: the type of the associated constant `K` must not depend on generic parameters + --> $DIR/param-in-ty.rs:51:52 + | +LL | trait Iface<'r>: ConstParamTy_ { + | -- the lifetime parameter `'r` is defined here +... +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> + | ^ its type must not depend on the lifetime parameter `'r` + | + = note: `K` has type `&'r [Self; Q]` + +error: the type of the associated constant `K` must not depend on `Self` + --> $DIR/param-in-ty.rs:51:52 + | +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> + | ^ its type must not depend on `Self` + | + = note: `K` has type `&'r [Self; Q]` + +error: the type of the associated constant `K` must not depend on generic parameters + --> $DIR/param-in-ty.rs:51:52 + | +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> + | - ^ its type must not depend on the const parameter `Q` + | | + | the const parameter `Q` is defined here + | + = note: `K` has type `&'r [Self; Q]` + +error: the type of the associated constant `K` must not depend on generic parameters + --> $DIR/param-in-ty.rs:51:52 + | +LL | trait Iface<'r>: ConstParamTy_ { + | -- the lifetime parameter `'r` is defined here +... +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> + | ^ its type must not depend on the lifetime parameter `'r` + | + = note: `K` has type `&'r [Self; Q]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: the type of the associated constant `K` must not depend on `Self` + --> $DIR/param-in-ty.rs:51:52 + | +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> + | ^ its type must not depend on `Self` + | + = note: `K` has type `&'r [Self; Q]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: the type of the associated constant `K` must not depend on generic parameters + --> $DIR/param-in-ty.rs:51:52 + | +LL | type Assoc: Trait<'r, Self, Q, K = const { loop {} }> + | - ^ its type must not depend on the const parameter `Q` + | | + | the const parameter `Q` is defined here + | + = note: `K` has type `&'r [Self; Q]` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 11 previous errors + diff --git a/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs new file mode 100644 index 000000000000..dbfbba9b7cbd --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.rs @@ -0,0 +1,17 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +// Issue 110549 + +pub trait TraitWAssocConst { + type const A: usize; +} + +fn foo>() {} + +fn bar() { + foo::(); + //~^ ERROR type mismatch resolving `::A == 32` +} + +fn main() {} diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr similarity index 82% rename from tests/ui/associated-consts/projection-unspecified-but-bounded.stderr rename to tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr index 232b15b7e981..11490a044091 100644 --- a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr +++ b/tests/ui/const-generics/associated-const-bindings/projection-unspecified-but-bounded.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/projection-unspecified-but-bounded.rs:14:11 + --> $DIR/projection-unspecified-but-bounded.rs:13:11 | LL | foo::(); | ^ expected `32`, found `::A` @@ -7,7 +7,7 @@ LL | foo::(); = note: expected constant `32` found constant `::A` note: required by a bound in `foo` - --> $DIR/projection-unspecified-but-bounded.rs:11:28 + --> $DIR/projection-unspecified-but-bounded.rs:10:28 | LL | fn foo>() {} | ^^^^^^ required by this bound in `foo` diff --git a/tests/ui/const-generics/associated-const-bindings/supertraits.rs b/tests/ui/const-generics/associated-const-bindings/supertraits.rs new file mode 100644 index 000000000000..cdceb682a854 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/supertraits.rs @@ -0,0 +1,24 @@ +// Regression test for issue #118040. +// Ensure that we support assoc const eq bounds where the assoc const comes from a supertrait. + +//@ check-pass + +#![feature( + min_generic_const_args, + adt_const_params, + unsized_const_params, + generic_const_parameter_types, +)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy_; + +trait Trait: SuperTrait {} +trait SuperTrait: SuperSuperTrait {} +trait SuperSuperTrait { + type const K: T; +} + +fn take(_: impl Trait) {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.rs b/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.rs new file mode 100644 index 000000000000..f2b581412a72 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.rs @@ -0,0 +1,22 @@ +//@ edition:2015 +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +pub enum Mode { + Cool, +} + +pub trait Parse { + const MODE: Mode; +} + +pub trait CoolStuff: Parse {} +//~^ ERROR expected constant, found type +//~| ERROR expected constant, found type +//~| ERROR expected constant, found type +//~| ERROR expected type + +fn no_help() -> Mode::Cool {} +//~^ ERROR expected type, found variant + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.stderr b/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.stderr new file mode 100644 index 000000000000..6608df2ebfbc --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/unbraced-enum-variant.stderr @@ -0,0 +1,77 @@ +error[E0573]: expected type, found variant `Mode::Cool` + --> $DIR/unbraced-enum-variant.rs:13:35 + | +LL | pub trait CoolStuff: Parse {} + | ^^^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Mode` + +error[E0573]: expected type, found variant `Mode::Cool` + --> $DIR/unbraced-enum-variant.rs:19:17 + | +LL | fn no_help() -> Mode::Cool {} + | ^^^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Mode` + +error: expected constant, found type + --> $DIR/unbraced-enum-variant.rs:13:35 + | +LL | pub trait CoolStuff: Parse {} + | ---- ^^^^^^^^^^ unexpected type + | | + | expected a constant because of this associated constant + | +note: the associated constant is defined here + --> $DIR/unbraced-enum-variant.rs:10:5 + | +LL | const MODE: Mode; + | ^^^^^^^^^^^^^^^^ +help: consider adding braces here + | +LL | pub trait CoolStuff: Parse {} + | + + + +error: expected constant, found type + --> $DIR/unbraced-enum-variant.rs:13:35 + | +LL | pub trait CoolStuff: Parse {} + | ---- ^^^^^^^^^^ unexpected type + | | + | expected a constant because of this associated constant + | +note: the associated constant is defined here + --> $DIR/unbraced-enum-variant.rs:10:5 + | +LL | const MODE: Mode; + | ^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider adding braces here + | +LL | pub trait CoolStuff: Parse {} + | + + + +error: expected constant, found type + --> $DIR/unbraced-enum-variant.rs:13:35 + | +LL | pub trait CoolStuff: Parse {} + | ---- ^^^^^^^^^^ unexpected type + | | + | expected a constant because of this associated constant + | +note: the associated constant is defined here + --> $DIR/unbraced-enum-variant.rs:10:5 + | +LL | const MODE: Mode; + | ^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider adding braces here + | +LL | pub trait CoolStuff: Parse {} + | + + + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0573`. diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.rs similarity index 90% rename from tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs rename to tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.rs index edadcd7c80ed..f28f3f694ff3 100644 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.rs +++ b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.rs @@ -12,7 +12,7 @@ impl AssocConst for (T,) { trait Trait {} -impl Trait for () where (U,): AssocConst {} +impl Trait for () where (U,): AssocConst {} //~^ ERROR associated const equality is incomplete //~| ERROR the type parameter `U` is not constrained by the impl trait diff --git a/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr new file mode 100644 index 000000000000..c34674604b51 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/unconstrained_impl_param.stderr @@ -0,0 +1,26 @@ +error[E0658]: associated const equality is incomplete + --> $DIR/unconstrained_impl_param.rs:15:45 + | +LL | impl Trait for () where (U,): AssocConst {} + | ^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates + --> $DIR/unconstrained_impl_param.rs:15:6 + | +LL | impl Trait for () where (U,): AssocConst {} + | ^ unconstrained type parameter + +error[E0282]: type annotations needed + --> $DIR/unconstrained_impl_param.rs:21:5 + | +LL | (): Trait, + | ^^^^^^^^^ cannot infer type for type parameter `U` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0207, E0282, E0658. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs new file mode 100644 index 000000000000..95f81323acf4 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.rs @@ -0,0 +1,13 @@ +// Regression test for #119783 + +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +trait Trait { + type const F: fn(); + //~^ ERROR using function pointers as const generic parameters is forbidden +} + +fn take(_: impl Trait) {} + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr new file mode 100644 index 000000000000..333dd1b89e9b --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/using-fnptr-as-type_const.stderr @@ -0,0 +1,9 @@ +error[E0741]: using function pointers as const generic parameters is forbidden + --> $DIR/using-fnptr-as-type_const.rs:7:19 + | +LL | type const F: fn(); + | ^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs new file mode 100644 index 000000000000..1beeb07e995a --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.rs @@ -0,0 +1,11 @@ +//! Check that we correctly handle associated const bindings +//! in `impl Trait` where the RHS is a const param (#151642). + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { type const CT: bool; } + +fn f(_: impl Trait) {} +//~^ ERROR the constant `N` is not of type `bool` +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr new file mode 100644 index 000000000000..56e01e640078 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr @@ -0,0 +1,14 @@ +error: the constant `N` is not of type `bool` + --> $DIR/wf-mismatch-1.rs:9:34 + | +LL | fn f(_: impl Trait) {} + | ^^^^^^^^^^ expected `bool`, found `i32` + | +note: required by a const generic parameter in `f` + --> $DIR/wf-mismatch-1.rs:9:34 + | +LL | fn f(_: impl Trait) {} + | ^^^^^^^^^^ required by this const generic parameter in `f` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs new file mode 100644 index 000000000000..7a75b6da78c5 --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.rs @@ -0,0 +1,13 @@ +//! Check that we correctly handle associated const bindings +//! in `dyn Trait` where the RHS is a const param (#151642). + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { type const CT: bool; } + +fn f() { + let _: dyn Trait; + //~^ ERROR the constant `N` is not of type `bool` +} +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr new file mode 100644 index 000000000000..8169cc07fc5f --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr @@ -0,0 +1,8 @@ +error: the constant `N` is not of type `bool` + --> $DIR/wf-mismatch-2.rs:10:12 + | +LL | let _: dyn Trait; + | ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs new file mode 100644 index 000000000000..3eeb7703aa2b --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.rs @@ -0,0 +1,17 @@ +//! Check that we correctly handle associated const bindings +//! where the RHS is a normalizable const projection (#151642). + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait { type const CT: bool; } + +trait Bound { type const N: u32; } +impl Bound for () { type const N: u32 = 0; } + +fn f() { let _: dyn Trait::N }>; } +//~^ ERROR the constant `0` is not of type `bool` +fn g(_: impl Trait::N }>) {} +//~^ ERROR the constant `0` is not of type `bool` + +fn main() {} diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.stderr new file mode 100644 index 000000000000..ac21527e04ed --- /dev/null +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-3.stderr @@ -0,0 +1,20 @@ +error: the constant `0` is not of type `bool` + --> $DIR/wf-mismatch-3.rs:14:20 + | +LL | fn g(_: impl Trait::N }>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `u32` + | +note: required by a const generic parameter in `g` + --> $DIR/wf-mismatch-3.rs:14:20 + | +LL | fn g(_: impl Trait::N }>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `g` + +error: the constant `0` is not of type `bool` + --> $DIR/wf-mismatch-3.rs:12:17 + | +LL | fn f() { let _: dyn Trait::N }>; } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `u32` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/associated_const_equality/coherence.rs b/tests/ui/const-generics/associated_const_equality/coherence.rs deleted file mode 100644 index fb5f255c1dc4..000000000000 --- a/tests/ui/const-generics/associated_const_equality/coherence.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![feature(associated_const_equality, min_generic_const_args)] -#![expect(incomplete_features)] - -pub trait IsVoid { - #[type_const] - const IS_VOID: bool; -} -impl IsVoid for () { - #[type_const] - const IS_VOID: bool = true; -} - -pub trait Maybe {} -impl Maybe for () {} -impl Maybe for () where (): IsVoid {} -//~^ ERROR conflicting implementations of trait `Maybe` for type `()` - -fn main() {} diff --git a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs b/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs deleted file mode 100644 index 3973c7af15b4..000000000000 --- a/tests/ui/const-generics/associated_const_equality/equality_bound_with_infer.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ check-pass - -#![feature(associated_const_equality, min_generic_const_args, generic_const_items)] -#![expect(incomplete_features)] - -// Regression test for #133066 where we would try to evaluate `<() as Foo>::ASSOC<_>` even -// though it contained inference variables, which would cause ICEs. - -trait Foo { - #[type_const] - const ASSOC: u32; -} - -impl Foo for () { - #[type_const] - const ASSOC: u32 = N; -} - -fn bar = 10>>() {} - -fn main() { - bar::<_, ()>(); -} diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs deleted file mode 100644 index 33afa7e3228e..000000000000 --- a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.rs +++ /dev/null @@ -1,20 +0,0 @@ -#![feature(generic_const_items, associated_const_equality, min_generic_const_args)] -#![expect(incomplete_features)] - -trait Foo { - #[type_const] - const ASSOC: u32; -} - -impl Foo for () { - #[type_const] - const ASSOC: u32 = N; -} - -fn bar = { N }>>() {} -//~^ ERROR: the constant `N` is not of type `u32` - -fn main() { - bar::<10_u64, ()>(); - //~^ ERROR: the constant `10` is not of type `u32` -} diff --git a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr b/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr deleted file mode 100644 index c2fb7faa3a3a..000000000000 --- a/tests/ui/const-generics/associated_const_equality/mismatched-types-with-generic-in-ace.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: the constant `N` is not of type `u32` - --> $DIR/mismatched-types-with-generic-in-ace.rs:14:29 - | -LL | fn bar = { N }>>() {} - | ^^^^^^^^^^^^^^^^ expected `u32`, found `u64` - | -note: required by a const generic parameter in `Foo::ASSOC` - --> $DIR/mismatched-types-with-generic-in-ace.rs:6:17 - | -LL | const ASSOC: u32; - | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` - -error: the constant `10` is not of type `u32` - --> $DIR/mismatched-types-with-generic-in-ace.rs:18:5 - | -LL | bar::<10_u64, ()>(); - | ^^^^^^^^^^^^^^^^^^^ expected `u32`, found `u64` - | -note: required by a const generic parameter in `Foo::ASSOC` - --> $DIR/mismatched-types-with-generic-in-ace.rs:6:17 - | -LL | const ASSOC: u32; - | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::ASSOC` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr b/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr deleted file mode 100644 index 4106c500215b..000000000000 --- a/tests/ui/const-generics/associated_const_equality/unconstrained_impl_param.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error[E0658]: associated const equality is incomplete - --> $DIR/unconstrained_impl_param.rs:15:45 - | -LL | impl Trait for () where (U,): AssocConst {} - | ^^^^^^^^^ - | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` 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[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/unconstrained_impl_param.rs:15:6 - | -LL | impl Trait for () where (U,): AssocConst {} - | ^ unconstrained type parameter - -error[E0282]: type annotations needed - --> $DIR/unconstrained_impl_param.rs:21:5 - | -LL | (): Trait, - | ^^^^^^^^^ cannot infer type for type parameter `U` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0207, E0282, E0658. -For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/defaults/pretty-printing-ast.stdout b/tests/ui/const-generics/defaults/pretty-printing-ast.stdout index 030fcec9cf2a..efd703b24b43 100644 --- a/tests/ui/const-generics/defaults/pretty-printing-ast.stdout +++ b/tests/ui/const-generics/defaults/pretty-printing-ast.stdout @@ -6,7 +6,6 @@ //@ edition: 2015 #![crate_type = "lib"] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/const-generics/fn-item-as-const-arg-137084.rs b/tests/ui/const-generics/fn-item-as-const-arg-137084.rs new file mode 100644 index 000000000000..8b75a3c8c96d --- /dev/null +++ b/tests/ui/const-generics/fn-item-as-const-arg-137084.rs @@ -0,0 +1,14 @@ +// Regression test for https://github.com/rust-lang/rust/issues/137084 +// Previously caused ICE when using function item as const generic argument + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +fn a() {} +fn d(e: &String) { + a:: + //~^ ERROR mismatched types + //~| ERROR the constant `d` is not of type `i32` +} + +fn main() {} diff --git a/tests/ui/const-generics/fn-item-as-const-arg-137084.stderr b/tests/ui/const-generics/fn-item-as-const-arg-137084.stderr new file mode 100644 index 000000000000..58b74c655cd2 --- /dev/null +++ b/tests/ui/const-generics/fn-item-as-const-arg-137084.stderr @@ -0,0 +1,35 @@ +error[E0308]: mismatched types + --> $DIR/fn-item-as-const-arg-137084.rs:9:5 + | +LL | fn a() {} + | -------------------- function `a` defined here +LL | fn d(e: &String) { +LL | a:: + | ^^^^^^ expected `()`, found fn item + | + = note: expected unit type `()` + found fn item `fn() {a::}` +help: try adding a return type + | +LL | fn d(e: &String) -> fn() { + | +++++++ +help: use parentheses to call this function + | +LL | a::() + | ++ + +error: the constant `d` is not of type `i32` + --> $DIR/fn-item-as-const-arg-137084.rs:9:9 + | +LL | a:: + | ^ expected `i32`, found fn item + | +note: required by a const generic parameter in `a` + --> $DIR/fn-item-as-const-arg-137084.rs:7:6 + | +LL | fn a() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `a` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr index 6cf4e881adae..62bebd53b14a 100644 --- a/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr +++ b/tests/ui/const-generics/generic_const_exprs/assoc_const_unification/doesnt_unify_evaluatable.stderr @@ -1,8 +1,8 @@ error: unconstrained generic constant - --> $DIR/doesnt_unify_evaluatable.rs:9:11 + --> $DIR/doesnt_unify_evaluatable.rs:9:13 | LL | bar::<{ T::ASSOC }>(); - | ^^^^^^^^^^^^ + | ^^^^^^^^ | help: try adding a `where` bound | diff --git a/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs b/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs new file mode 100644 index 000000000000..8cd46783d4fd --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs @@ -0,0 +1,4 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +pub type const NON_LOCAL_CONST: char = 'a'; diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs index f1305202ad45..a6988a492f61 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.rs @@ -2,7 +2,7 @@ //~^ WARN the feature `generic_const_exprs` is incomplete fn foo() { - let _ = [0u8; const { std::mem::size_of::() }]; + let _ = [0u8; { const { std::mem::size_of::() } }]; //~^ ERROR: overly complex generic constant } diff --git a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr index 03b0004bf0bd..db547e6a2481 100644 --- a/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr +++ b/tests/ui/const-generics/generic_const_exprs/const-block-is-poly.stderr @@ -10,8 +10,10 @@ LL | #![feature(generic_const_exprs)] error: overly complex generic constant --> $DIR/const-block-is-poly.rs:5:19 | -LL | let _ = [0u8; const { std::mem::size_of::() }]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ const blocks are not supported in generic constants +LL | let _ = [0u8; { const { std::mem::size_of::() } }]; + | ^^----------------------------------^^ + | | + | const blocks are not supported in generic constants | = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs index 298cfb512e41..79e9834b54ed 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.rs @@ -18,5 +18,4 @@ fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { fn main() { use_dyn(&()); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr index a124fbc60920..f9904c9d2e48 100644 --- a/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/dyn-compatibility-ok-infer-err.stderr @@ -14,27 +14,6 @@ help: consider specifying the generic argument LL | use_dyn::(&()); | +++++ -error[E0284]: type annotations needed - --> $DIR/dyn-compatibility-ok-infer-err.rs:19:5 - | -LL | use_dyn(&()); - | ^^^^^^^ --- type must be known at this point - | | - | cannot infer the value of the const parameter `N` declared on the function `use_dyn` - | -note: required for `()` to implement `Foo<_>` - --> $DIR/dyn-compatibility-ok-infer-err.rs:8:22 - | -LL | impl Foo for () { - | -------------- ^^^^^^ ^^ - | | - | unsatisfied trait bound introduced here - = note: required for the cast from `&()` to `&dyn Foo<_>` -help: consider specifying the generic argument - | -LL | use_dyn::(&()); - | +++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr index d822fa5894a5..58f0d31b0960 100644 --- a/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr +++ b/tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr @@ -2,9 +2,15 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/error_in_ty.rs:6:31 | LL | pub struct A {} - | - ^ help: a const parameter with a similar name exists: `z` + | - ^ | | | similarly named const parameter `z` defined here + | +help: a const parameter with a similar name exists + | +LL - pub struct A {} +LL + pub struct A {} + | error: `[usize; x]` is forbidden as the type of a const generic parameter --> $DIR/error_in_ty.rs:6:23 diff --git a/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs b/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs index b9537014767e..8d7ec1867857 100644 --- a/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs +++ b/tests/ui/const-generics/generic_const_exprs/feature-attribute-missing-in-dependent-crate-ice.rs @@ -11,7 +11,7 @@ struct Wrapper(i64); impl aux::FromSlice for Wrapper { fn validate_slice(_: &[[u8; Self::SIZE]]) -> Result<(), aux::Error> { - //~^ ERROR generic `Self` types are currently not permitted in anonymous constants + //~^ ERROR generic `Self` Ok(()) } } diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs index 9f20cf085794..c08d36f4d9ff 100644 --- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs +++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.rs @@ -11,7 +11,7 @@ where //~^ ERROR only lifetime parameters can be used in this context //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders //~| ERROR defaults for generic parameters are not allowed in `for<...>` binders - //~| ERROR failed to resolve: use of undeclared type `COT` + //~| ERROR cannot find //~| ERROR the name `N` is already used for a generic parameter in this item's generic parameters { } diff --git a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr index 8e9b5b03d14e..de81c021b829 100644 --- a/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr +++ b/tests/ui/const-generics/generic_const_exprs/ice-predicates-of-no-entry-found-for-key-119275.stderr @@ -43,7 +43,7 @@ error: defaults for generic parameters are not allowed in `for<...>` binders LL | for [(); COT::BYTES]:, | ^^^^^^^ -error[E0433]: failed to resolve: use of undeclared type `COT` +error[E0433]: cannot find type `COT` in this scope --> $DIR/ice-predicates-of-no-entry-found-for-key-119275.rs:10:43 | LL | for [(); COT::BYTES]:, diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105257.rs b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs index 85a28f2b3303..947410cbe0dc 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105257.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-105257.rs @@ -2,9 +2,9 @@ #![expect(incomplete_features)] trait Trait { - fn fnc(&self) {} //~ERROR defaults for generic parameters are not allowed here - //~^ ERROR: mismatched types - fn foo() }>(&self) {} //~ERROR defaults for generic parameters are not allowed here + fn fnc(&self) {} //~ ERROR defaults for generic parameters are not allowed here + //~^ ERROR mismatched types + fn foo() }>(&self) {} //~ ERROR defaults for generic parameters are not allowed here } fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr index 1c97eaddfe1b..cc35035edf95 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr @@ -3,7 +3,6 @@ error[E0282]: type annotations needed | LL | Combination::<0>.and::<_>().and::<_>(); | ^^^ cannot infer type of the type parameter `M` declared on the method `and` - | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr index eb4ff8305dac..7fa0d8c7dbaa 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-69654.stderr @@ -5,6 +5,11 @@ LL | impl Bar for [u8; T] {} | - ^ not a value | | | found this type parameter + | +help: you might have meant to write a const parameter here + | +LL | impl Bar for [u8; T] {} + | +++++ ++++++++++++ error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 diff --git a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs deleted file mode 100644 index 1ed0965e1bde..000000000000 --- a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! ICE regression test for #114317 and #126182 -//! Type mismatches of literals cause errors int typeck, -//! but those errors cannot be propagated to the various -//! `lit_to_const` call sites. Now `lit_to_const` just delays -//! a bug and produces an error constant on its own. - -#![feature(adt_const_params)] -#![feature(generic_const_exprs)] -#![allow(incomplete_features)] - -struct A(C); -//~^ ERROR: generic parameters with a default must be trailing -//~| ERROR: mismatched types - -struct Cond; - -struct Thing>(T); -//~^ ERROR: mismatched types - -impl Thing {} - -fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr deleted file mode 100644 index e4613e498b27..000000000000 --- a/tests/ui/const-generics/generic_const_exprs/lit_type_mismatch.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error: generic parameters with a default must be trailing - --> $DIR/lit_type_mismatch.rs:11:16 - | -LL | struct A(C); - | ^ - -error[E0308]: mismatched types - --> $DIR/lit_type_mismatch.rs:11:24 - | -LL | struct A(C); - | ^ expected `()`, found integer - -error[E0308]: mismatched types - --> $DIR/lit_type_mismatch.rs:17:23 - | -LL | struct Thing>(T); - | ^ expected `bool`, found integer - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/generic_const_exprs/non-local-const.rs b/tests/ui/const-generics/generic_const_exprs/non-local-const.rs index 0a30cc385ac4..d0efdb2c2017 100644 --- a/tests/ui/const-generics/generic_const_exprs/non-local-const.rs +++ b/tests/ui/const-generics/generic_const_exprs/non-local-const.rs @@ -1,10 +1,12 @@ // regression test for #133808. +//@ aux-build:non_local_type_const.rs #![feature(generic_const_exprs)] #![feature(min_generic_const_args)] #![allow(incomplete_features)] #![crate_type = "lib"] +extern crate non_local_type_const; pub trait Foo {} -impl Foo for [u8; std::path::MAIN_SEPARATOR] {} -//~^ ERROR the constant `MAIN_SEPARATOR` is not of type `usize` +impl Foo for [u8; non_local_type_const::NON_LOCAL_CONST] {} +//~^ ERROR the constant `'a'` is not of type `usize` diff --git a/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr b/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr index d8df3269a19e..3d1ec60eb908 100644 --- a/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr +++ b/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr @@ -1,10 +1,10 @@ -error: the constant `MAIN_SEPARATOR` is not of type `usize` - --> $DIR/non-local-const.rs:9:14 +error: the constant `'a'` is not of type `usize` + --> $DIR/non-local-const.rs:11:14 | -LL | impl Foo for [u8; std::path::MAIN_SEPARATOR] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `char` +LL | impl Foo for [u8; non_local_type_const::NON_LOCAL_CONST] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `char` | - = note: the length of array `[u8; MAIN_SEPARATOR]` must be type `usize` + = note: the length of array `[u8; 'a']` must be type `usize` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr index d3a7e286fdd6..b547bdd7d07a 100644 --- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr @@ -20,7 +20,13 @@ LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here ... LL | pub const fn v21() -> v18 {} - | ^^^ help: a type alias with a similar name exists: `v11` + | ^^^ + | +help: a type alias with a similar name exists + | +LL - pub const fn v21() -> v18 {} +LL + pub const fn v21() -> v11 {} + | error[E0425]: cannot find type `v18` in this scope --> $DIR/unevaluated-const-ice-119731.rs:35:31 @@ -29,7 +35,13 @@ LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here ... LL | pub const fn v21() -> v18 { - | ^^^ help: a type alias with a similar name exists: `v11` + | ^^^ + | +help: a type alias with a similar name exists + | +LL - pub const fn v21() -> v18 { +LL + pub const fn v21() -> v11 { + | error[E0422]: cannot find struct, variant or union type `v18` in this scope --> $DIR/unevaluated-const-ice-119731.rs:37:13 @@ -38,7 +50,13 @@ LL | pub type v11 = [[usize; v4]; v4]; | --------------------------------- similarly named type alias `v11` defined here ... LL | v18 { _p: () } - | ^^^ help: a type alias with a similar name exists: `v11` + | ^^^ + | +help: a type alias with a similar name exists + | +LL - v18 { _p: () } +LL + v11 { _p: () } + | warning: type `v11` should have an upper camel case name --> $DIR/unevaluated-const-ice-119731.rs:9:14 diff --git a/tests/ui/const-generics/ice-151186-fn-ptr-in-where-clause.rs b/tests/ui/const-generics/ice-151186-fn-ptr-in-where-clause.rs new file mode 100644 index 000000000000..7710fc68d795 --- /dev/null +++ b/tests/ui/const-generics/ice-151186-fn-ptr-in-where-clause.rs @@ -0,0 +1,16 @@ +// Regression test for https://github.com/rust-lang/rust/issues/151186 + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +trait Maybe {} + +trait MyTrait ()> {} +//~^ ERROR using function pointers as const generic parameters is forbidden + +fn foo<'a>(x: &'a ()) -> &'a () { x } + +impl Maybe for T where T: MyTrait<{ foo }> {} +//~^ ERROR the constant `foo` is not of type `fn()` + +fn main() {} diff --git a/tests/ui/const-generics/ice-151186-fn-ptr-in-where-clause.stderr b/tests/ui/const-generics/ice-151186-fn-ptr-in-where-clause.stderr new file mode 100644 index 000000000000..7c9d7ee7dde5 --- /dev/null +++ b/tests/ui/const-generics/ice-151186-fn-ptr-in-where-clause.stderr @@ -0,0 +1,22 @@ +error: using function pointers as const generic parameters is forbidden + --> $DIR/ice-151186-fn-ptr-in-where-clause.rs:8:24 + | +LL | trait MyTrait ()> {} + | ^^^^^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: the constant `foo` is not of type `fn()` + --> $DIR/ice-151186-fn-ptr-in-where-clause.rs:13:33 + | +LL | impl Maybe for T where T: MyTrait<{ foo }> {} + | ^^^^^^^^^^^^^^^^ expected fn pointer, found fn item + | +note: required by a const generic parameter in `MyTrait` + --> $DIR/ice-151186-fn-ptr-in-where-clause.rs:8:15 + | +LL | trait MyTrait ()> {} + | ^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `MyTrait` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/ice-68875.rs b/tests/ui/const-generics/ice-68875.rs index cc9546be2c92..7bf6a824729a 100644 --- a/tests/ui/const-generics/ice-68875.rs +++ b/tests/ui/const-generics/ice-68875.rs @@ -1,7 +1,7 @@ //@ check-fail struct DataWrapper<'a> { - data: &'a [u8; Self::SIZE], //~ ERROR generic `Self` types are currently not permitted in anonymous constants + data: &'a [u8; Self::SIZE], //~ ERROR generic `Self` } impl DataWrapper<'_> { diff --git a/tests/ui/const-generics/incorrect-const-param.rs b/tests/ui/const-generics/incorrect-const-param.rs new file mode 100644 index 000000000000..5f1d8ca2ae99 --- /dev/null +++ b/tests/ui/const-generics/incorrect-const-param.rs @@ -0,0 +1,45 @@ +// #84327 + +struct VecWrapper(Vec); + +// Correct +impl From<[T; N]> for VecWrapper +where + T: Clone, +{ + fn from(slice: [T; N]) -> Self { + VecWrapper(slice.to_vec()) + } +} + +// Forgot const +impl From<[T; N]> for VecWrapper //~ ERROR expected value, found type parameter `N` +where //~^ ERROR expected trait, found builtin type `usize` + T: Clone, +{ + fn from(slice: [T; N]) -> Self { //~ ERROR expected value, found type parameter `N` + VecWrapper(slice.to_vec()) + } +} + +// Forgot type +impl From<[T; N]> for VecWrapper //~ ERROR expected `:`, found `>` +where + T: Clone, +{ + fn from(slice: [T; N]) -> Self { + VecWrapper(slice.to_vec()) + } +} + +// Forgot const and type +impl From<[T; N]> for VecWrapper //~ ERROR expected value, found type parameter `N` +where + T: Clone, +{ + fn from(slice: [T; N]) -> Self { //~ ERROR expected value, found type parameter `N` + VecWrapper(slice.to_vec()) + } +} + +fn main() {} diff --git a/tests/ui/const-generics/incorrect-const-param.stderr b/tests/ui/const-generics/incorrect-const-param.stderr new file mode 100644 index 000000000000..c5cf54500ee0 --- /dev/null +++ b/tests/ui/const-generics/incorrect-const-param.stderr @@ -0,0 +1,70 @@ +error: expected `:`, found `>` + --> $DIR/incorrect-const-param.rs:26:16 + | +LL | impl From<[T; N]> for VecWrapper + | ^ expected `:` + | +help: you likely meant to write the type of the const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | ++++++++++++ + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:16:28 + | +LL | impl From<[T; N]> for VecWrapper + | - ^ not a value + | | + | found this type parameter + +error[E0404]: expected trait, found builtin type `usize` + --> $DIR/incorrect-const-param.rs:16:12 + | +LL | impl From<[T; N]> for VecWrapper + | ^^^^^ not a trait + | +help: you might have meant to write a const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | +++++ + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:20:24 + | +LL | impl From<[T; N]> for VecWrapper + | - found this type parameter +... +LL | fn from(slice: [T; N]) -> Self { + | ^ not a value + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:36:21 + | +LL | impl From<[T; N]> for VecWrapper + | - ^ not a value + | | + | found this type parameter + | +help: you might have meant to write a const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | +++++ ++++++++++++ + +error[E0423]: expected value, found type parameter `N` + --> $DIR/incorrect-const-param.rs:40:24 + | +LL | impl From<[T; N]> for VecWrapper + | - found this type parameter +... +LL | fn from(slice: [T; N]) -> Self { + | ^ not a value + | +help: you might have meant to write a const parameter here + | +LL | impl From<[T; N]> for VecWrapper + | +++++ ++++++++++++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0404, E0423. +For more information about an error, try `rustc --explain E0404`. diff --git a/tests/ui/const-generics/infer/issue-77092.rs b/tests/ui/const-generics/infer/issue-77092.rs index 47c594e5b11e..77d1fe187795 100644 --- a/tests/ui/const-generics/infer/issue-77092.rs +++ b/tests/ui/const-generics/infer/issue-77092.rs @@ -10,6 +10,5 @@ fn main() { for i in 1..4 { println!("{:?}", take_array_from_mut(&mut arr, i)); //~^ ERROR type annotations needed - //~| ERROR type annotations needed } } diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 3763cd738a86..96f6496eca53 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr @@ -14,24 +14,6 @@ help: consider specifying the generic arguments LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); | ++++++++++ -error[E0284]: type annotations needed - --> $DIR/issue-77092.rs:11:26 - | -LL | println!("{:?}", take_array_from_mut(&mut arr, i)); - | ---- ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` - | | - | required by this formatting parameter - | - = note: required for `[i32; _]` to implement `Debug` - = note: 1 redundant requirement hidden - = note: required for `&mut [i32; _]` to implement `Debug` -note: required by a bound in `core::fmt::rt::Argument::<'_>::new_debug` - --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL -help: consider specifying the generic arguments - | -LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); - | ++++++++++ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr b/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr index f8010b4ea687..5fc7e7fef75d 100644 --- a/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr +++ b/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr @@ -1,4 +1,4 @@ -error: `#[inline]` attribute cannot be used on function params +error: `#[inline]` attribute cannot be used on const parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:6:16 | LL | pub struct Foo<#[inline] const N: usize>; @@ -6,7 +6,7 @@ LL | pub struct Foo<#[inline] const N: usize>; | = help: `#[inline]` can only be applied to functions -error: `#[inline]` attribute cannot be used on function params +error: `#[inline]` attribute cannot be used on lifetime parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:14:17 | LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); @@ -14,7 +14,7 @@ LL | pub struct Foo2<#[inline] 'a>(PhantomData<&'a ()>); | = help: `#[inline]` can only be applied to functions -error: `#[inline]` attribute cannot be used on function params +error: `#[inline]` attribute cannot be used on type parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:22:17 | LL | pub struct Foo3<#[inline] T>(PhantomData); @@ -40,7 +40,7 @@ error[E0517]: attribute should be applied to a struct, enum, or union LL | pub struct Baz3<#[repr(C)] T>(PhantomData); | ^ - not a struct, enum, or union -error: `#[cold]` attribute cannot be used on function params +error: `#[cold]` attribute cannot be used on const parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:8:16 | LL | pub struct Bar<#[cold] const N: usize>; @@ -54,7 +54,7 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: `#[cold]` attribute cannot be used on function params +error: `#[cold]` attribute cannot be used on lifetime parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:16:17 | LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); @@ -63,7 +63,7 @@ LL | pub struct Bar2<#[cold] 'a>(PhantomData<&'a ()>); = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[cold]` can only be applied to functions -error: `#[cold]` attribute cannot be used on function params +error: `#[cold]` attribute cannot be used on type parameters --> $DIR/invalid-attributes-on-const-params-78957.rs:24:17 | LL | pub struct Bar3<#[cold] T>(PhantomData); diff --git a/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr index 7d563e3b6054..87ec5973fa28 100644 --- a/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr +++ b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.stderr @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait X { | - this trait is not dyn compatible... LL | type Y; - | ^ ...because it contains the generic associated type `Y` + | ^ ...because it contains generic associated type `Y` = help: consider moving `Y` to another trait error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-56445-2.rs b/tests/ui/const-generics/issues/issue-56445-2.rs index e078c8487c72..11c844340080 100644 --- a/tests/ui/const-generics/issues/issue-56445-2.rs +++ b/tests/ui/const-generics/issues/issue-56445-2.rs @@ -5,7 +5,7 @@ impl<'a> OnDiskDirEntry<'a> { const LFN_FRAGMENT_LEN: usize = 2; fn lfn_contents(&self) -> [char; Self::LFN_FRAGMENT_LEN] { loop { } } - //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants + //~^ ERROR: generic `Self` } fn main() {} diff --git a/tests/ui/const-generics/issues/issue-56445-3.rs b/tests/ui/const-generics/issues/issue-56445-3.rs index c29df14586e2..a9a4a48ab675 100644 --- a/tests/ui/const-generics/issues/issue-56445-3.rs +++ b/tests/ui/const-generics/issues/issue-56445-3.rs @@ -2,7 +2,7 @@ pub struct Memory<'rom> { rom: &'rom [u8], ram: [u8; Self::SIZE], - //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants + //~^ ERROR: generic `Self` } impl<'rom> Memory<'rom> { diff --git a/tests/ui/const-generics/issues/issue-67945-2.rs b/tests/ui/const-generics/issues/issue-67945-2.rs index ce48b3f86a65..d3c5c891f760 100644 --- a/tests/ui/const-generics/issues/issue-67945-2.rs +++ b/tests/ui/const-generics/issues/issue-67945-2.rs @@ -7,7 +7,7 @@ struct Bug { A: [(); { //[full]~^ ERROR overly complex generic constant let x: Option> = None; - //[min]~^ ERROR generic `Self` types are currently not permitted in anonymous constants + //[min]~^ ERROR generic `Self` 0 }], B: S diff --git a/tests/ui/const-generics/issues/issue-82956.rs b/tests/ui/const-generics/issues/issue-82956.rs index 983717170c34..8586c39a717a 100644 --- a/tests/ui/const-generics/issues/issue-82956.rs +++ b/tests/ui/const-generics/issues/issue-82956.rs @@ -24,7 +24,7 @@ where fn pop(self) -> (Self::Newlen, Self::Output) { let mut iter = IntoIter::new(self); - //~^ ERROR: failed to resolve: use of undeclared type `IntoIter` + //~^ ERROR: cannot find let end = iter.next_back().unwrap(); let new = [(); N - 1].map(move |()| iter.next().unwrap()); (new, end) diff --git a/tests/ui/const-generics/issues/issue-82956.stderr b/tests/ui/const-generics/issues/issue-82956.stderr index beb801496115..a3d5572d5474 100644 --- a/tests/ui/const-generics/issues/issue-82956.stderr +++ b/tests/ui/const-generics/issues/issue-82956.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `IntoIter` +error[E0433]: cannot find type `IntoIter` in this scope --> $DIR/issue-82956.rs:26:24 | LL | let mut iter = IntoIter::new(self); diff --git a/tests/ui/const-generics/issues/issue-88119.rs b/tests/ui/const-generics/issues/issue-88119.rs index d44b5ab985b0..fb279dd824f8 100644 --- a/tests/ui/const-generics/issues/issue-88119.rs +++ b/tests/ui/const-generics/issues/issue-88119.rs @@ -1,5 +1,4 @@ -//@ known-bug: #110395 -//@ compile-flags: -Znext-solver +//@ check-pass #![allow(incomplete_features)] #![feature(const_trait_impl, generic_const_exprs)] diff --git a/tests/ui/const-generics/issues/issue-88119.stderr b/tests/ui/const-generics/issues/issue-88119.stderr deleted file mode 100644 index 0bdf153468bc..000000000000 --- a/tests/ui/const-generics/issues/issue-88119.stderr +++ /dev/null @@ -1,95 +0,0 @@ -error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed - --> $DIR/issue-88119.rs:4:30 - | -LL | #![feature(const_trait_impl, generic_const_exprs)] - | ^^^^^^^^^^^^^^^^^^^ - | - = help: remove one of these features - -error[E0275]: overflow evaluating the requirement `&T: [const] ConstName` - --> $DIR/issue-88119.rs:18:49 - | -LL | impl const ConstName for &T - | ^^ - -error[E0275]: overflow evaluating the requirement `&T: ConstName` - --> $DIR/issue-88119.rs:18:49 - | -LL | impl const ConstName for &T - | ^^ - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:20:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&T as ConstName>` - --> $DIR/issue-88119.rs:20:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:20:10 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&T as ConstName>` - --> $DIR/issue-88119.rs:20:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>` - -error[E0275]: overflow evaluating the requirement `&mut T: [const] ConstName` - --> $DIR/issue-88119.rs:25:49 - | -LL | impl const ConstName for &mut T - | ^^^^^^ - -error[E0275]: overflow evaluating the requirement `&mut T: ConstName` - --> $DIR/issue-88119.rs:25:49 - | -LL | impl const ConstName for &mut T - | ^^^^^^ - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:27:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&mut T as ConstName>` - --> $DIR/issue-88119.rs:27:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` - -error[E0275]: overflow evaluating the requirement `[(); name_len::()] well-formed` - --> $DIR/issue-88119.rs:27:10 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^ - | -note: required by a bound in `<&mut T as ConstName>` - --> $DIR/issue-88119.rs:27:5 - | -LL | [(); name_len::()]:, - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>` - -error[E0275]: overflow evaluating the requirement `&&mut u8: ConstName` - --> $DIR/issue-88119.rs:32:35 - | -LL | pub const ICE_1: &'static [u8] = <&&mut u8 as ConstName>::NAME_BYTES; - | ^^^^^^^^ - -error[E0275]: overflow evaluating the requirement `&mut &u8: ConstName` - --> $DIR/issue-88119.rs:33:35 - | -LL | pub const ICE_2: &'static [u8] = <&mut &u8 as ConstName>::NAME_BYTES; - | ^^^^^^^^ - -error: aborting due to 11 previous errors - -For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs new file mode 100644 index 000000000000..8470b933cadd --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.rs @@ -0,0 +1,38 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +enum Option { + Some(T), + None, +} +use Option::Some; + +fn foo>() {} + + +trait Trait { + type const ASSOC: u32; +} + +fn bar() { + // the initializer of `_0` is a `N` which is a legal const argument + // so this is ok. + foo::<{ Some:: { 0: N } }>(); + + // this is allowed as mgca supports uses of assoc consts in the + // type system. ie `::ASSOC` is a legal const argument + foo::<{ Some:: { 0: ::ASSOC } }>(); + + // this on the other hand is not allowed as `N + 1` is not a legal + // const argument + foo::<{ Some:: { 0: N + 1 } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + + // this also is not allowed as generic parameters cannot be used + // in anon const const args + foo::<{ Some:: { 0: const { N + 1 } } }>(); + //~^ ERROR: generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr new file mode 100644 index 000000000000..f1d5e5c67475 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_simple.stderr @@ -0,0 +1,16 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/adt_expr_arg_simple.rs:29:30 + | +LL | foo::<{ Some:: { 0: N + 1 } }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/adt_expr_arg_simple.rs:34:38 + | +LL | foo::<{ Some:: { 0: const { N + 1 } } }>(); + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs new file mode 100644 index 000000000000..68f999fb76fa --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.rs @@ -0,0 +1,26 @@ +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + + +trait Trait { + type const ASSOC: usize; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N2) }>(); + //~^ ERROR the constant `N` is not of type `u32` + takes_tuple::<{ (N, T::ASSOC) }>(); + //~^ ERROR the constant `N` is not of type `u32` + //~| ERROR the constant `::ASSOC` is not of type `u32` + + takes_nested_tuple::<{ (N, (N, N2)) }>(); + //~^ ERROR the constant `N` is not of type `u32` + takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); + //~^ ERROR the constant `N` is not of type `u32` + //~| ERROR the constant `::ASSOC` is not of type `u32` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr new file mode 100644 index 000000000000..9d80ebeaa680 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr @@ -0,0 +1,38 @@ +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:13:21 + | +LL | takes_tuple::<{ (N, N2) }>(); + | ^^^^^^^ expected `u32`, found `usize` + +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:15:21 + | +LL | takes_tuple::<{ (N, T::ASSOC) }>(); + | ^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `::ASSOC` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:15:21 + | +LL | takes_tuple::<{ (N, T::ASSOC) }>(); + | ^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:19:28 + | +LL | takes_nested_tuple::<{ (N, (N, N2)) }>(); + | ^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `N` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:21:28 + | +LL | takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); + | ^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `::ASSOC` is not of type `u32` + --> $DIR/adt_expr_arg_tuple_expr_fail.rs:21:28 + | +LL | takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); + | ^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.rs b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.rs new file mode 100644 index 000000000000..752844e4328f --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.rs @@ -0,0 +1,26 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![crate_type = "lib"] + +// Miscellaneous assortment of invalid cases of directly represented +// `ConstArgKind::Struct`'s under mgca. + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct Foo { field: T } + +fn NonStruct() {} + +fn accepts>() {} + +fn bar() { + accepts::<{ Foo:: { }}>(); + //~^ ERROR: struct expression with missing field initialiser for `field` + accepts::<{ Foo:: { field: const { 1 }, field: const { 2} }}>(); + //~^ ERROR: struct expression with multiple initialisers for `field` + accepts::<{ Fooo:: { field: const { 1 } }}>(); + //~^ ERROR: cannot find struct, variant or union type `Fooo` in this scope + //~| ERROR: struct expression with invalid base path + accepts::<{ NonStruct { }}>(); + //~^ ERROR: expected struct, variant or union type, found function `NonStruct` + //~| ERROR: struct expression with invalid base path +} diff --git a/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr new file mode 100644 index 000000000000..72e0e94ff625 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_erroneuous_inits.stderr @@ -0,0 +1,49 @@ +error[E0422]: cannot find struct, variant or union type `Fooo` in this scope + --> $DIR/adt_expr_erroneuous_inits.rs:20:17 + | +LL | struct Foo { field: T } + | ------------- similarly named struct `Foo` defined here +... +LL | accepts::<{ Fooo:: { field: const { 1 } }}>(); + | ^^^^ + | +help: a struct with a similar name exists + | +LL - accepts::<{ Fooo:: { field: const { 1 } }}>(); +LL + accepts::<{ Foo:: { field: const { 1 } }}>(); + | + +error[E0574]: expected struct, variant or union type, found function `NonStruct` + --> $DIR/adt_expr_erroneuous_inits.rs:23:17 + | +LL | accepts::<{ NonStruct { }}>(); + | ^^^^^^^^^ not a struct, variant or union type + +error: struct expression with missing field initialiser for `field` + --> $DIR/adt_expr_erroneuous_inits.rs:16:17 + | +LL | accepts::<{ Foo:: { }}>(); + | ^^^^^^^^^^^^^ + +error: struct expression with multiple initialisers for `field` + --> $DIR/adt_expr_erroneuous_inits.rs:18:49 + | +LL | accepts::<{ Foo:: { field: const { 1 }, field: const { 2} }}>(); + | ^^^^^^^^^^^^^^^^^ + +error: struct expression with invalid base path + --> $DIR/adt_expr_erroneuous_inits.rs:20:17 + | +LL | accepts::<{ Fooo:: { field: const { 1 } }}>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: struct expression with invalid base path + --> $DIR/adt_expr_erroneuous_inits.rs:23:17 + | +LL | accepts::<{ NonStruct { }}>(); + | ^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0422, E0574. +For more information about an error, try `rustc --explain E0422`. diff --git a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs new file mode 100644 index 000000000000..496a424bac65 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.rs @@ -0,0 +1,38 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct S1 { + f1: T, + f2: isize, +} + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct S2(T, isize); + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +enum En { + Var1(bool, T), + Var2 { field: i64 }, +} + +fn accepts_1>() {} +fn accepts_2>() {} +fn accepts_3>() {} + +fn bar() { + accepts_1::<{ S1:: { f1: N, f2: N } }>(); + //~^ ERROR the constant `N` is not of type `u8` + //~| ERROR the constant `N` is not of type `isize` + accepts_2::<{ S2::(N, N) }>(); + //~^ ERROR the constant `N` is not of type `u8` + //~| ERROR the constant `N` is not of type `isize` + accepts_3::<{ En::Var1::(N, N) }>(); + //~^ ERROR the constant `N` is not of type `u8` + accepts_3::<{ En::Var2:: { field: N } }>(); + //~^ ERROR the constant `N` is not of type `i64` + accepts_3::<{ En::Var2:: { field: const { false } } }>(); + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr new file mode 100644 index 000000000000..81f7c5366b46 --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr @@ -0,0 +1,45 @@ +error: the constant `N` is not of type `u8` + --> $DIR/adt_expr_fields_type_check.rs:24:19 + | +LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` + +error: the constant `N` is not of type `isize` + --> $DIR/adt_expr_fields_type_check.rs:24:19 + | +LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool` + +error: the constant `N` is not of type `u8` + --> $DIR/adt_expr_fields_type_check.rs:27:19 + | +LL | accepts_2::<{ S2::(N, N) }>(); + | ^^^^^^^^^^^^^^ expected `u8`, found `bool` + +error: the constant `N` is not of type `isize` + --> $DIR/adt_expr_fields_type_check.rs:27:19 + | +LL | accepts_2::<{ S2::(N, N) }>(); + | ^^^^^^^^^^^^^^ expected `isize`, found `bool` + +error: the constant `N` is not of type `u8` + --> $DIR/adt_expr_fields_type_check.rs:30:19 + | +LL | accepts_3::<{ En::Var1::(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` + +error: the constant `N` is not of type `i64` + --> $DIR/adt_expr_fields_type_check.rs:32:19 + | +LL | accepts_3::<{ En::Var2:: { field: N } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i64`, found `bool` + +error[E0308]: mismatched types + --> $DIR/adt_expr_fields_type_check.rs:34:51 + | +LL | accepts_3::<{ En::Var2:: { field: const { false } } }>(); + | ^^^^^ expected `i64`, found `bool` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs b/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs new file mode 100644 index 000000000000..5def3cbb829b --- /dev/null +++ b/tests/ui/const-generics/mgca/adt_expr_infers_from_value.rs @@ -0,0 +1,44 @@ +//@ check-pass + +#![feature( + generic_const_items, + min_generic_const_args, + adt_const_params, + generic_const_parameter_types, + unsized_const_params, +)] +#![expect(incomplete_features)] + +use std::marker::{PhantomData, ConstParamTy, ConstParamTy_}; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Foo { + field: T, +} + +type const WRAP: Foo = { Foo:: { + field: N, +} }; + +fn main() { + // What we're trying to accomplish here is winding up with an equality relation + // between two `ty::Const` that looks something like: + // + // ``` + // Foo { field: const { 1 + 2 } } + // eq + // Foo { field: ?x } + // ``` + // + // Note that the `field: _` here means a const argument `_` not a wildcard pattern. + // This tests that we are able to infer `?x=3` even though the first `ty::Const` + // may be a fully evaluated constant, and the latter is not fully evaluatable due + // to inference variables. + let _: PC<_, { WRAP:: }> + = PC::<_, { Foo:: { field: _ }}>; +} + +// "PhantomConst" helper equivalent to "PhantomData" used for testing equalities +// of arbitrarily typed const arguments. +struct PC { _0: PhantomData } +const PC: PC = PC { _0: PhantomData:: }; diff --git a/tests/ui/const-generics/mgca/array-expr-complex.rs b/tests/ui/const-generics/mgca/array-expr-complex.rs new file mode 100644 index 000000000000..3e8320bc94de --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-complex.rs @@ -0,0 +1,16 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] + +fn takes_array() {} + +fn generic_caller() { + // not supported yet + takes_array::<{ [1, 2, 1 + 2] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_array::<{ [X; 3] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + takes_array::<{ [0; Y] }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-complex.stderr b/tests/ui/const-generics/mgca/array-expr-complex.stderr new file mode 100644 index 000000000000..beac1aa232f2 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-complex.stderr @@ -0,0 +1,20 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:8:28 + | +LL | takes_array::<{ [1, 2, 1 + 2] }>(); + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:10:19 + | +LL | takes_array::<{ [X; 3] }>(); + | ^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/array-expr-complex.rs:12:19 + | +LL | takes_array::<{ [0; Y] }>(); + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/mgca/array-expr-empty.rs b/tests/ui/const-generics/mgca/array-expr-empty.rs new file mode 100644 index 000000000000..d37c6f2fcfe3 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-empty.rs @@ -0,0 +1,9 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +fn takes_empty_array() {} +//~^ ERROR: expected type, found `]` + +fn main() { + takes_empty_array::<{ [] }>(); +} diff --git a/tests/ui/const-generics/mgca/array-expr-empty.stderr b/tests/ui/const-generics/mgca/array-expr-empty.stderr new file mode 100644 index 000000000000..91340e621acb --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-empty.stderr @@ -0,0 +1,8 @@ +error: expected type, found `]` + --> $DIR/array-expr-empty.rs:4:32 + | +LL | fn takes_empty_array() {} + | ^ expected type + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/array-expr-simple.rs b/tests/ui/const-generics/mgca/array-expr-simple.rs new file mode 100644 index 000000000000..44feeccb4f9f --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-simple.rs @@ -0,0 +1,25 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +fn takes_array_u32() {} +fn takes_array_bool() {} +fn takes_nested_array() {} +fn takes_empty_array() {} + +fn generic_caller() { + takes_array_u32::<{ [X, Y, X] }>(); + takes_array_u32::<{ [X, Y, const { 1 }] }>(); + takes_array_u32::<{ [X, Y, const { 1 + 1 }] }>(); + takes_array_u32::<{ [2_002, 2u32, 1_u32] }>(); + + takes_array_bool::<{ [true, false] }>(); + + takes_nested_array::<{ [[X, Y], [3, 4]] }>(); + takes_nested_array::<{ [[1u32, 2_u32], [const { 3 }, 4]] }>(); + + takes_empty_array::<{ [] }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs new file mode 100644 index 000000000000..cda519b96d4d --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.rs @@ -0,0 +1,21 @@ +//! regression test for +#![feature(min_generic_const_args)] +#![feature(adt_const_params)] +#![expect(incomplete_features)] + +trait Trait1 {} +trait Trait2 {} + +fn foo() +where + T: Trait1<{ [] }>, //~ ERROR: expected `usize`, found const array +{ +} + +fn bar() +where + T: Trait2<3>, //~ ERROR: mismatched types +{ +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr new file mode 100644 index 000000000000..be40e4474226 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-type-mismatch-in-where-bound.stderr @@ -0,0 +1,15 @@ +error: expected `usize`, found const array + --> $DIR/array-expr-type-mismatch-in-where-bound.rs:11:17 + | +LL | T: Trait1<{ [] }>, + | ^^ + +error[E0308]: mismatched types + --> $DIR/array-expr-type-mismatch-in-where-bound.rs:17:15 + | +LL | T: Trait2<3>, + | ^ expected `[u8; 3]`, found integer + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs new file mode 100644 index 000000000000..7401181962bb --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-assoc-const.rs @@ -0,0 +1,17 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +fn takes_array() {} + +trait Trait { + type const ASSOC: u32; +} + +fn generic_caller() { + takes_array::<{ [T::ASSOC, N, T::ASSOC] }>(); + takes_array::<{ [1_u32, T::ASSOC, 2] }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-macro.rs b/tests/ui/const-generics/mgca/array-expr-with-macro.rs new file mode 100644 index 000000000000..aef5acc1c803 --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-macro.rs @@ -0,0 +1,18 @@ +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] +#![allow(dead_code)] + +macro_rules! make_array { + ($n:expr, $m:expr, $p:expr) => { + [N, $m, $p] + }; +} + +fn takes_array() {} + +fn generic_caller() { + takes_array::<{ make_array!(N, 2, 3) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-struct.rs b/tests/ui/const-generics/mgca/array-expr-with-struct.rs new file mode 100644 index 000000000000..883af57e918e --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-struct.rs @@ -0,0 +1,20 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Container { + values: [u32; 3], +} + +fn takes_container() {} + +fn generic_caller() { + takes_container::<{ Container { values: [N, M, 1] } }>(); + takes_container::<{ Container { values: [1, 2, 3] } }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/array-expr-with-tuple.rs b/tests/ui/const-generics/mgca/array-expr-with-tuple.rs new file mode 100644 index 000000000000..004663dcefab --- /dev/null +++ b/tests/ui/const-generics/mgca/array-expr-with-tuple.rs @@ -0,0 +1,13 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +fn takes_tuple() {} + +fn generic_caller() { + takes_tuple::<{ ([N, M], 5, [M, N]) }>(); + takes_tuple::<{ ([1, 2], 3, [4, 5]) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs b/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs new file mode 100644 index 000000000000..13b2e031b118 --- /dev/null +++ b/tests/ui/const-generics/mgca/assoc-const-projection-in-bound.rs @@ -0,0 +1,25 @@ +//! regression test for +//@ run-pass +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] +#![allow(dead_code)] + +trait Abc {} + +trait A { + type const VALUE: usize; +} + +impl A for T { + type const VALUE: usize = 0; +} + +trait S {} + +trait Handler +where + (): S<{ ::VALUE }>, +{ +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs index a11314c11aae..ca7299e7690b 100644 --- a/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs @@ -6,9 +6,9 @@ pub trait Tr { } fn mk_array(_x: T) -> [(); T::SIZE] { - //~^ ERROR type_const + //~^ ERROR: use of `const` in the type system not defined as `type const` [(); T::SIZE] - //~^ ERROR type_const + //~^ ERROR: use of `const` in the type system not defined as `type const` } fn main() {} diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr index 7872e0967626..759a40cc0675 100644 --- a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr @@ -1,18 +1,20 @@ -error: use of trait associated const without `#[type_const]` +error: use of `const` in the type system not defined as `type const` --> $DIR/assoc-const-without-type_const.rs:8:35 | +LL | const SIZE: usize; + | - help: add `type` before `const` for `Tr::SIZE`: `type` +... LL | fn mk_array(_x: T) -> [(); T::SIZE] { | ^^^^^^^ - | - = note: the declaration in the trait must be marked with `#[type_const]` -error: use of trait associated const without `#[type_const]` +error: use of `const` in the type system not defined as `type const` --> $DIR/assoc-const-without-type_const.rs:10:10 | +LL | const SIZE: usize; + | - help: add `type` before `const` for `Tr::SIZE`: `type` +... LL | [(); T::SIZE] | ^^^^^^^ - | - = note: the declaration in the trait must be marked with `#[type_const]` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/assoc-const.rs b/tests/ui/const-generics/mgca/assoc-const.rs index fb5b4308a7f8..c49b84edba10 100644 --- a/tests/ui/const-generics/mgca/assoc-const.rs +++ b/tests/ui/const-generics/mgca/assoc-const.rs @@ -4,8 +4,7 @@ #![allow(incomplete_features)] pub trait Tr { - #[type_const] - const SIZE: usize; + type const SIZE: usize; } fn mk_array>(_x: T) -> [(); >::SIZE] { diff --git a/tests/ui/const-generics/mgca/auxiliary/non_local_const.rs b/tests/ui/const-generics/mgca/auxiliary/non_local_const.rs new file mode 100644 index 000000000000..19091e4780fe --- /dev/null +++ b/tests/ui/const-generics/mgca/auxiliary/non_local_const.rs @@ -0,0 +1 @@ +pub const N: usize = 2; diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs index bb5bdb8d7c4c..81be1ca4eb88 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs @@ -1,16 +1,16 @@ trait Tr { - #[type_const()] - //~^ ERROR malformed - //~| ERROR experimental - const N: usize; + type const N: usize; + //~^ ERROR: `type const` syntax is experimental [E0658] + //~| ERROR: associated `type const` are unstable [E0658] } struct S; impl Tr for S { - #[type_const] - //~^ ERROR experimental - const N: usize = 0; + + type const N: usize = 0; + //~^ ERROR: `type const` syntax is experimental [E0658] + //~| ERROR: associated `type const` are unstable [E0658] } fn main() {} diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr index df442c22241b..7bb2adf27199 100644 --- a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr +++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr @@ -1,33 +1,43 @@ -error[E0658]: the `#[type_const]` attribute is an experimental feature +error[E0658]: `type const` syntax is experimental --> $DIR/bad-type_const-syntax.rs:2:5 | -LL | #[type_const()] - | ^^^^^^^^^^^^^^^ +LL | type const N: usize; + | ^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0658]: the `#[type_const]` attribute is an experimental feature +error[E0658]: `type const` syntax is experimental --> $DIR/bad-type_const-syntax.rs:11:5 | -LL | #[type_const] - | ^^^^^^^^^^^^^ +LL | type const N: usize = 0; + | ^^^^^^^^^^ | = note: see issue #132980 for more information = help: add `#![feature(min_generic_const_args)]` 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[E0565]: malformed `type_const` attribute input +error[E0658]: associated `type const` are unstable --> $DIR/bad-type_const-syntax.rs:2:5 | -LL | #[type_const()] - | ^^^^^^^^^^^^--^ - | | | - | | didn't expect any arguments here - | help: must be of the form: `#[type_const]` +LL | type const N: usize; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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: aborting due to 3 previous errors +error[E0658]: associated `type const` are unstable + --> $DIR/bad-type_const-syntax.rs:11:5 + | +LL | type const N: usize = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -Some errors have detailed explanations: E0565, E0658. -For more information about an error, try `rustc --explain E0565`. +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs index 37f9c31feaa5..69d16993a7e0 100644 --- a/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs +++ b/tests/ui/const-generics/mgca/concrete-expr-with-generics-in-env.rs @@ -4,23 +4,17 @@ #![feature(min_generic_const_args, generic_const_items)] pub trait Tr { - #[type_const] - const N1: usize; - #[type_const] - const N2: usize; - #[type_const] - const N3: usize; + type const N1: usize; + type const N2: usize; + type const N3: usize; } pub struct S; impl Tr for S { - #[type_const] - const N1: usize = 0; - #[type_const] - const N2: usize = 1; - #[type_const] - const N3: usize = 2; + type const N1: usize = 0; + type const N2: usize = 1; + type const N3: usize = 2; } fn main() {} diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs index 68aa30bd65bb..9d475f8224fa 100644 --- a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs @@ -3,7 +3,8 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -const C: usize = 0; + +type const C: usize = 0; pub struct A {} impl A { fn fun1() {} diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr index 3d74d1db206e..6b2b871ba4b9 100644 --- a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr @@ -1,11 +1,11 @@ error[E0107]: missing generics for struct `A` - --> $DIR/const-arg-coherence-conflicting-methods.rs:12:6 + --> $DIR/const-arg-coherence-conflicting-methods.rs:13:6 | LL | impl A { | ^ expected 1 generic argument | note: struct defined here, with 1 generic parameter: `M` - --> $DIR/const-arg-coherence-conflicting-methods.rs:7:12 + --> $DIR/const-arg-coherence-conflicting-methods.rs:8:12 | LL | pub struct A {} | ^ -------------- @@ -15,7 +15,7 @@ LL | impl A { | +++ error[E0592]: duplicate definitions with name `fun1` - --> $DIR/const-arg-coherence-conflicting-methods.rs:9:5 + --> $DIR/const-arg-coherence-conflicting-methods.rs:10:5 | LL | fn fun1() {} | ^^^^^^^^^ duplicate definitions for `fun1` diff --git a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs new file mode 100644 index 000000000000..6a4ee3ed1772 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.rs @@ -0,0 +1,19 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +struct U; + +#[derive(ConstParamTy, PartialEq, Eq)] +//~^ ERROR overflow evaluating the requirement `S well-formed` +//~| ERROR overflow evaluating the requirement `S well-formed` + +struct S() +where + S<{ U }>:; +//~^ ERROR overflow evaluating the requirement `S well-formed` +//~| ERROR overflow evaluating the requirement `S well-formed` +//~| ERROR overflow evaluating the requirement `S well-formed` + +fn main() {} diff --git a/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr new file mode 100644 index 000000000000..4c5ad645bc45 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-overflow-eval.stderr @@ -0,0 +1,80 @@ +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | S<{ U }>:; + | ^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | S<{ U }>:; + | ^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | S<{ U }>:; + | ^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:8:24 + | +LL | #[derive(ConstParamTy, PartialEq, Eq)] + | ^^^^^^^^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + +error[E0275]: overflow evaluating the requirement `S well-formed` + --> $DIR/const-ctor-overflow-eval.rs:8:35 + | +LL | #[derive(ConstParamTy, PartialEq, Eq)] + | ^^ + | +note: required by a bound in `S` + --> $DIR/const-ctor-overflow-eval.rs:14:5 + | +LL | struct S() + | - required by a bound in this struct +LL | where +LL | S<{ U }>:; + | ^^^^^^^^ required by this bound in `S` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/const-generics/mgca/const-ctor-with-error.rs b/tests/ui/const-generics/mgca/const-ctor-with-error.rs new file mode 100644 index 000000000000..95a910e3dd2c --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-with-error.rs @@ -0,0 +1,19 @@ +// to ensure it does not ices like before + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +enum Option { + #[allow(dead_code)] + Some(T), + None, +} + +fn pass_enum>() {} + +fn main() { + pass_enum::<{ None }>(); + //~^ ERROR missing generics for enum `std::option::Option` +} diff --git a/tests/ui/const-generics/mgca/const-ctor-with-error.stderr b/tests/ui/const-generics/mgca/const-ctor-with-error.stderr new file mode 100644 index 000000000000..8684457a978b --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor-with-error.stderr @@ -0,0 +1,14 @@ +error[E0107]: missing generics for enum `std::option::Option` + --> $DIR/const-ctor-with-error.rs:17:19 + | +LL | pass_enum::<{ None }>(); + | ^^^^ expected 1 generic argument + | +help: add missing generic argument + | +LL | pass_enum::<{ None }>(); + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/mgca/const-ctor.rs b/tests/ui/const-generics/mgca/const-ctor.rs new file mode 100644 index 000000000000..19900b56a816 --- /dev/null +++ b/tests/ui/const-generics/mgca/const-ctor.rs @@ -0,0 +1,49 @@ +//! Regression test for +//! +//! + +//@ check-pass + +#![feature( + min_generic_const_args, + adt_const_params, + generic_const_parameter_types, + unsized_const_params +)] +#![expect(incomplete_features)] +use std::marker::{ConstParamTy, ConstParamTy_}; +#[derive(ConstParamTy, PartialEq, Eq)] +struct Colour; + +#[derive(ConstParamTy, PartialEq, Eq)] +enum A { + B, +} + +#[derive(ConstParamTy, PartialEq, Eq)] +enum MyOption { + #[allow(dead_code)] + Some(T), + None, +} + +#[derive(ConstParamTy, PartialEq, Eq)] +struct Led; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo; + +fn pass_enum>() {} + +fn accepts_foo>() {} + +fn accepts_bar>() {} + +fn test() { + accepts_foo:: }>(); + accepts_bar:: }>(); +} + +fn main() { + Led::<{ Colour }>; +} diff --git a/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs b/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs new file mode 100644 index 000000000000..a7e46ad877e7 --- /dev/null +++ b/tests/ui/const-generics/mgca/cyclic-type-const-151251.rs @@ -0,0 +1,10 @@ +//@ needs-rustc-debug-assertions + +#![feature(min_generic_const_args)] +#![feature(generic_const_exprs)] +#![expect(incomplete_features)] + +type const A: u8 = A; +//~^ ERROR overflow normalizing the unevaluated constant `A` + +fn main() {} diff --git a/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr b/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr new file mode 100644 index 000000000000..47653dd1896f --- /dev/null +++ b/tests/ui/const-generics/mgca/cyclic-type-const-151251.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow normalizing the unevaluated constant `A` + --> $DIR/cyclic-type-const-151251.rs:7:1 + | +LL | type const A: u8 = A; + | ^^^^^^^^^^^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.rs b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.rs new file mode 100644 index 000000000000..0ee2b4eb45f6 --- /dev/null +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.rs @@ -0,0 +1,13 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo<'a, T>() +where + 'a: 'a, + T: Trait + //~^ ERROR generic parameters may not be used in const operations +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr new file mode 100644 index 000000000000..e0804158952d --- /dev/null +++ b/tests/ui/const-generics/mgca/early-bound-param-lt-bad.stderr @@ -0,0 +1,10 @@ +error: generic parameters may not be used in const operations + --> $DIR/early-bound-param-lt-bad.rs:9:30 + | +LL | T: Trait + | ^^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.rs b/tests/ui/const-generics/mgca/explicit_anon_consts.rs new file mode 100644 index 000000000000..2b9909b43dfb --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.rs @@ -0,0 +1,73 @@ +#![feature(generic_const_items, min_generic_const_args)] +#![expect(incomplete_features)] +// library crates exercise weirder code paths around +// DefIds which were created for const args. +#![crate_type = "lib"] + +struct Foo; + +type Adt1 = Foo; +type Adt2 = Foo<{ N }>; +type Adt3 = Foo; +//~^ ERROR: generic parameters may not be used in const operations +type Adt4 = Foo<{ 1 + 1 }>; +//~^ ERROR: complex const arguments must be placed inside of a `const` block +type Adt5 = Foo; + +type Arr = [(); N]; +type Arr2 = [(); { N }]; +type Arr3 = [(); const { N }]; +//~^ ERROR: generic parameters may not be used in const operations +type Arr4 = [(); 1 + 1]; +//~^ ERROR: complex const arguments must be placed inside of a `const` block +type Arr5 = [(); const { 1 + 1 }]; + +fn repeats() -> [(); N] { + let _1 = [(); N]; + let _2 = [(); { N }]; + let _3 = [(); const { N }]; + //~^ ERROR: generic parameters may not be used in const operations + let _4 = [(); 1 + 1]; + //~^ ERROR: complex const arguments must be placed inside of a `const` block + let _5 = [(); const { 1 + 1 }]; + let _6: [(); const { N }] = todo!(); + //~^ ERROR: generic parameters may not be used in const operations +} + + +type const ITEM1: usize = N; + +type const ITEM2: usize = { N }; + +type const ITEM3: usize = const { N }; +//~^ ERROR: generic parameters may not be used in const operations + +type const ITEM4: usize = { 1 + 1 }; +//~^ ERROR: complex const arguments must be placed inside of a `const` block + +type const ITEM5: usize = const { 1 + 1}; + +trait Trait { + + type const ASSOC: usize; +} + +fn ace_bounds< + const N: usize, + // We skip the T1 case because it doesn't resolve + // T1: Trait, + T2: Trait, + T3: Trait, + //~^ ERROR: generic parameters may not be used in const operations + T4: Trait, + //~^ ERROR: complex const arguments must be placed inside of a `const` block + T5: Trait, +>() {} + +struct Default1; +struct Default2; +struct Default3; +//~^ ERROR: generic parameters may not be used in const operations +struct Default4; +//~^ ERROR: complex const arguments must be placed inside of a `const` block +struct Default5; diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts.stderr b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr new file mode 100644 index 000000000000..714d7a804d11 --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts.stderr @@ -0,0 +1,94 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:13:33 + | +LL | type Adt4 = Foo<{ 1 + 1 }>; + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:21:34 + | +LL | type Arr4 = [(); 1 + 1]; + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:30:19 + | +LL | let _4 = [(); 1 + 1]; + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:45:43 + | +LL | type const ITEM4: usize = { 1 + 1 }; + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:62:23 + | +LL | T4: Trait, + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/explicit_anon_consts.rs:71:50 + | +LL | struct Default4; + | ^^^^^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:42:51 + | +LL | type const ITEM3: usize = const { N }; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:60:31 + | +LL | T3: Trait, + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:69:58 + | +LL | struct Default3; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:28:27 + | +LL | let _3 = [(); const { N }]; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:33:26 + | +LL | let _6: [(); const { N }] = todo!(); + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:11:41 + | +LL | type Adt3 = Foo; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/explicit_anon_consts.rs:19:42 + | +LL | type Arr3 = [(); const { N }]; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 13 previous errors + diff --git a/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs new file mode 100644 index 000000000000..be853bb87a37 --- /dev/null +++ b/tests/ui/const-generics/mgca/explicit_anon_consts_literals_hack.rs @@ -0,0 +1,29 @@ +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +trait Trait { + type const ASSOC: isize; +} + +fn ace>() {} +fn repeat_count() { + [(); 1]; +} +type ArrLen = [(); 1]; +struct Foo; +type NormalArg = (Foo<1>, Foo<-1>); + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct ADT { field: u8 } + +fn struct_expr() { + fn takes_n() {} + + takes_n::<{ ADT { field: 1 } }>(); + + takes_n::<{ ADT { field: const { 1 } } }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs b/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs new file mode 100644 index 000000000000..948b8ce72148 --- /dev/null +++ b/tests/ui/const-generics/mgca/generic_const_type_mismatch.rs @@ -0,0 +1,19 @@ +//! Regression test for +#![expect(incomplete_features)] +#![feature( + adt_const_params, + generic_const_items, + generic_const_parameter_types, + min_generic_const_args, + unsized_const_params +)] +use std::marker::ConstParamTy_; + +struct Foo { + field: T, +} + +type const WRAP : T = Foo::{field : 1}; +//~^ ERROR: type annotations needed for the literal + +fn main() {} diff --git a/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr b/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr new file mode 100644 index 000000000000..fdb0995bff5d --- /dev/null +++ b/tests/ui/const-generics/mgca/generic_const_type_mismatch.stderr @@ -0,0 +1,8 @@ +error: type annotations needed for the literal + --> $DIR/generic_const_type_mismatch.rs:16:59 + | +LL | type const WRAP : T = Foo::{field : 1}; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/higher-ranked-lts-bad.rs b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.rs new file mode 100644 index 000000000000..368644b641df --- /dev/null +++ b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.rs @@ -0,0 +1,12 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo() +where + for<'a> T: Trait + //~^ ERROR cannot capture late-bound lifetime in constant +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/higher-ranked-lts-bad.stderr b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.stderr new file mode 100644 index 000000000000..0f7389cac5cd --- /dev/null +++ b/tests/ui/const-generics/mgca/higher-ranked-lts-bad.stderr @@ -0,0 +1,8 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/higher-ranked-lts-bad.rs:8:38 + | +LL | for<'a> T: Trait + | -- lifetime defined here ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/higher-ranked-lts-good.rs b/tests/ui/const-generics/mgca/higher-ranked-lts-good.rs new file mode 100644 index 000000000000..5b455bb1e71e --- /dev/null +++ b/tests/ui/const-generics/mgca/higher-ranked-lts-good.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo() +where + T: Trait fn(&'a ()); 1 }> +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/late-bound-param-lt-bad.rs b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.rs new file mode 100644 index 000000000000..5c57bdfb9024 --- /dev/null +++ b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.rs @@ -0,0 +1,12 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Trait {} + +fn foo<'a, T>() +where + T: Trait + //~^ ERROR cannot capture late-bound lifetime in constant +{} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/late-bound-param-lt-bad.stderr b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.stderr new file mode 100644 index 000000000000..e5c22f282544 --- /dev/null +++ b/tests/ui/const-generics/mgca/late-bound-param-lt-bad.stderr @@ -0,0 +1,11 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/late-bound-param-lt-bad.rs:8:30 + | +LL | fn foo<'a, T>() + | -- lifetime defined here +LL | where +LL | T: Trait + | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs b/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs new file mode 100644 index 000000000000..bbe624269672 --- /dev/null +++ b/tests/ui/const-generics/mgca/multi_braced_direct_const_args.rs @@ -0,0 +1,24 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct Foo; + +trait Trait { + type const ASSOC: usize; +} + +type Arr = [(); {{{ N }}}]; +type Arr2 = [(); {{{ ::ASSOC }}}]; +type Ty = Foo<{{{ N }}}>; +type Ty2 = Foo<{{{ ::ASSOC }}}>; +struct Default; +struct Default2::ASSOC }}}>(T); + +fn repeat() { + let _1 = [(); {{{ N }}}]; + let _2 = [(); {{{ ::ASSOC }}}]; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/negated-literal.rs b/tests/ui/const-generics/mgca/negated-literal.rs new file mode 100644 index 000000000000..a7651822b0a8 --- /dev/null +++ b/tests/ui/const-generics/mgca/negated-literal.rs @@ -0,0 +1,17 @@ +//@ check-pass + +#![feature(adt_const_params, min_generic_const_args)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo { + field: isize +} + +fn foo() {} + +fn main() { + foo::<{ Foo { field: -1 } }>(); +} diff --git a/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs b/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs new file mode 100644 index 000000000000..6f1235269dfc --- /dev/null +++ b/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs @@ -0,0 +1,9 @@ +// Just a test of the error message (it's different for non-local consts) +//@ aux-build:non_local_const.rs +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] +extern crate non_local_const; +fn main() { + let x = [(); non_local_const::N]; + //~^ ERROR: use of `const` in the type system not defined as `type const` +} diff --git a/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr b/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr new file mode 100644 index 000000000000..3c10b78eb3e1 --- /dev/null +++ b/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr @@ -0,0 +1,10 @@ +error: use of `const` in the type system not defined as `type const` + --> $DIR/non-local-const-without-type_const.rs:7:18 + | +LL | let x = [(); non_local_const::N]; + | ^^^^^^^^^^^^^^^^^^ + | + = note: only consts marked defined as `type const` may be used in types + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs b/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs new file mode 100644 index 000000000000..cd68a2c0d430 --- /dev/null +++ b/tests/ui/const-generics/mgca/nonsensical-negated-literal.rs @@ -0,0 +1,26 @@ +#![feature(adt_const_params, min_generic_const_args)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo { + field: isize +} + +fn foo() {} + +fn main() { + foo::<{ Foo { field: -1_usize } }>(); + //~^ ERROR: type annotations needed for the literal + foo::<{ Foo { field: { -1_usize } } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + foo::<{ Foo { field: -true } }>(); + //~^ ERROR: the constant `true` is not of type `isize` + foo::<{ Foo { field: { -true } } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block + foo::<{ Foo { field: -"<3" } }>(); + //~^ ERROR: the constant `"<3"` is not of type `isize` + foo::<{ Foo { field: { -"<3" } } }>(); + //~^ ERROR: complex const arguments must be placed inside of a `const` block +} diff --git a/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr b/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr new file mode 100644 index 000000000000..43ed4b71e33e --- /dev/null +++ b/tests/ui/const-generics/mgca/nonsensical-negated-literal.stderr @@ -0,0 +1,38 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/nonsensical-negated-literal.rs:16:26 + | +LL | foo::<{ Foo { field: { -1_usize } } }>(); + | ^^^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/nonsensical-negated-literal.rs:20:26 + | +LL | foo::<{ Foo { field: { -true } } }>(); + | ^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/nonsensical-negated-literal.rs:24:26 + | +LL | foo::<{ Foo { field: { -"<3" } } }>(); + | ^^^^^^^^^ + +error: type annotations needed for the literal + --> $DIR/nonsensical-negated-literal.rs:14:26 + | +LL | foo::<{ Foo { field: -1_usize } }>(); + | ^^^^^^^^ + +error: the constant `true` is not of type `isize` + --> $DIR/nonsensical-negated-literal.rs:18:13 + | +LL | foo::<{ Foo { field: -true } }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool` + +error: the constant `"<3"` is not of type `isize` + --> $DIR/nonsensical-negated-literal.rs:22:13 + | +LL | foo::<{ Foo { field: -"<3" } }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&'static str` + +error: aborting due to 6 previous errors + diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs new file mode 100644 index 000000000000..16ed24a7b287 --- /dev/null +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.rs @@ -0,0 +1,38 @@ +//! Regression test for +//@ edition 2024 + +#![allow(incomplete_features)] +#![feature(min_generic_const_args, adt_const_params)] + +#[derive(Eq, PartialEq, core::marker::ConstParamTy)] +struct Foo; + +trait Trait { + + type const ASSOC: u32; +} + +fn foo() {} + +fn bar() { + foo::<{ Option::Some:: { 0: N } }>; + //~^ ERROR the constant `Option::::Some(N)` is not of type `Foo` +} + +fn baz() { + foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + //~^ ERROR the constant `Option::::Some(::ASSOC)` is not of type `Foo` +} + +fn main() {} + +fn test_ice_missing_bound() { + foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + //~^ ERROR the trait bound `T: Trait` is not satisfied + //~| ERROR the constant `Option::::Some(_)` is not of type `Foo` +} + +fn test_underscore_inference() { + foo::<{ Option::Some:: { 0: _ } }>(); + //~^ ERROR the constant `Option::::Some(_)` is not of type `Foo` +} diff --git a/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr new file mode 100644 index 000000000000..0184aebf157a --- /dev/null +++ b/tests/ui/const-generics/mgca/printing_valtrees_supports_non_values.stderr @@ -0,0 +1,62 @@ +error: the constant `Option::::Some(N)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:18:13 + | +LL | foo::<{ Option::Some:: { 0: N } }>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: the constant `Option::::Some(::ASSOC)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:23:13 + | +LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error[E0277]: the trait bound `T: Trait` is not satisfied + --> $DIR/printing_valtrees_supports_non_values.rs:30:5 + | +LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` + | +help: consider restricting type parameter `T` with trait `Trait` + | +LL | fn test_ice_missing_bound() { + | +++++++ + +error: the constant `Option::::Some(_)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:30:13 + | +LL | foo::<{ Option::Some:: { 0: ::ASSOC } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: the constant `Option::::Some(_)` is not of type `Foo` + --> $DIR/printing_valtrees_supports_non_values.rs:36:13 + | +LL | foo::<{ Option::Some:: { 0: _ } }>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Foo`, found `Option` + | +note: required by a const generic parameter in `foo` + --> $DIR/printing_valtrees_supports_non_values.rs:15:8 + | +LL | fn foo() {} + | ^^^^^^^^^^^^ required by this const generic parameter in `foo` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/mgca/projection-error.rs b/tests/ui/const-generics/mgca/projection-error.rs index edb6db098084..d3bd520297e1 100644 --- a/tests/ui/const-generics/mgca/projection-error.rs +++ b/tests/ui/const-generics/mgca/projection-error.rs @@ -5,10 +5,8 @@ // containing erroneous types normalizes to a const error instead of // a type error. - pub trait Tr { - #[type_const] - const SIZE: usize; + type const SIZE: usize; } fn mk_array(_x: T) -> [(); >::SIZE] {} diff --git a/tests/ui/const-generics/mgca/projection-error.stderr b/tests/ui/const-generics/mgca/projection-error.stderr index 9357600a5e11..94e6bbcdd87f 100644 --- a/tests/ui/const-generics/mgca/projection-error.stderr +++ b/tests/ui/const-generics/mgca/projection-error.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find type `T` in this scope - --> $DIR/projection-error.rs:14:17 + --> $DIR/projection-error.rs:12:17 | LL | pub trait Tr { | --------------- similarly named trait `Tr` defined here @@ -17,7 +17,7 @@ LL | fn mk_array(_x: T) -> [(); >::SIZE] {} | +++ error[E0425]: cannot find type `T` in this scope - --> $DIR/projection-error.rs:14:29 + --> $DIR/projection-error.rs:12:29 | LL | pub trait Tr { | --------------- similarly named trait `Tr` defined here diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.rs b/tests/ui/const-generics/mgca/selftyalias-containing-param.rs new file mode 100644 index 000000000000..5ab39799078f --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.rs @@ -0,0 +1,13 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct S([(); N]); + +impl S { + fn foo() -> [(); const { let _: Self = loop {}; 1 }] { + //~^ ERROR generic `Self` + todo!() + } +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr new file mode 100644 index 000000000000..1c841e39e673 --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyalias-containing-param.stderr @@ -0,0 +1,15 @@ +error: generic `Self` types are currently not permitted in anonymous constants + --> $DIR/selftyalias-containing-param.rs:7:37 + | +LL | fn foo() -> [(); const { let _: Self = loop {}; 1 }] { + | ^^^^ + | +note: not a concrete type + --> $DIR/selftyalias-containing-param.rs:6:22 + | +LL | impl S { + | ^^^^ + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/selftyparam.rs b/tests/ui/const-generics/mgca/selftyparam.rs new file mode 100644 index 000000000000..58433405b8ca --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyparam.rs @@ -0,0 +1,9 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Tr { + fn foo() -> [(); const { let _: Self; 1 }]; + //~^ ERROR generic parameters +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/selftyparam.stderr b/tests/ui/const-generics/mgca/selftyparam.stderr new file mode 100644 index 000000000000..c3e0770fb978 --- /dev/null +++ b/tests/ui/const-generics/mgca/selftyparam.stderr @@ -0,0 +1,10 @@ +error: generic parameters may not be used in const operations + --> $DIR/selftyparam.rs:5:37 + | +LL | fn foo() -> [(); const { let _: Self; 1 }]; + | ^^^^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs new file mode 100644 index 000000000000..d06ea7a10c74 --- /dev/null +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.rs @@ -0,0 +1,13 @@ +//! regression test for +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +fn foo() { + [0; size_of::<*mut T>()]; + //~^ ERROR: complex const arguments must be placed inside of a `const` block + [0; const { size_of::<*mut T>() }]; + //~^ ERROR: generic parameters may not be used in const operations + [0; const { size_of::<*mut i32>() }]; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr new file mode 100644 index 000000000000..61e934380c36 --- /dev/null +++ b/tests/ui/const-generics/mgca/size-of-generic-ptr-in-array-len.stderr @@ -0,0 +1,16 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/size-of-generic-ptr-in-array-len.rs:6:9 + | +LL | [0; size_of::<*mut T>()]; + | ^^^^^^^^^^^^^^^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/size-of-generic-ptr-in-array-len.rs:8:32 + | +LL | [0; const { size_of::<*mut T>() }]; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/struct-ctor-in-array-len.rs b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.rs new file mode 100644 index 000000000000..715caef38a9a --- /dev/null +++ b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.rs @@ -0,0 +1,16 @@ +// Regression test for https://github.com/rust-lang/rust/issues/141738 +// +// Using a struct constructor as an array repeat count with +// `min_generic_const_args` used to ICE with "unexpected `DefKind` +// for const alias to resolve to: Ctor(Struct, Const)". +// It should now produce a proper type error. + +#![feature(min_generic_const_args)] +//~^ WARN the feature `min_generic_const_args` is incomplete + +struct S; + +fn main() { + let _b = [0; S]; + //~^ ERROR the constant `S` is not of type `usize` +} diff --git a/tests/ui/const-generics/mgca/struct-ctor-in-array-len.stderr b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.stderr new file mode 100644 index 000000000000..baf587a856bc --- /dev/null +++ b/tests/ui/const-generics/mgca/struct-ctor-in-array-len.stderr @@ -0,0 +1,19 @@ +warning: the feature `min_generic_const_args` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/struct-ctor-in-array-len.rs:8:12 + | +LL | #![feature(min_generic_const_args)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: the constant `S` is not of type `usize` + --> $DIR/struct-ctor-in-array-len.rs:14:14 + | +LL | let _b = [0; S]; + | ^^^^^^ expected `usize`, found `S` + | + = note: the length of array `[{integer}; S]` must be type `usize` + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/const-generics/mgca/struct_expr_with_macros.rs b/tests/ui/const-generics/mgca/struct_expr_with_macros.rs new file mode 100644 index 000000000000..b59a73066488 --- /dev/null +++ b/tests/ui/const-generics/mgca/struct_expr_with_macros.rs @@ -0,0 +1,31 @@ +//@ check-pass + +// Test that the def collector makes `AnonConst`s not `InlineConst`s even +// when the const block is obscured via macros. + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +macro_rules! const_block { + ($e:expr) => { const { + $e + } } +} + +macro_rules! foo_expr { + ($e:expr) => { Foo { + field: $e, + } } +} + +use std::marker::ConstParamTy; + +#[derive(PartialEq, Eq, ConstParamTy)] +struct Foo { field: u32 } + +fn foo() {} + +fn main() { + foo::<{ Foo { field: const_block!{ 1 + 1 }} }>(); + foo::<{ foo_expr! { const_block! { 1 + 1 }} }>(); +} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs b/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs new file mode 100644 index 000000000000..e946441453d8 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_arg_simple.rs @@ -0,0 +1,51 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] +#![allow(dead_code)] + +use std::marker::ConstParamTy; + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +struct Point(u32, u32); + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +enum MyEnum { + Variant(T), + Other, +} + +trait Trait { + type const ASSOC: u32; +} + +fn with_point() -> Point { + P +} + +fn with_enum>() -> MyEnum { + E +} + +fn test() { + with_point::<{ Point(::ASSOC, N) }>(); +} + +fn test_basic() { + with_point::<{ Point(N, N) }>(); + with_point::<{ Point(const { 5 }, const { 10 }) }>(); + + with_enum::<{ MyEnum::Variant::(N) }>(); + with_enum::<{ MyEnum::Variant::(const { 42 }) }>(); + + with_enum::<{ >::Variant(N) }>(); +} + +fn main() { + test_basic::<5>(); + + let p = with_point::<{ Point(const { 1 }, const { 2 }) }>(); + assert_eq!(p, Point(1, 2)); + + let e = with_enum::<{ MyEnum::Variant::(const { 10 }) }>(); + assert_eq!(e, MyEnum::Variant(10)); +} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs new file mode 100644 index 000000000000..2e39f8952b11 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.rs @@ -0,0 +1,19 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Point(u32, u32); + +fn with_point() {} + +fn test() { + with_point::<{ Point(N + 1, N) }>(); + //~^ ERROR complex const arguments must be placed inside of a `const` block + + with_point::<{ Point(const { N + 1 }, N) }>(); + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr new file mode 100644 index 000000000000..2961c714d141 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_complex_args.stderr @@ -0,0 +1,16 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/tuple_ctor_complex_args.rs:12:26 + | +LL | with_point::<{ Point(N + 1, N) }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/tuple_ctor_complex_args.rs:15:34 + | +LL | with_point::<{ Point(const { N + 1 }, N) }>(); + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs new file mode 100644 index 000000000000..43d0d21fb736 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs @@ -0,0 +1,47 @@ +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Point(u32, u32); + +#[derive(Eq, PartialEq, ConstParamTy)] +enum MyEnum { + Variant(T), + Unit, +} + + +type const CONST_ITEM: u32 = 42; + +fn accepts_point() {} +fn accepts_enum>() {} + +fn non_ctor() {} + +fn test_errors() { + accepts_point::<{ Point(N) }>(); + //~^ ERROR tuple constructor has 2 arguments but 1 were provided + + accepts_point::<{ Point(N, N, N) }>(); + //~^ ERROR tuple constructor has 2 arguments but 3 were provided + + accepts_point::<{ UnresolvedIdent(N, N) }>(); + //~^ ERROR cannot find function, tuple struct or tuple variant `UnresolvedIdent` in this scope + //~| ERROR tuple constructor with invalid base path + + accepts_point::<{ non_ctor(N, N) }>(); + //~^ ERROR complex const arguments must be placed inside of a `const` block + + accepts_point::<{ CONST_ITEM(N, N) }>(); + //~^ ERROR tuple constructor with invalid base path + + accepts_point::<{ Point }>(); + //~^ ERROR the constant `Point` is not of type `Point` + + accepts_enum::<{ MyEnum::Variant:: }>(); + //~^ ERROR the constant `MyEnum::::Variant` is not of type `MyEnum` +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr new file mode 100644 index 000000000000..ce210b2b3e39 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr @@ -0,0 +1,68 @@ +error[E0425]: cannot find function, tuple struct or tuple variant `UnresolvedIdent` in this scope + --> $DIR/tuple_ctor_erroneous.rs:30:23 + | +LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); + | ^^^^^^^^^^^^^^^ not found in this scope + | +help: you might be missing a const parameter + | +LL | fn test_errors() { + | +++++++++++++++++++++++++++++++++++ + +error: tuple constructor has 2 arguments but 1 were provided + --> $DIR/tuple_ctor_erroneous.rs:24:23 + | +LL | accepts_point::<{ Point(N) }>(); + | ^^^^^^^^ + +error: tuple constructor has 2 arguments but 3 were provided + --> $DIR/tuple_ctor_erroneous.rs:27:23 + | +LL | accepts_point::<{ Point(N, N, N) }>(); + | ^^^^^^^^^^^^^^ + +error: tuple constructor with invalid base path + --> $DIR/tuple_ctor_erroneous.rs:30:23 + | +LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/tuple_ctor_erroneous.rs:34:23 + | +LL | accepts_point::<{ non_ctor(N, N) }>(); + | ^^^^^^^^^^^^^^ + +error: tuple constructor with invalid base path + --> $DIR/tuple_ctor_erroneous.rs:37:23 + | +LL | accepts_point::<{ CONST_ITEM(N, N) }>(); + | ^^^^^^^^^^^^^^^^ + +error: the constant `Point` is not of type `Point` + --> $DIR/tuple_ctor_erroneous.rs:40:23 + | +LL | accepts_point::<{ Point }>(); + | ^^^^^ expected `Point`, found struct constructor + | +note: required by a const generic parameter in `accepts_point` + --> $DIR/tuple_ctor_erroneous.rs:18:18 + | +LL | fn accepts_point() {} + | ^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_point` + +error: the constant `MyEnum::::Variant` is not of type `MyEnum` + --> $DIR/tuple_ctor_erroneous.rs:43:22 + | +LL | accepts_enum::<{ MyEnum::Variant:: }>(); + | ^^^^^^^^^^^^^^^^^^^^^^ expected `MyEnum`, found enum constructor + | +note: required by a const generic parameter in `accepts_enum` + --> $DIR/tuple_ctor_erroneous.rs:19:17 + | +LL | fn accepts_enum>() {} + | ^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_enum` + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.rs b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.rs new file mode 100644 index 000000000000..5c7290b40be2 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.rs @@ -0,0 +1,16 @@ +//! Regression test for + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +pub struct S(); + +impl S { + pub fn f() -> [u8; S] { + //~^ ERROR the constant `S` is not of type `usize` + [] + //~^ ERROR mismatched types [E0308] + } +} + +pub fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.stderr b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.stderr new file mode 100644 index 000000000000..64c3cecd4fb5 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_in_array_len.stderr @@ -0,0 +1,23 @@ +error: the constant `S` is not of type `usize` + --> $DIR/tuple_ctor_in_array_len.rs:9:19 + | +LL | pub fn f() -> [u8; S] { + | ^^^^^^^ expected `usize`, found struct constructor + | + = note: the length of array `[u8; S]` must be type `usize` + +error[E0308]: mismatched types + --> $DIR/tuple_ctor_in_array_len.rs:11:9 + | +LL | pub fn f() -> [u8; S] { + | ------- expected `[u8; S]` because of return type +LL | +LL | [] + | ^^ expected an array with a size of S, found one with a size of 0 + | + = note: expected array `[u8; S]` + found array `[_; 0]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/tuple_ctor_nested.rs b/tests/ui/const-generics/mgca/tuple_ctor_nested.rs new file mode 100644 index 000000000000..49a31ea3e527 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_nested.rs @@ -0,0 +1,38 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +struct Inner(u32); + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +struct Outer(Inner); + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +enum Container { + Wrap(T), +} + +fn with_outer() -> Outer { + O +} + +fn with_container>() -> Container { + C +} + +fn test() { + with_outer::<{ Outer(Inner(N)) }>(); + with_outer::<{ Outer(Inner(const { 42 })) }>(); + + with_container::<{ Container::Wrap::(Inner(N)) }>(); +} + +fn main() { + test::<5>(); + + let o = with_outer::<{ Outer(Inner(const { 10 })) }>(); + assert_eq!(o, Outer(Inner(10))); +} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_type_relative.rs b/tests/ui/const-generics/mgca/tuple_ctor_type_relative.rs new file mode 100644 index 000000000000..d5a07cbb7d70 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_ctor_type_relative.rs @@ -0,0 +1,26 @@ +//@ run-pass +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Debug, Eq, PartialEq, ConstParamTy)] +enum Option { + Some(T), +} + +fn with_option>() -> Option { + O +} + +fn test() { + with_option::<{ >::Some(N) }>(); + with_option::<{ >::Some(const { 42 }) }>(); +} + +fn main() { + test::<5>(); + + let o = with_option::<{ >::Some(const { 10 }) }>(); + assert_eq!(o, Option::Some(10)); +} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs new file mode 100644 index 000000000000..4aecd30e86bb --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.rs @@ -0,0 +1,8 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct Y { + stuff: [u8; { ([1, 2], 3, [4, 5]) }], //~ ERROR expected `usize`, found const tuple +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr new file mode 100644 index 000000000000..468bf703d90d --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_bad-issue-151048.stderr @@ -0,0 +1,8 @@ +error: expected `usize`, found const tuple + --> $DIR/tuple_expr_arg_bad-issue-151048.rs:5:19 + | +LL | stuff: [u8; { ([1, 2], 3, [4, 5]) }], + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs new file mode 100644 index 000000000000..5a40c1b14c2d --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.rs @@ -0,0 +1,20 @@ +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + + type const ASSOC: usize; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_tuple::<{ (N, T::ASSOC + 1) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + + takes_nested_tuple::<{ (N, (N, N + 1)) }>(); //~ ERROR complex const arguments must be placed inside of a `const` block + takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); //~ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr new file mode 100644 index 000000000000..b4853d3c2e38 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_complex.stderr @@ -0,0 +1,28 @@ +error: complex const arguments must be placed inside of a `const` block + --> $DIR/tuple_expr_arg_complex.rs:13:25 + | +LL | takes_tuple::<{ (N, N + 1) }>(); + | ^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/tuple_expr_arg_complex.rs:14:25 + | +LL | takes_tuple::<{ (N, T::ASSOC + 1) }>(); + | ^^^^^^^^^^^^ + +error: complex const arguments must be placed inside of a `const` block + --> $DIR/tuple_expr_arg_complex.rs:16:36 + | +LL | takes_nested_tuple::<{ (N, (N, N + 1)) }>(); + | ^^^^^ + +error: generic parameters may not be used in const operations + --> $DIR/tuple_expr_arg_complex.rs:17:44 + | +LL | takes_nested_tuple::<{ (N, (N, const { N + 1 })) }>(); + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 4 previous errors + diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs new file mode 100644 index 000000000000..95acd66074f6 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.rs @@ -0,0 +1,8 @@ +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +pub fn takes_nested_tuple() { + takes_nested_tuple::<{ () }> //~ ERROR expected `u32`, found const tuple +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr new file mode 100644 index 000000000000..dfbd294951fd --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_mismatch_type.stderr @@ -0,0 +1,8 @@ +error: expected `u32`, found const tuple + --> $DIR/tuple_expr_arg_mismatch_type.rs:5:28 + | +LL | takes_nested_tuple::<{ () }> + | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs b/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs new file mode 100644 index 000000000000..4c040bcaa945 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_arg_simple.rs @@ -0,0 +1,21 @@ +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params, unsized_const_params)] +#![expect(incomplete_features)] + +trait Trait { + type const ASSOC: u32; +} + +fn takes_tuple() {} +fn takes_nested_tuple() {} + +fn generic_caller() { + takes_tuple::<{ (N, N2) }>(); + takes_tuple::<{ (N, T::ASSOC) }>(); + + takes_nested_tuple::<{ (N, (N, N2)) }>(); + takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs new file mode 100644 index 000000000000..4bf62b3a3070 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.rs @@ -0,0 +1,20 @@ +//! Regression test for +#![expect(incomplete_features)] +#![feature( + adt_const_params, + min_generic_const_args, + unsized_const_params +)] +fn foo() {} +fn bar() {} +fn qux() {} + +fn main() { + foo::<{ (1, true) }>(); + //~^ ERROR: type annotations needed for the literal + bar::<{ (1_u32, [1, 2]) }>(); + //~^ ERROR: expected `i32`, found const array + qux::<{ (1i32, 'a') }>(); + //~^ ERROR: the constant `1` is not of type `char` + //~| ERROR: the constant `'a'` is not of type `i32 +} diff --git a/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr new file mode 100644 index 000000000000..4136c7337cd4 --- /dev/null +++ b/tests/ui/const-generics/mgca/tuple_expr_type_mismatch.stderr @@ -0,0 +1,26 @@ +error: type annotations needed for the literal + --> $DIR/tuple_expr_type_mismatch.rs:13:14 + | +LL | foo::<{ (1, true) }>(); + | ^ + +error: expected `i32`, found const array + --> $DIR/tuple_expr_type_mismatch.rs:15:21 + | +LL | bar::<{ (1_u32, [1, 2]) }>(); + | ^^^^^^ + +error: the constant `1` is not of type `char` + --> $DIR/tuple_expr_type_mismatch.rs:17:13 + | +LL | qux::<{ (1i32, 'a') }>(); + | ^^^^^^^^^^^ expected `char`, found `i32` + +error: the constant `'a'` is not of type `i32` + --> $DIR/tuple_expr_type_mismatch.rs:17:13 + | +LL | qux::<{ (1i32, 'a') }>(); + | ^^^^^^^^^^^ expected `i32`, found `char` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs new file mode 100644 index 000000000000..e98b1ad4fe37 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.rs @@ -0,0 +1,17 @@ +//@ needs-rustc-debug-assertions + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +trait Tr { + type const SIZE: usize; +} + +struct T; + +impl Tr for T { + type const SIZE: usize; + //~^ ERROR associated constant in `impl` without body +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr new file mode 100644 index 000000000000..ba01456ee040 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-assoc-const-without-body.stderr @@ -0,0 +1,10 @@ +error: associated constant in `impl` without body + --> $DIR/type-const-assoc-const-without-body.rs:13:5 + | +LL | type const SIZE: usize; + | ^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/type-const-ctor-148953.rs b/tests/ui/const-generics/mgca/type-const-ctor-148953.rs new file mode 100644 index 000000000000..bdd3dcf8618f --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-ctor-148953.rs @@ -0,0 +1,31 @@ +//! Regression test for +//! +//! Unit struct constructors used as the RHS of a `type const` associated +//! const used to ICE during normalization because they were lowered as +//! `Const::new_unevaluated` with a Ctor def_id. Fixed by adding proper const +//! constructor support that produces a concrete ValTree value instead. + +//@ check-pass + +#![feature(min_generic_const_args, adt_const_params)] +#![expect(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(ConstParamTy, PartialEq, Eq)] +struct S; + +impl S { + type const N: S = S; +} + +#[derive(ConstParamTy, PartialEq, Eq)] +enum E { + V, +} + +impl E { + type const M: E = { E::V }; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs new file mode 100644 index 000000000000..9fa417637295 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.rs @@ -0,0 +1,11 @@ +//@ needs-rustc-debug-assertions + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +impl S { //~ ERROR cannot find type `S` in this scope + type const SIZE: usize; + //~^ ERROR associated constant in `impl` without body +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr new file mode 100644 index 000000000000..b1e1edfa70d6 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-inherent-assoc-const-without-body.stderr @@ -0,0 +1,17 @@ +error: associated constant in `impl` without body + --> $DIR/type-const-inherent-assoc-const-without-body.rs:7:5 + | +LL | type const SIZE: usize; + | ^^^^^^^^^^^^^^^^^^^^^^- + | | + | help: provide a definition for the constant: `= ;` + +error[E0425]: cannot find type `S` in this scope + --> $DIR/type-const-inherent-assoc-const-without-body.rs:6:6 + | +LL | impl S { + | ^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/mgca/type-const-used-in-trait.rs b/tests/ui/const-generics/mgca/type-const-used-in-trait.rs new file mode 100644 index 000000000000..1efc65bd7018 --- /dev/null +++ b/tests/ui/const-generics/mgca/type-const-used-in-trait.rs @@ -0,0 +1,12 @@ +//@ check-pass + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +type const N: usize = 2; + +trait CollectArray { + fn inner_array(&mut self) -> [A; N]; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_as_const_in_array_len.rs b/tests/ui/const-generics/mgca/type_as_const_in_array_len.rs new file mode 100644 index 000000000000..b6b76fe3fc91 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_as_const_in_array_len.rs @@ -0,0 +1,14 @@ +//! Regression test for + +#![feature(min_generic_const_args)] +#![expect(incomplete_features)] + +struct B(Box<[u8; C]>); +//~^ ERROR missing generics for struct `C` +impl B { + fn d(self) { + self.0.e() + } +} +struct C<'a>(&'a u8); +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_as_const_in_array_len.stderr b/tests/ui/const-generics/mgca/type_as_const_in_array_len.stderr new file mode 100644 index 000000000000..482fd730a71c --- /dev/null +++ b/tests/ui/const-generics/mgca/type_as_const_in_array_len.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for struct `C` + --> $DIR/type_as_const_in_array_len.rs:6:19 + | +LL | struct B(Box<[u8; C]>); + | ^ expected 1 lifetime argument + | +note: struct defined here, with 1 lifetime parameter: `'a` + --> $DIR/type_as_const_in_array_len.rs:13:8 + | +LL | struct C<'a>(&'a u8); + | ^ -- +help: add missing lifetime argument + | +LL | struct B(Box<[u8; C<'a>]>); + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/mgca/type_const-array-return.rs b/tests/ui/const-generics/mgca/type_const-array-return.rs new file mode 100644 index 000000000000..43db35966a45 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-array-return.rs @@ -0,0 +1,24 @@ +//@ check-pass +// This test should compile without an ICE. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +pub struct A; + +pub trait Array { + type const LEN: usize; + fn arr() -> [u8; Self::LEN]; +} + +impl Array for A { + type const LEN: usize = 4; + + #[allow(unused_braces)] + fn arr() -> [u8; const { Self::LEN }] { + return [0u8; const { Self::LEN }]; + } +} + +fn main() { + let _ = A::arr(); +} diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr new file mode 100644 index 000000000000..095f42355c77 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr @@ -0,0 +1,38 @@ +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:8:58 + | +LL | type const FOO: [T; 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:12:43 + | +LL | type const BAR: [(); N] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants with lifetimes in their type are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:16:35 + | +LL | type const BAZ<'a>: [&'a (); 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:32:64 + | +LL | type const ASSOC: [T; 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:36:55 + | +LL | type const ASSOC_CONST: [(); N] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants with lifetimes in their type are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:40:44 + | +LL | type const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr new file mode 100644 index 000000000000..b18bd678973a --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr @@ -0,0 +1,57 @@ +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:8:50 + | +LL | type const FOO: [T; 0] = const { [] }; + | ^ the type must not depend on the parameter `T` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:12:38 + | +LL | type const BAR: [(); N] = const { [] }; + | ^ the type must not depend on the parameter `N` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:16:23 + | +LL | type const BAZ<'a>: [&'a (); 0] = const { [] }; + | ^^ the type must not depend on the parameter `'a` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:21:56 + | +LL | type const ASSOC: [T; 0]; + | ^ the type must not depend on the parameter `T` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:24:50 + | +LL | type const ASSOC_CONST: [(); N]; + | ^ the type must not depend on the parameter `N` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:27:32 + | +LL | type const ASSOC_LT<'a>: [&'a (); 0]; + | ^^ the type must not depend on the parameter `'a` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:32:56 + | +LL | type const ASSOC: [T; 0] = const { [] }; + | ^ the type must not depend on the parameter `T` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:36:50 + | +LL | type const ASSOC_CONST: [(); N] = const { [] }; + | ^ the type must not depend on the parameter `N` + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:40:32 + | +LL | type const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + | ^^ the type must not depend on the parameter `'a` + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs new file mode 100644 index 000000000000..72ae464822e4 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs @@ -0,0 +1,45 @@ +//@ revisions: nogate gate +//@ [gate] check-fail +// FIXME(generic_const_parameter_types): this should pass +#![expect(incomplete_features)] +#![feature(adt_const_params, unsized_const_params, min_generic_const_args, generic_const_items)] +#![cfg_attr(gate, feature(generic_const_parameter_types))] + +type const FOO: [T; 0] = const { [] }; +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + +type const BAR: [(); N] = const { [] }; +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + +type const BAZ<'a>: [&'a (); 0] = const { [] }; +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +//[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported + +trait Tr { + type const ASSOC: [T; 0]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + + type const ASSOC_CONST: [(); N]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + + type const ASSOC_LT<'a>: [&'a (); 0]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters +} + +impl Tr for () { + type const ASSOC: [T; 0] = const { [] }; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + + type const ASSOC_CONST: [(); N] = const { [] }; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + //[gate]~^^ ERROR anonymous constants referencing generics are not yet supported + + type const ASSOC_LT<'a>: [&'a (); 0] = const { [] }; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + //[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-incemental-compile.rs b/tests/ui/const-generics/mgca/type_const-incemental-compile.rs new file mode 100644 index 000000000000..7094d89d5062 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-incemental-compile.rs @@ -0,0 +1,10 @@ +//@ check-pass +//@compile-flags: -Clink-dead-code=true +// link-dead-code tries to eagerly monomorphize and collect items +// This lead to collector.rs to try and evaluate a type_const +// which will fail since they do not have bodies. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +type const TYPE_CONST: usize = 0; +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs new file mode 100644 index 000000000000..3262e79478bd --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.rs @@ -0,0 +1,11 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +struct A; + +impl A { + type const B = 4; + //~^ ERROR: missing type for `const` item +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr new file mode 100644 index 000000000000..77e54ab2f2e9 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-inherent-const-omitted-type.stderr @@ -0,0 +1,13 @@ +error: missing type for `const` item + --> $DIR/type_const-inherent-const-omitted-type.rs:7:17 + | +LL | type const B = 4; + | ^ + | +help: provide a type for the item + | +LL | type const B: = 4; + | ++++++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs index 8d2eae71d330..c73785f9a3e3 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.rs +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.rs @@ -1,22 +1,19 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] -#[type_const] -const FREE: u32 = 5_usize; -//~^ ERROR mismatched types +type const FREE: u32 = 5_usize; +//~^ ERROR the constant `5` is not of type `u32` +//~| ERROR mismatched types -#[type_const] -const FREE2: isize = FREE; +type const FREE2: isize = FREE; //~^ ERROR the constant `5` is not of type `isize` trait Tr { - #[type_const] - const N: usize; + type const N: usize; } impl Tr for () { - #[type_const] - const N: usize = false; + type const N: usize = false; //~^ ERROR mismatched types } diff --git a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr index 4029bb7b6bff..f7f64c535f60 100644 --- a/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr +++ b/tests/ui/const-generics/mgca/type_const-mismatched-types.stderr @@ -1,27 +1,33 @@ -error: the constant `5` is not of type `isize` - --> $DIR/type_const-mismatched-types.rs:9:1 +error: the constant `5` is not of type `u32` + --> $DIR/type_const-mismatched-types.rs:4:1 | -LL | const FREE2: isize = FREE; - | ^^^^^^^^^^^^^^^^^^ expected `isize`, found `u32` +LL | type const FREE: u32 = 5_usize; + | ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` + +error: the constant `5` is not of type `isize` + --> $DIR/type_const-mismatched-types.rs:8:1 + | +LL | type const FREE2: isize = FREE; + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `usize` error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:5:19 + --> $DIR/type_const-mismatched-types.rs:16:27 | -LL | const FREE: u32 = 5_usize; - | ^^^^^^^ expected `u32`, found `usize` +LL | type const N: usize = false; + | ^^^^^ expected `usize`, found `bool` + +error[E0308]: mismatched types + --> $DIR/type_const-mismatched-types.rs:4:24 + | +LL | type const FREE: u32 = 5_usize; + | ^^^^^^^ expected `u32`, found `usize` | help: change the type of the numeric literal from `usize` to `u32` | -LL - const FREE: u32 = 5_usize; -LL + const FREE: u32 = 5_u32; +LL - type const FREE: u32 = 5_usize; +LL + type const FREE: u32 = 5_u32; | -error[E0308]: mismatched types - --> $DIR/type_const-mismatched-types.rs:19:22 - | -LL | const N: usize = false; - | ^^^^^ expected `usize`, found `bool` - -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.rs b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs index 27b446e6a40d..b78bb4ca599d 100644 --- a/tests/ui/const-generics/mgca/type_const-not-constparamty.rs +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.rs @@ -4,22 +4,19 @@ struct S; // FIXME(mgca): need support for ctors without anon const -// (we use double-braces to trigger an anon const here) -#[type_const] -const FREE: S = { { S } }; +// (we use a const-block to trigger an anon const here) +type const FREE: S = const { S }; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter trait Tr { - #[type_const] - const N: S; + type const N: S; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter } impl Tr for S { // FIXME(mgca): need support for ctors without anon const - // (we use double-braces to trigger an anon const here) - #[type_const] - const N: S = { { S } }; + // (we use a const-block to trigger an anon const here) + type const N: S = const { S }; //~^ ERROR `S` must implement `ConstParamTy` to be used as the type of a const generic parameter } diff --git a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr index 6b13917a95cd..2cbb644f2c71 100644 --- a/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr +++ b/tests/ui/const-generics/mgca/type_const-not-constparamty.stderr @@ -1,8 +1,8 @@ error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/type_const-not-constparamty.rs:9:13 + --> $DIR/type_const-not-constparamty.rs:8:18 | -LL | const FREE: S = { { S } }; - | ^ +LL | type const FREE: S = const { S }; + | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct | @@ -11,10 +11,10 @@ LL | struct S; | error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/type_const-not-constparamty.rs:22:14 + --> $DIR/type_const-not-constparamty.rs:19:19 | -LL | const N: S = { { S } }; - | ^ +LL | type const N: S = const { S }; + | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct | @@ -23,10 +23,10 @@ LL | struct S; | error[E0741]: `S` must implement `ConstParamTy` to be used as the type of a const generic parameter - --> $DIR/type_const-not-constparamty.rs:14:14 + --> $DIR/type_const-not-constparamty.rs:12:19 | -LL | const N: S; - | ^ +LL | type const N: S; + | ^ | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct | diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs index d38d5ab7a59f..f4cf3a4c5ce9 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.rs @@ -1,34 +1,11 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args, generic_const_items)] -#[type_const] -const FREE1: usize = std::mem::size_of::(); -//~^ ERROR generic parameters may not be used in const operations -#[type_const] -const FREE2: usize = I + 1; + +type const FREE1: usize = const { std::mem::size_of::() }; //~^ ERROR generic parameters may not be used in const operations -pub trait Tr { - #[type_const] - const N1: usize; - #[type_const] - const N2: usize; - #[type_const] - const N3: usize; -} - -pub struct S; - -impl Tr for S { - #[type_const] - const N1: usize = std::mem::size_of::(); - //~^ ERROR generic parameters may not be used in const operations - #[type_const] - const N2: usize = I + 1; - //~^ ERROR generic parameters may not be used in const operations - #[type_const] - const N3: usize = 2 & X; - //~^ ERROR generic parameters may not be used in const operations -} +type const FREE2: usize = const { I + 1 }; +//~^ ERROR generic parameters may not be used in const operations fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr index 76638f27e96c..475d2cf312d6 100644 --- a/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr +++ b/tests/ui/const-generics/mgca/type_const-on-generic-expr.stderr @@ -1,47 +1,18 @@ error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:5:45 + --> $DIR/type_const-on-generic-expr.rs:5:58 | -LL | const FREE1: usize = std::mem::size_of::(); - | ^ cannot perform const operation using `T` +LL | type const FREE1: usize = const { std::mem::size_of::() }; + | ^ | - = note: type parameters may not be used in const expressions - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:8:38 + --> $DIR/type_const-on-generic-expr.rs:8:51 | -LL | const FREE2: usize = I + 1; - | ^ cannot perform const operation using `I` +LL | type const FREE2: usize = const { I + 1 }; + | ^ | - = help: const parameters may only be used as standalone arguments here, i.e. `I` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items -error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:24:46 - | -LL | const N1: usize = std::mem::size_of::(); - | ^ cannot perform const operation using `T` - | - = note: type parameters may not be used in const expressions - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:27:39 - | -LL | const N2: usize = I + 1; - | ^ cannot perform const operation using `I` - | - = help: const parameters may only be used as standalone arguments here, i.e. `I` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/type_const-on-generic-expr.rs:30:27 - | -LL | const N3: usize = 2 & X; - | ^ cannot perform const operation using `X` - | - = help: const parameters may only be used as standalone arguments here, i.e. `X` - = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs new file mode 100644 index 000000000000..2a26138d373f --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.rs @@ -0,0 +1,21 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args, generic_const_items)] + +pub trait Tr { + type const N1: usize; + type const N2: usize; + type const N3: usize; +} + +pub struct S; + +impl Tr for S { + type const N1: usize = const { std::mem::size_of::() }; + //~^ ERROR generic parameters may not be used in const operations + type const N2: usize = const { I + 1 }; + //~^ ERROR generic parameters may not be used in const operations + type const N3: usize = const { 2 & X }; + //~^ ERROR generic parameters may not be used in const operations +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr new file mode 100644 index 000000000000..e13d6fbcdd82 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-on-generic_expr-2.stderr @@ -0,0 +1,26 @@ +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic_expr-2.rs:13:59 + | +LL | type const N1: usize = const { std::mem::size_of::() }; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic_expr-2.rs:15:52 + | +LL | type const N2: usize = const { I + 1 }; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: generic parameters may not be used in const operations + --> $DIR/type_const-on-generic_expr-2.rs:17:40 + | +LL | type const N3: usize = const { 2 & X }; + | ^ + | + = help: add `#![feature(opaque_generic_const_args)]` to allow generic expressions as the RHS of const items + +error: aborting due to 3 previous errors + diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs new file mode 100644 index 000000000000..a7ff9f0ce03f --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.rs @@ -0,0 +1,21 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +trait BadTr { + const NUM: usize; +} + +struct GoodS; + +impl BadTr for GoodS { + type const NUM: = 84; + //~^ ERROR: missing type for `const` item + +} + +fn accept_bad_tr>(_x: &T) {} +//~^ ERROR use of trait associated const not defined as `type const` + +fn main() { + accept_bad_tr::<84, _>(&GoodS); +} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr new file mode 100644 index 000000000000..11a60246f6a6 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl-omitted-type.stderr @@ -0,0 +1,16 @@ +error: missing type for `const` item + --> $DIR/type_const-only-in-impl-omitted-type.rs:11:20 + | +LL | type const NUM: = 84; + | ^ help: provide a type for the associated constant: `usize` + +error: use of trait associated const not defined as `type const` + --> $DIR/type_const-only-in-impl-omitted-type.rs:16:43 + | +LL | fn accept_bad_tr>(_x: &T) {} + | ^^^^^^^^^^^ + | + = note: the declaration in the trait must begin with `type const` not just `const` alone + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl.rs b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs index ae4a0004232b..e016908b3cc3 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl.rs @@ -1,5 +1,5 @@ #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait BadTr { const NUM: usize; @@ -8,12 +8,11 @@ trait BadTr { struct GoodS; impl BadTr for GoodS { - #[type_const] - const NUM: usize = 84; + type const NUM: usize = 84; } fn accept_bad_tr>(_x: &T) {} -//~^ ERROR use of trait associated const without `#[type_const]` +//~^ ERROR use of trait associated const not defined as `type const` fn main() { accept_bad_tr::<84, _>(&GoodS); diff --git a/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr b/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr index 44632e46fb07..55d5cca6ba69 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr +++ b/tests/ui/const-generics/mgca/type_const-only-in-impl.stderr @@ -1,10 +1,10 @@ -error: use of trait associated const without `#[type_const]` - --> $DIR/type_const-only-in-impl.rs:15:43 +error: use of trait associated const not defined as `type const` + --> $DIR/type_const-only-in-impl.rs:14:43 | LL | fn accept_bad_tr>(_x: &T) {} | ^^^^^^^^^^^ | - = note: the declaration in the trait must be marked with `#[type_const]` + = note: the declaration in the trait must begin with `type const` not just `const` alone error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/type_const-only-in-trait.rs b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs index 8c8ff6259cae..1def66a1ba68 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-trait.rs +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.rs @@ -1,16 +1,15 @@ #![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] +#![feature(min_generic_const_args)] trait GoodTr { - #[type_const] - const NUM: usize; + type const NUM: usize; } struct BadS; impl GoodTr for BadS { const NUM: usize = 42; - //~^ ERROR implementation of `#[type_const]` const must be marked with `#[type_const]` + //~^ ERROR implementation of a `type const` must also be marked as `type const` } fn accept_good_tr>(_x: &T) {} diff --git a/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr index 29f1b724960a..f98b4d9cbbfd 100644 --- a/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr +++ b/tests/ui/const-generics/mgca/type_const-only-in-trait.stderr @@ -1,16 +1,14 @@ -error: implementation of `#[type_const]` const must be marked with `#[type_const]` - --> $DIR/type_const-only-in-trait.rs:12:5 +error: implementation of a `type const` must also be marked as `type const` + --> $DIR/type_const-only-in-trait.rs:11:5 | LL | const NUM: usize = 42; | ^^^^^^^^^^^^^^^^ | -note: trait declaration of const is marked with `#[type_const]` +note: trait declaration of const is marked as `type const` --> $DIR/type_const-only-in-trait.rs:5:5 | -LL | #[type_const] - | ^^^^^^^^^^^^^ -LL | const NUM: usize; - | ^^^^^^^^^^^^^^^^ +LL | type const NUM: usize; + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/type_const-pub.rs b/tests/ui/const-generics/mgca/type_const-pub.rs new file mode 100644 index 000000000000..70fab75901b9 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-pub.rs @@ -0,0 +1,11 @@ +//@ check-pass +// This previously caused an ICE when checking reachability of a pub const item +// This is because reachability also tried to evaluate the #[type_const] which +// requires the item have a body. #[type_const] do not have bodies. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +pub type const TYPE_CONST : usize = 1; +fn main() { + print!("{}", TYPE_CONST) +} diff --git a/tests/ui/const-generics/mgca/type_const-recursive.rs b/tests/ui/const-generics/mgca/type_const-recursive.rs new file mode 100644 index 000000000000..ebaab51bbc3b --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-recursive.rs @@ -0,0 +1,8 @@ +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + + +type const A: u8 = A; +//~^ ERROR: overflow normalizing the unevaluated constant `A` [E0275] + +fn main() {} diff --git a/tests/ui/const-generics/mgca/type_const-recursive.stderr b/tests/ui/const-generics/mgca/type_const-recursive.stderr new file mode 100644 index 000000000000..d21ccb22bc90 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-recursive.stderr @@ -0,0 +1,11 @@ +error[E0275]: overflow normalizing the unevaluated constant `A` + --> $DIR/type_const-recursive.rs:5:1 + | +LL | type const A: u8 = A; + | ^^^^^^^^^^^^^^^^ + | + = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/const-generics/mgca/type_const-use.rs b/tests/ui/const-generics/mgca/type_const-use.rs new file mode 100644 index 000000000000..f295bf465e30 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-use.rs @@ -0,0 +1,12 @@ +//@ check-pass +// This test should compile without an ICE. +#![expect(incomplete_features)] +#![feature(min_generic_const_args)] + +type const CONST: usize = 1; + +fn uses_const() { + CONST; +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs new file mode 100644 index 000000000000..cf75b45b9ff0 --- /dev/null +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.rs @@ -0,0 +1,42 @@ +#![feature(adt_const_params)] + +#[derive(Eq, PartialEq, std::marker::ConstParamTy)] +struct Inner; + +struct Foo< + const PARAM_TY: Inner, + //~^ ERROR: unbraced const blocks as const args are experimental + const DEFAULT: usize = const { 1 }, + //~^ ERROR: unbraced const blocks as const args are experimental +>; + +type Array = [(); const { 1 }]; +type NormalTy = Inner; + //~^ ERROR: unbraced const blocks as const args are experimental + +fn repeat() { + [1_u8; const { 1 }]; +} + +fn body_ty() { + let _: Inner; + //~^ ERROR: unbraced const blocks as const args are experimental +} + +fn generic() { + if false { + generic::(); + //~^ ERROR: unbraced const blocks as const args are experimental + } +} + +const NON_TYPE_CONST: usize = const { 1 }; + + +type const TYPE_CONST: usize = const { 1 }; +//~^ ERROR: `type const` syntax is experimental [E0658] +//~| ERROR: top-level `type const` are unstable [E0658] + +static STATIC: usize = const { 1 }; + +fn main() {} diff --git a/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr new file mode 100644 index 000000000000..dbcb8c56ac5b --- /dev/null +++ b/tests/ui/const-generics/mgca/unbraced_const_block_const_arg_gated.stderr @@ -0,0 +1,73 @@ +error[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:7:27 + | +LL | const PARAM_TY: Inner, + | ^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:9:28 + | +LL | const DEFAULT: usize = const { 1 }, + | ^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:14:23 + | +LL | type NormalTy = Inner; + | ^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:22:18 + | +LL | let _: Inner; + | ^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: unbraced const blocks as const args are experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:28:19 + | +LL | generic::(); + | ^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: `type const` syntax is experimental + --> $DIR/unbraced_const_block_const_arg_gated.rs:36:1 + | +LL | type const TYPE_CONST: usize = const { 1 }; + | ^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0658]: top-level `type const` are unstable + --> $DIR/unbraced_const_block_const_arg_gated.rs:36:1 + | +LL | type const TYPE_CONST: usize = const { 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/mgca/unmarked-free-const.rs b/tests/ui/const-generics/mgca/unmarked-free-const.rs new file mode 100644 index 000000000000..d6d9b936d95b --- /dev/null +++ b/tests/ui/const-generics/mgca/unmarked-free-const.rs @@ -0,0 +1,11 @@ +// regression test, used to ICE + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +const N: usize = 4; + +fn main() { + let x = [(); N]; + //~^ ERROR use of `const` in the type system not defined as `type const` +} diff --git a/tests/ui/const-generics/mgca/unmarked-free-const.stderr b/tests/ui/const-generics/mgca/unmarked-free-const.stderr new file mode 100644 index 000000000000..76875d8db0ef --- /dev/null +++ b/tests/ui/const-generics/mgca/unmarked-free-const.stderr @@ -0,0 +1,11 @@ +error: use of `const` in the type system not defined as `type const` + --> $DIR/unmarked-free-const.rs:9:18 + | +LL | const N: usize = 4; + | - help: add `type` before `const` for `N`: `type` +... +LL | let x = [(); N]; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/unused_speculative_def_id.rs b/tests/ui/const-generics/mgca/unused_speculative_def_id.rs new file mode 100644 index 000000000000..e617daba24b6 --- /dev/null +++ b/tests/ui/const-generics/mgca/unused_speculative_def_id.rs @@ -0,0 +1,24 @@ +#![feature(min_generic_const_args, generic_const_exprs, generic_const_items)] +#![expect(incomplete_features)] + +// Previously we would create a `DefId` to represent the const argument to `A` +// except it would go unused as it's a MGCA path const arg. We would also make +// a `DefId` for the `const { 1 }` anon const arg to `ERR` which would wind up +// with a `DefId` parent of the speculatively created `DefId` for the argument to +// `A`. +// +// This then caused Problems:tm: in the rest of the compiler that did not expect +// to encounter such nonsensical `DefId`s. +// +// The `ERR` path must fail to resolve as if it can be resolved then broken GCE +// logic will attempt to evaluate the constant directly which is wrong for +// `type_const`s which do not have bodies. + +struct A; + +struct Foo { + field: A<{ ERR:: }>, + //~^ ERROR: cannot find value `ERR` in this scope +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr new file mode 100644 index 000000000000..e087e046ec35 --- /dev/null +++ b/tests/ui/const-generics/mgca/unused_speculative_def_id.stderr @@ -0,0 +1,18 @@ +error[E0425]: cannot find value `ERR` in this scope + --> $DIR/unused_speculative_def_id.rs:20:16 + | +LL | field: A<{ ERR:: }>, + | ^^^ + | + --> $SRC_DIR/core/src/result.rs:LL:COL + | + = note: similarly named tuple variant `Err` defined here +help: a tuple variant with a similar name exists + | +LL - field: A<{ ERR:: }>, +LL + field: A<{ Err:: }>, + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs deleted file mode 100644 index 554e078ccd49..000000000000 --- a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Regression test for #119783 - -#![expect(incomplete_features)] -#![feature(associated_const_equality, min_generic_const_args)] - -trait Trait { - #[type_const] - const F: fn(); - //~^ ERROR using function pointers as const generic parameters is forbidden -} - -fn take(_: impl Trait) {} - -fn main() {} diff --git a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr b/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr deleted file mode 100644 index 09d1063081fe..000000000000 --- a/tests/ui/const-generics/mgca/using-fnptr-as-type_const.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0741]: using function pointers as const generic parameters is forbidden - --> $DIR/using-fnptr-as-type_const.rs:8:14 - | -LL | const F: fn(); - | ^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0741`. diff --git a/tests/ui/const-generics/mgca/wrong_type_const_arr_diag.rs b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag.rs new file mode 100644 index 000000000000..8a2117096a4a --- /dev/null +++ b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag.rs @@ -0,0 +1,13 @@ +// This test causes ERROR: mismatched types [E0308] +// and makes rustc to print array from const arguments +#![feature(min_generic_const_args, adt_const_params)] +#![allow(incomplete_features)] + +struct TakesArr; + +fn foo() { + let _: TakesArr<{ [N] }> = TakesArr::<{ [1] }>; + //~^ ERROR: mismatched types [E0308] +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/wrong_type_const_arr_diag.stderr b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag.stderr new file mode 100644 index 000000000000..a2e212b28ec6 --- /dev/null +++ b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/wrong_type_const_arr_diag.rs:9:32 + | +LL | let _: TakesArr<{ [N] }> = TakesArr::<{ [1] }>; + | ----------------- ^^^^^^^^^^^^^^^^^^^ expected `[N]`, found `*b"\x01"` + | | + | expected due to this + | + = note: expected struct `TakesArr<[N]>` + found struct `TakesArr<*b"\x01">` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.rs b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.rs new file mode 100644 index 000000000000..909189ae4875 --- /dev/null +++ b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.rs @@ -0,0 +1,21 @@ +// This test causes ERROR: mismatched types [E0308] +// and makes rustc to print array from const arguments +#![feature(min_generic_const_args, adt_const_params, trivial_bounds)] +#![allow(incomplete_features)] + +trait Trait { + + type const ASSOC: u8; +} + +struct TakesArr; + +fn foo() +where + u8: Trait +{ + let _: TakesArr<{ [::ASSOC] }> = TakesArr::<{ [1] }>; + //~^ ERROR: mismatched types [E0308] +} + +fn main() {} diff --git a/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.stderr b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.stderr new file mode 100644 index 000000000000..66de4a4d6a86 --- /dev/null +++ b/tests/ui/const-generics/mgca/wrong_type_const_arr_diag_trait.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/wrong_type_const_arr_diag_trait.rs:17:51 + | +LL | let _: TakesArr<{ [::ASSOC] }> = TakesArr::<{ [1] }>; + | ------------------------------------ ^^^^^^^^^^^^^^^^^^^ expected `[::ASSOC]`, found `*b"\x01"` + | | + | expected due to this + | + = note: expected struct `TakesArr<[::ASSOC]>` + found struct `TakesArr<*b"\x01">` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs b/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs index e1cf7b579aa5..b8739b263aee 100644 --- a/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs +++ b/tests/ui/const-generics/min_const_generics/forbid-self-no-normalize.rs @@ -9,7 +9,7 @@ trait BindsParam { type ArrayTy; } impl BindsParam for ::Assoc { - type ArrayTy = [u8; Self::MAX]; //~ ERROR generic `Self` types + type ArrayTy = [u8; Self::MAX]; //~ ERROR generic `Self` } fn main() {} diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr index cc6a813b747d..df7c2a0a8629 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr @@ -1,3 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:40:32 | @@ -40,30 +64,6 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character ff __ __ __ │ .░░░ } -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:21 - | -LL | get_flag::(); - | ^^^^ expected `char`, found `u8` - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 - | -LL | get_flag::<7, 'c'>(); - | ^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35:14 - | -LL | get_flag::<42, 0x5ad>(); - | ^^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35:18 - | -LL | get_flag::<42, 0x5ad>(); - | ^^^^^ expected `char`, found `u8` - error: aborting due to 8 previous errors Some errors have detailed explanations: E0080, E0308. diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr index cc6a813b747d..df7c2a0a8629 100644 --- a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr +++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr @@ -1,3 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:31:21 + | +LL | get_flag::(); + | ^^^^ expected `char`, found `u8` + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:33:14 + | +LL | get_flag::<7, 'c'>(); + | ^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:14 + | +LL | get_flag::<42, 0x5ad>(); + | ^^ expected `bool`, found integer + +error[E0308]: mismatched types + --> $DIR/invalid-patterns.rs:35:18 + | +LL | get_flag::<42, 0x5ad>(); + | ^^^^^ expected `char`, found `u8` + error[E0080]: reading memory at ALLOC0[0x0..0x4], but memory is uninitialized at [0x1..0x4], and this operation requires initialized memory --> $DIR/invalid-patterns.rs:40:32 | @@ -40,30 +64,6 @@ LL | get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character ff __ __ __ │ .░░░ } -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:31:21 - | -LL | get_flag::(); - | ^^^^ expected `char`, found `u8` - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:33:14 - | -LL | get_flag::<7, 'c'>(); - | ^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35:14 - | -LL | get_flag::<42, 0x5ad>(); - | ^^ expected `bool`, found integer - -error[E0308]: mismatched types - --> $DIR/invalid-patterns.rs:35:18 - | -LL | get_flag::<42, 0x5ad>(); - | ^^^^^ expected `char`, found `u8` - error: aborting due to 8 previous errors Some errors have detailed explanations: E0080, E0308. diff --git a/tests/ui/const-generics/ogca/basic-fail.rs b/tests/ui/const-generics/ogca/basic-fail.rs new file mode 100644 index 000000000000..e3db3dea3735 --- /dev/null +++ b/tests/ui/const-generics/ogca/basic-fail.rs @@ -0,0 +1,18 @@ +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(opaque_generic_const_args)] +#![expect(incomplete_features)] + +type const ADD1: usize = const { N + 1 }; + +type const INC: usize = const { N + 1 }; + +type const ONE: usize = ADD1::<0>; + +type const OTHER_ONE: usize = INC::<0>; + +// Not definitionally equal. +const ARR: [(); ADD1::<0>] = [(); INC::<0>]; +//~^ ERROR mismatched types + +fn main() {} diff --git a/tests/ui/const-generics/ogca/basic-fail.stderr b/tests/ui/const-generics/ogca/basic-fail.stderr new file mode 100644 index 000000000000..ce4e8eb1471c --- /dev/null +++ b/tests/ui/const-generics/ogca/basic-fail.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/basic-fail.rs:15:30 + | +LL | const ARR: [(); ADD1::<0>] = [(); INC::<0>]; + | ^^^^^^^^^^^^^^ expected an array with a size of const { N + 1 }, found one with a size of const { N + 1 } + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/ogca/basic.rs b/tests/ui/const-generics/ogca/basic.rs new file mode 100644 index 000000000000..e736484b5c3c --- /dev/null +++ b/tests/ui/const-generics/ogca/basic.rs @@ -0,0 +1,18 @@ +//@ check-pass + +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(opaque_generic_const_args)] +#![expect(incomplete_features)] + +type const ADD1: usize = const { N + 1 }; + +type const INC: usize = ADD1::; + +type const ONE: usize = ADD1::<0>; + +type const OTHER_ONE: usize = INC::<0>; + +const ARR: [(); ADD1::<0>] = [(); INC::<0>]; + +fn main() {} diff --git a/tests/ui/const-generics/ogca/coherence-ambiguous.rs b/tests/ui/const-generics/ogca/coherence-ambiguous.rs new file mode 100644 index 000000000000..21efe4cfe981 --- /dev/null +++ b/tests/ui/const-generics/ogca/coherence-ambiguous.rs @@ -0,0 +1,19 @@ +// FIXME(ogca): this should ERROR not pass!! +//@ check-pass + +#![feature(generic_const_items, min_generic_const_args, opaque_generic_const_args)] +#![expect(incomplete_features)] + +type const FOO: usize = const { N + 1 }; + +type const BAR: usize = const { N + 1 }; + +trait Trait {} + +impl Trait for [(); FOO::<1>] {} +impl Trait for [(); BAR::<1>] {} +// FIXME(ogca): this should ERROR! +impl Trait for [(); BAR::<2>] {} +// FIXME(ogca): this should ERROR! + +fn main() {} diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.rs b/tests/ui/const-generics/ogca/rhs-but-not-root.rs new file mode 100644 index 000000000000..2897b16d493f --- /dev/null +++ b/tests/ui/const-generics/ogca/rhs-but-not-root.rs @@ -0,0 +1,12 @@ +#![feature(generic_const_items)] +#![feature(min_generic_const_args)] +#![feature(opaque_generic_const_args)] +#![expect(incomplete_features)] + +// Anon consts must be the root of the RHS to be OGCA. +type const FOO: usize = ID::; +//~^ ERROR generic parameters may not be used in const operations + +type const ID: usize = N; + +fn main() {} diff --git a/tests/ui/const-generics/ogca/rhs-but-not-root.stderr b/tests/ui/const-generics/ogca/rhs-but-not-root.stderr new file mode 100644 index 000000000000..c720b58b9bde --- /dev/null +++ b/tests/ui/const-generics/ogca/rhs-but-not-root.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/rhs-but-not-root.rs:7:54 + | +LL | type const FOO: usize = ID::; + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr b/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr index 00eeecb9595f..9452e747a755 100644 --- a/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr +++ b/tests/ui/const-generics/parent_generics_of_nested_in_default.stderr @@ -8,9 +8,15 @@ error[E0425]: cannot find value `B` in this scope --> $DIR/parent_generics_of_nested_in_default.rs:1:30 | LL | impl Tr {} - | - ^ help: a const parameter with a similar name exists: `A` + | - ^ | | | similarly named const parameter `A` defined here + | +help: a const parameter with a similar name exists + | +LL - impl Tr {} +LL + impl Tr {} + | error: defaults for generic parameters are not allowed here --> $DIR/parent_generics_of_nested_in_default.rs:1:6 diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr index d435af07db2a..9c956d79a7bb 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -4,8 +4,8 @@ error[E0658]: associated const equality is incomplete LL | impl Foo for Bar { | ^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0229]: associated item constraints are not allowed here diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr index f852c14b1784..4a4ff098dc4b 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -16,8 +16,8 @@ error[E0658]: associated const equality is incomplete LL | impl Foo for Bar { | ^^^^^^^^^^^ | - = note: see issue #92827 for more information - = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable + = note: see issue #132980 for more information + = help: add `#![feature(min_generic_const_args)]` 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[E0229]: associated item constraints are not allowed here diff --git a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs index 49c88856bc96..808d960da68b 100644 --- a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.rs @@ -4,8 +4,6 @@ use std::convert::TryFrom; pub fn test_usage(p: ()) { SmallCString::try_from(p).map(|cstr| cstr); //~^ ERROR: type annotations needed - //~| ERROR: type annotations needed - //~| ERROR: type annotations needed } pub struct SmallCString {} diff --git a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr index 1557b83b00ec..c80efd6df8a8 100644 --- a/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr +++ b/tests/ui/const-generics/try-from-with-const-genericsrs-98299.stderr @@ -7,7 +7,7 @@ LL | SmallCString::try_from(p).map(|cstr| cstr); | type must be known at this point | note: required by a const generic parameter in `SmallCString` - --> $DIR/try-from-with-const-genericsrs-98299.rs:11:25 + --> $DIR/try-from-with-const-genericsrs-98299.rs:9:25 | LL | pub struct SmallCString {} | ^^^^^^^^^^^^^^ required by this const generic parameter in `SmallCString` @@ -16,46 +16,6 @@ help: consider giving this closure parameter an explicit type, where the value o LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); | +++++++++++++++++ -error[E0284]: type annotations needed for `SmallCString<_>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 - | -LL | SmallCString::try_from(p).map(|cstr| cstr); - | ------------ ^^^^ - | | - | type must be known at this point - | -note: required for `SmallCString<_>` to implement `TryFrom<()>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 - | -LL | impl TryFrom<()> for SmallCString { - | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ - | | - | unsatisfied trait bound introduced here -help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified - | -LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); - | +++++++++++++++++ - -error[E0284]: type annotations needed for `SmallCString<_>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:5:36 - | -LL | SmallCString::try_from(p).map(|cstr| cstr); - | ------------------------- ^^^^ - | | - | type must be known at this point - | -note: required for `SmallCString<_>` to implement `TryFrom<()>` - --> $DIR/try-from-with-const-genericsrs-98299.rs:13:22 - | -LL | impl TryFrom<()> for SmallCString { - | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ - | | - | unsatisfied trait bound introduced here -help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified - | -LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); - | +++++++++++++++++ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr index 95d20de1b432..9de140dab9eb 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.full.stderr @@ -1,3 +1,15 @@ +error: the constant `1` is not of type `u8` + --> $DIR/type-mismatch.rs:8:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +note: required by a const generic parameter in `R::method` + --> $DIR/type-mismatch.rs:5:15 + | +LL | fn method(&self) -> u8 { N } + | ^^^^^^^^^^^ required by this const generic parameter in `R::method` + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -10,6 +22,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr index 95d20de1b432..9de140dab9eb 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr +++ b/tests/ui/const-generics/type-dependent/type-mismatch.min.stderr @@ -1,3 +1,15 @@ +error: the constant `1` is not of type `u8` + --> $DIR/type-mismatch.rs:8:27 + | +LL | assert_eq!(R.method::<1u16>(), 1); + | ^^^^ expected `u8`, found `u16` + | +note: required by a const generic parameter in `R::method` + --> $DIR/type-mismatch.rs:5:15 + | +LL | fn method(&self) -> u8 { N } + | ^^^^^^^^^^^ required by this const generic parameter in `R::method` + error[E0308]: mismatched types --> $DIR/type-mismatch.rs:8:27 | @@ -10,6 +22,6 @@ LL - assert_eq!(R.method::<1u16>(), 1); LL + assert_eq!(R.method::<1u8>(), 1); | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/type-dependent/type-mismatch.rs b/tests/ui/const-generics/type-dependent/type-mismatch.rs index 6ed5fdca30ae..fc7ae994184b 100644 --- a/tests/ui/const-generics/type-dependent/type-mismatch.rs +++ b/tests/ui/const-generics/type-dependent/type-mismatch.rs @@ -6,5 +6,6 @@ impl R { } fn main() { assert_eq!(R.method::<1u16>(), 1); - //~^ ERROR mismatched types + //~^ ERROR the constant `1` is not of type `u8` + //~| ERROR mismatched types } diff --git a/tests/ui/const-generics/type-relative-path-144547.min.stderr b/tests/ui/const-generics/type-relative-path-144547.min.stderr new file mode 100644 index 000000000000..1192a7434ec8 --- /dev/null +++ b/tests/ui/const-generics/type-relative-path-144547.min.stderr @@ -0,0 +1,8 @@ +error: generic parameters may not be used in const operations + --> $DIR/type-relative-path-144547.rs:39:35 + | +LL | type SupportedArray = [T; ::SUPPORTED_SLOTS]; + | ^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/type-relative-path-144547.rs b/tests/ui/const-generics/type-relative-path-144547.rs new file mode 100644 index 000000000000..e3532fe635c2 --- /dev/null +++ b/tests/ui/const-generics/type-relative-path-144547.rs @@ -0,0 +1,43 @@ +// Regression test for #144547. + +//@ revisions: min mgca +//@[mgca] check-pass +#![allow(incomplete_features)] +#![feature(mgca_type_const_syntax)] +#![cfg_attr(mgca, feature(min_generic_const_args))] +// FIXME(mgca) syntax is it's own feature flag before +// expansion and is also an incomplete feature. +//#![cfg_attr(mgca, expect(incomplete_features))] + +trait UnderlyingImpl { + type InfoType: LevelInfo; + type SupportedArray; +} + +trait LevelInfo { + #[cfg(mgca)] + type const SUPPORTED_SLOTS: usize; + + #[cfg(not(mgca))] + const SUPPORTED_SLOTS: usize; +} + +struct Info; + +impl LevelInfo for Info { + #[cfg(mgca)] + type const SUPPORTED_SLOTS: usize = 1; + + #[cfg(not(mgca))] + const SUPPORTED_SLOTS: usize = 1; +} + +struct SomeImpl; + +impl UnderlyingImpl for SomeImpl { + type InfoType = Info; + type SupportedArray = [T; ::SUPPORTED_SLOTS]; + //[min]~^ ERROR generic parameters +} + +fn main() {} diff --git a/tests/ui/const-generics/vec-macro-in-static-array.stderr b/tests/ui/const-generics/vec-macro-in-static-array.stderr index de21f2274f3a..63d7b0c89fa1 100644 --- a/tests/ui/const-generics/vec-macro-in-static-array.stderr +++ b/tests/ui/const-generics/vec-macro-in-static-array.stderr @@ -6,7 +6,6 @@ LL | static VEC: [u32; 256] = vec![]; | = note: expected array `[u32; 256]` found struct `Vec<_>` - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-block-item.stderr b/tests/ui/consts/const-block-item.stderr deleted file mode 100644 index b325976a60b6..000000000000 --- a/tests/ui/consts/const-block-item.stderr +++ /dev/null @@ -1,10 +0,0 @@ -warning: trait `Value` is never used - --> $DIR/const-block-item.rs:5:15 - | -LL | pub trait Value { - | ^^^^^ - | - = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default - -warning: 1 warning emitted - diff --git a/tests/ui/consts/const-block-items/assert-fail.rs b/tests/ui/consts/const-block-items/assert-fail.rs new file mode 100644 index 000000000000..a7e3478666ef --- /dev/null +++ b/tests/ui/consts/const-block-items/assert-fail.rs @@ -0,0 +1,10 @@ +//@ check-fail + +#![feature(const_block_items)] + +const { assert!(false) } +//~^ ERROR: evaluation panicked: assertion failed: false [E0080] +const { assert!(2 + 2 == 5) } +//~^ ERROR: evaluation panicked: assertion failed: 2 + 2 == 5 [E0080] + +fn main() {} diff --git a/tests/ui/consts/const-block-items/assert-fail.stderr b/tests/ui/consts/const-block-items/assert-fail.stderr new file mode 100644 index 000000000000..b1444dc5e0d0 --- /dev/null +++ b/tests/ui/consts/const-block-items/assert-fail.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation panicked: assertion failed: false + --> $DIR/assert-fail.rs:5:9 + | +LL | const { assert!(false) } + | ^^^^^^^^^^^^^^ evaluation of `_` failed here + +error[E0080]: evaluation panicked: assertion failed: 2 + 2 == 5 + --> $DIR/assert-fail.rs:7:9 + | +LL | const { assert!(2 + 2 == 5) } + | ^^^^^^^^^^^^^^^^^^^ evaluation of `_` failed here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-block-items/assert-pass.rs b/tests/ui/consts/const-block-items/assert-pass.rs new file mode 100644 index 000000000000..c409cc5b91f7 --- /dev/null +++ b/tests/ui/consts/const-block-items/assert-pass.rs @@ -0,0 +1,7 @@ +//@ check-pass +#![feature(const_block_items)] + +const { assert!(true) } +const { assert!(2 + 2 == 4) } + +fn main() {} diff --git a/tests/ui/consts/const-block-items/hir.rs b/tests/ui/consts/const-block-items/hir.rs new file mode 100644 index 000000000000..1d9c5e91b57e --- /dev/null +++ b/tests/ui/consts/const-block-items/hir.rs @@ -0,0 +1,10 @@ +//@ build-pass +//@ compile-flags: -Zunpretty=hir + +#![feature(const_block_items)] + +const { + // foo +} + +fn main() { } diff --git a/tests/ui/consts/const-block-items/hir.stdout b/tests/ui/consts/const-block-items/hir.stdout new file mode 100644 index 000000000000..2b7f0818556f --- /dev/null +++ b/tests/ui/consts/const-block-items/hir.stdout @@ -0,0 +1,14 @@ +//@ build-pass +//@ compile-flags: -Zunpretty=hir + +#![feature(const_block_items)] +extern crate std; +#[attr = PreludeImport] +use ::std::prelude::rust_2015::*; + +const _: () = + { + // foo + }; + +fn main() { } diff --git a/tests/ui/consts/const-block-items/typecheck.rs b/tests/ui/consts/const-block-items/typecheck.rs new file mode 100644 index 000000000000..2e521cbfda05 --- /dev/null +++ b/tests/ui/consts/const-block-items/typecheck.rs @@ -0,0 +1,20 @@ +//@ check-fail + +#![feature(const_block_items)] + +const { + assert!(true); + 2 + 2 //~ ERROR: mismatched types [E0308] +} + + +const fn id(t: T) -> T { + t +} + +const { id(2) } +//~^ ERROR: mismatched types [E0308] +const { id(()) } + + +fn main() {} diff --git a/tests/ui/consts/const-block-items/typecheck.stderr b/tests/ui/consts/const-block-items/typecheck.stderr new file mode 100644 index 000000000000..93d1eb1bc9e4 --- /dev/null +++ b/tests/ui/consts/const-block-items/typecheck.stderr @@ -0,0 +1,30 @@ +error[E0308]: mismatched types + --> $DIR/typecheck.rs:7:5 + | +LL | 2 + 2 + | ^^^^^ expected `()`, found integer + +error[E0308]: mismatched types + --> $DIR/typecheck.rs:15:12 + | +LL | const { id(2) } + | -- ^ expected `()`, found integer + | | + | arguments to this function are incorrect + | +help: the return type of this call is `{integer}` due to the type of the argument passed + --> $DIR/typecheck.rs:15:9 + | +LL | const { id(2) } + | ^^^-^ + | | + | this argument influences the return type of `id` +note: function defined here + --> $DIR/typecheck.rs:11:10 + | +LL | const fn id(t: T) -> T { + | ^^ ---- + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-blocks/trait-error.stderr b/tests/ui/consts/const-blocks/trait-error.stderr index 601d067e3d84..308d71f0f4bd 100644 --- a/tests/ui/consts/const-blocks/trait-error.stderr +++ b/tests/ui/consts/const-blocks/trait-error.stderr @@ -5,10 +5,12 @@ LL | [Foo(String::new()); 4]; | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` | note: required for `Foo` to implement `Copy` - --> $DIR/trait-error.rs:1:10 + --> $DIR/trait-error.rs:2:8 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ---- in this derive macro expansion +LL | struct Foo(T); + | ^^^ - type parameter would need to implement `Copy` = note: the `Copy` trait is required because this value will be copied for each element of the array help: create an inline `const` block | diff --git a/tests/ui/consts/const-closure-fn-trait-object.rs b/tests/ui/consts/const-closure-fn-trait-object.rs new file mode 100644 index 000000000000..e47a118dd3f4 --- /dev/null +++ b/tests/ui/consts/const-closure-fn-trait-object.rs @@ -0,0 +1,5 @@ +//! regression test for +//@ run-pass +fn main() { + const _C: &'static dyn Fn() = &|| {}; +} diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.rs b/tests/ui/consts/const-eval/array-len-mismatch-type.rs new file mode 100644 index 000000000000..463572c13e10 --- /dev/null +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.rs @@ -0,0 +1,8 @@ +//! Regression test for +pub struct Data([[&'static str]; 5_i32]); +//~^ ERROR the constant `5` is not of type `usize` +//~| ERROR the size for values of type `[&'static str]` cannot be known at compilation time +//~| ERROR mismatched types +const _: &'static Data = unsafe { &*(&[] as *const Data) }; +//~^ ERROR the type `[[&str]; 5]` has an unknown layout +fn main() {} diff --git a/tests/ui/consts/const-eval/array-len-mismatch-type.stderr b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr new file mode 100644 index 000000000000..0f03006f0032 --- /dev/null +++ b/tests/ui/consts/const-eval/array-len-mismatch-type.stderr @@ -0,0 +1,39 @@ +error: the constant `5` is not of type `usize` + --> $DIR/array-len-mismatch-type.rs:2:17 + | +LL | pub struct Data([[&'static str]; 5_i32]); + | ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `i32` + | + = note: the length of array `[[&'static str]; 5]` must be type `usize` + +error[E0277]: the size for values of type `[&'static str]` cannot be known at compilation time + --> $DIR/array-len-mismatch-type.rs:2:17 + | +LL | pub struct Data([[&'static str]; 5_i32]); + | ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[&'static str]` + = note: slice and array elements must have `Sized` type + +error[E0080]: the type `[[&str]; 5]` has an unknown layout + --> $DIR/array-len-mismatch-type.rs:6:39 + | +LL | const _: &'static Data = unsafe { &*(&[] as *const Data) }; + | ^^ evaluation of `_` failed here + +error[E0308]: mismatched types + --> $DIR/array-len-mismatch-type.rs:2:34 + | +LL | pub struct Data([[&'static str]; 5_i32]); + | ^^^^^ expected `usize`, found `i32` + | +help: change the type of the numeric literal from `i32` to `usize` + | +LL - pub struct Data([[&'static str]; 5_i32]); +LL + pub struct Data([[&'static str]; 5_usize]); + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0080, E0277, E0308. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/c-variadic-fail.rs b/tests/ui/consts/const-eval/c-variadic-fail.rs new file mode 100644 index 000000000000..b5a400a8bf25 --- /dev/null +++ b/tests/ui/consts/const-eval/c-variadic-fail.rs @@ -0,0 +1,147 @@ +//@ build-fail + +#![feature(c_variadic)] +#![feature(const_c_variadic)] +#![feature(const_trait_impl)] +#![feature(const_destruct)] +#![feature(const_clone)] + +use std::ffi::VaList; +use std::mem::MaybeUninit; + +const unsafe extern "C" fn read_n(mut ap: ...) { + let mut i = N; + while i > 0 { + i -= 1; + let _ = ap.arg::(); + } +} + +unsafe fn read_too_many() { + // None passed, none read. + const { read_n::<0>() } + + // One passed, none read. Ignoring arguments is fine. + const { read_n::<0>(1) } + + // None passed, one read. + const { read_n::<1>() } + //~^ ERROR more C-variadic arguments read than were passed + + // One passed, two read. + const { read_n::<2>(1) } + //~^ ERROR more C-variadic arguments read than were passed +} + +const unsafe extern "C" fn read_as(mut ap: ...) -> T { + ap.arg::() +} + +unsafe fn read_cast() { + const { read_as::(1i32) }; + const { read_as::(1u32) }; + + const { read_as::(1i32, 2u64, 3.0f64) }; + const { read_as::(1u32, 2u64, 3.0f64) }; + + const { read_as::(1i64) }; + const { read_as::(1u64) }; + + const { read_as::(1i32) }; + //~^ ERROR va_arg type mismatch: requested `u32`, but next argument is `i32` + + const { read_as::(1u32) }; + //~^ ERROR va_arg type mismatch: requested `i32`, but next argument is `u32` + + const { read_as::(1u64) }; + //~^ ERROR va_arg type mismatch: requested `i32`, but next argument is `u64` + + const { read_as::(1i32) }; + //~^ ERROR va_arg type mismatch: requested `f64`, but next argument is `i32` + + const { read_as::<*const u8>(1i32) }; + //~^ ERROR va_arg type mismatch: requested `*const u8`, but next argument is `i32` +} + +fn use_after_free() { + const unsafe extern "C" fn helper(ap: ...) -> [u8; size_of::()] { + unsafe { std::mem::transmute(ap) } + } + + const { + unsafe { + let ap = helper(1, 2, 3); + let mut ap = std::mem::transmute::<_, VaList>(ap); + ap.arg::(); + //~^ ERROR memory access failed: ALLOC0 has been freed, so this pointer is dangling [E0080] + } + }; +} + +fn manual_copy_drop() { + const unsafe extern "C" fn helper(ap: ...) { + // A copy created using Clone is valid, and can be used to read arguments. + let mut copy = ap.clone(); + assert!(copy.arg::() == 1i32); + + let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; + + // Using the copy is actually fine. + let _ = copy.arg::(); + drop(copy); + + // But then using the original is UB. + drop(ap); + } + + const { unsafe { helper(1, 2, 3) } }; + //~^ ERROR using ALLOC0 as variable argument list pointer but it does not point to a variable argument list [E0080] +} + +fn manual_copy_forget() { + const unsafe extern "C" fn helper(ap: ...) { + let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; + + // Using the copy is actually fine. + let _ = copy.arg::(); + std::mem::forget(copy); + + // The read (via `copy`) deallocated the original allocation. + drop(ap); + } + + const { unsafe { helper(1, 2, 3) } }; + //~^ ERROR using ALLOC0 as variable argument list pointer but it does not point to a variable argument list [E0080] +} + +fn manual_copy_read() { + const unsafe extern "C" fn helper(mut ap: ...) { + let mut copy: VaList = unsafe { std::mem::transmute_copy(&ap) }; + + // Reading from `ap` after reading from `copy` is UB. + let _ = copy.arg::(); + let _ = ap.arg::(); + } + + const { unsafe { helper(1, 2, 3) } }; + //~^ ERROR using ALLOC0 as variable argument list pointer but it does not point to a variable argument list [E0080] +} + +fn drop_of_invalid() { + const { + let mut invalid: MaybeUninit = MaybeUninit::zeroed(); + let ap = unsafe { invalid.assume_init() }; + } + //~^ ERROR pointer not dereferenceable: pointer must point to some allocation, but got null pointer [E0080] +} + +fn main() { + unsafe { + read_too_many(); + read_cast(); + manual_copy_read(); + manual_copy_drop(); + manual_copy_forget(); + drop_of_invalid(); + } +} diff --git a/tests/ui/consts/const-eval/c-variadic-fail.stderr b/tests/ui/consts/const-eval/c-variadic-fail.stderr new file mode 100644 index 000000000000..14da5500cb1b --- /dev/null +++ b/tests/ui/consts/const-eval/c-variadic-fail.stderr @@ -0,0 +1,355 @@ +error[E0080]: more C-variadic arguments read than were passed + --> $DIR/c-variadic-fail.rs:28:13 + | +LL | const { read_n::<1>() } + | ^^^^^^^^^^^^^ evaluation of `read_too_many::{constant#2}` failed inside this call + | +note: inside `read_n::<1>` + --> $DIR/c-variadic-fail.rs:16:17 + | +LL | let _ = ap.arg::(); + | ^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:28:5 + | +LL | const { read_n::<1>() } + | ^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:28:5 + | +LL | const { read_n::<1>() } + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: more C-variadic arguments read than were passed + --> $DIR/c-variadic-fail.rs:32:13 + | +LL | const { read_n::<2>(1) } + | ^^^^^^^^^^^^^^ evaluation of `read_too_many::{constant#3}` failed inside this call + | +note: inside `read_n::<2>` + --> $DIR/c-variadic-fail.rs:16:17 + | +LL | let _ = ap.arg::(); + | ^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:32:5 + | +LL | const { read_n::<2>(1) } + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:32:5 + | +LL | const { read_n::<2>(1) } + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: va_arg type mismatch: requested `u32`, but next argument is `i32` + --> $DIR/c-variadic-fail.rs:50:13 + | +LL | const { read_as::(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast::{constant#6}` failed inside this call + | +note: inside `read_as::` + --> $DIR/c-variadic-fail.rs:37:5 + | +LL | ap.arg::() + | ^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:50:5 + | +LL | const { read_as::(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:50:5 + | +LL | const { read_as::(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: va_arg type mismatch: requested `i32`, but next argument is `u32` + --> $DIR/c-variadic-fail.rs:53:13 + | +LL | const { read_as::(1u32) }; + | ^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast::{constant#7}` failed inside this call + | +note: inside `read_as::` + --> $DIR/c-variadic-fail.rs:37:5 + | +LL | ap.arg::() + | ^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:53:5 + | +LL | const { read_as::(1u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:53:5 + | +LL | const { read_as::(1u32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: va_arg type mismatch: requested `i32`, but next argument is `u64` + --> $DIR/c-variadic-fail.rs:56:13 + | +LL | const { read_as::(1u64) }; + | ^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast::{constant#8}` failed inside this call + | +note: inside `read_as::` + --> $DIR/c-variadic-fail.rs:37:5 + | +LL | ap.arg::() + | ^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:56:5 + | +LL | const { read_as::(1u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:56:5 + | +LL | const { read_as::(1u64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: va_arg type mismatch: requested `f64`, but next argument is `i32` + --> $DIR/c-variadic-fail.rs:59:13 + | +LL | const { read_as::(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast::{constant#9}` failed inside this call + | +note: inside `read_as::` + --> $DIR/c-variadic-fail.rs:37:5 + | +LL | ap.arg::() + | ^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:59:5 + | +LL | const { read_as::(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:59:5 + | +LL | const { read_as::(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: va_arg type mismatch: requested `*const u8`, but next argument is `i32` + --> $DIR/c-variadic-fail.rs:62:13 + | +LL | const { read_as::<*const u8>(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `read_cast::{constant#10}` failed inside this call + | +note: inside `read_as::<*const u8>` + --> $DIR/c-variadic-fail.rs:37:5 + | +LL | ap.arg::() + | ^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::<*const u8>` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:62:5 + | +LL | const { read_as::<*const u8>(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:62:5 + | +LL | const { read_as::<*const u8>(1i32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: memory access failed: ALLOC0 has been freed, so this pointer is dangling + --> $DIR/c-variadic-fail.rs:75:13 + | +LL | ap.arg::(); + | ^^^^^^^^^^^^^^^ evaluation of `use_after_free::{constant#0}` failed inside this call + | +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:71:5 + | +LL | / const { +LL | | unsafe { +LL | | let ap = helper(1, 2, 3); +LL | | let mut ap = std::mem::transmute::<_, VaList>(ap); +... | +LL | | }; + | |_____^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:71:5 + | +LL | / const { +LL | | unsafe { +LL | | let ap = helper(1, 2, 3); +LL | | let mut ap = std::mem::transmute::<_, VaList>(ap); +... | +LL | | }; + | |_____^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: using ALLOC1 as variable argument list pointer but it does not point to a variable argument list + --> $DIR/c-variadic-fail.rs:97:22 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_drop::{constant#0}` failed inside this call + | +note: inside `manual_copy_drop::helper` + --> $DIR/c-variadic-fail.rs:94:9 + | +LL | drop(ap); + | ^^^^^^^^ +note: inside `std::mem::drop::>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +note: inside `drop_in_place::> - shim(Some(VaList<'_>))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Drop>::drop` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:97:5 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:97:5 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: using ALLOC2 as variable argument list pointer but it does not point to a variable argument list + --> $DIR/c-variadic-fail.rs:113:22 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_forget::{constant#0}` failed inside this call + | +note: inside `manual_copy_forget::helper` + --> $DIR/c-variadic-fail.rs:110:9 + | +LL | drop(ap); + | ^^^^^^^^ +note: inside `std::mem::drop::>` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL +note: inside `drop_in_place::> - shim(Some(VaList<'_>))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Drop>::drop` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:113:5 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:113:5 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: using ALLOC3 as variable argument list pointer but it does not point to a variable argument list + --> $DIR/c-variadic-fail.rs:126:22 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^ evaluation of `manual_copy_read::{constant#0}` failed inside this call + | +note: inside `manual_copy_read::helper` + --> $DIR/c-variadic-fail.rs:123:17 + | +LL | let _ = ap.arg::(); + | ^^^^^^^^^^^^^^^ +note: inside `VaList::<'_>::arg::` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:126:5 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:126:5 + | +LL | const { unsafe { helper(1, 2, 3) } }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0080]: pointer not dereferenceable: pointer must point to some allocation, but got null pointer + --> $DIR/c-variadic-fail.rs:134:5 + | +LL | } + | ^ evaluation of `drop_of_invalid::{constant#0}` failed inside this call + | +note: inside `drop_in_place::> - shim(Some(VaList<'_>))` + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL +note: inside ` as Drop>::drop` + --> $SRC_DIR/core/src/ffi/va_list.rs:LL:COL + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:131:5 + | +LL | / const { +LL | | let mut invalid: MaybeUninit = MaybeUninit::zeroed(); +LL | | let ap = unsafe { invalid.assume_init() }; +LL | | } + | |_____^ + +note: erroneous constant encountered + --> $DIR/c-variadic-fail.rs:131:5 + | +LL | / const { +LL | | let mut invalid: MaybeUninit = MaybeUninit::zeroed(); +LL | | let ap = unsafe { invalid.assume_init() }; +LL | | } + | |_____^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/c-variadic.rs b/tests/ui/consts/const-eval/c-variadic.rs new file mode 100644 index 000000000000..2f8d043fb5db --- /dev/null +++ b/tests/ui/consts/const-eval/c-variadic.rs @@ -0,0 +1,155 @@ +//@ edition: 2021 +//@ run-pass +//@ ignore-backends: gcc + +#![feature(c_variadic)] +#![feature(const_c_variadic)] +#![feature(const_destruct)] +#![feature(const_cmp)] +#![feature(const_trait_impl)] + +use std::ffi::*; + +fn ignores_arguments() { + const unsafe extern "C" fn variadic(_: ...) {} + + const { + unsafe { variadic() }; + unsafe { variadic(1, 2, 3) }; + } +} + +fn echo() { + const unsafe extern "C" fn variadic(mut ap: ...) -> i32 { + ap.arg() + } + + assert_eq!(unsafe { variadic(1) }, 1); + assert_eq!(unsafe { variadic(3, 2, 1) }, 3); + + const { + assert!(unsafe { variadic(1) } == 1); + assert!(unsafe { variadic(3, 2, 1) } == 3); + } +} + +fn forward_by_val() { + const unsafe fn helper(mut ap: VaList) -> i32 { + ap.arg() + } + + const unsafe extern "C" fn variadic(ap: ...) -> i32 { + helper(ap) + } + + assert_eq!(unsafe { variadic(1) }, 1); + assert_eq!(unsafe { variadic(3, 2, 1) }, 3); + + const { + assert!(unsafe { variadic(1) } == 1); + assert!(unsafe { variadic(3, 2, 1) } == 3); + } +} + +fn forward_by_ref() { + const unsafe fn helper(ap: &mut VaList) -> i32 { + ap.arg() + } + + const unsafe extern "C" fn variadic(mut ap: ...) -> i32 { + helper(&mut ap) + } + + assert_eq!(unsafe { variadic(1) }, 1); + assert_eq!(unsafe { variadic(3, 2, 1) }, 3); + + const { + assert!(unsafe { variadic(1) } == 1); + assert!(unsafe { variadic(3, 2, 1) } == 3); + } +} + +#[allow(improper_ctypes_definitions)] +fn nested() { + const unsafe fn helper(mut ap1: VaList, mut ap2: VaList) -> (i32, i32) { + (ap1.arg(), ap2.arg()) + } + + const unsafe extern "C" fn variadic2(ap1: VaList, ap2: ...) -> (i32, i32) { + helper(ap1, ap2) + } + + const unsafe extern "C" fn variadic1(ap1: ...) -> (i32, i32) { + variadic2(ap1, 2, 2) + } + + assert_eq!(unsafe { variadic1(1) }, (1, 2)); + + const { + let (a, b) = unsafe { variadic1(1, 1) }; + + assert!(a != 2); + assert!(a == 1); + assert!(b != 1); + assert!(b == 2); + } +} + +fn various_types() { + const unsafe extern "C" fn check_list_2(mut ap: ...) { + macro_rules! continue_if { + ($cond:expr) => { + if !($cond) { + panic!(); + } + }; + } + + const unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool { + match CStr::from_ptr(ptr).to_str() { + Ok(cstr) => cstr == val, + Err(_) => panic!(), + } + } + + continue_if!(ap.arg::().floor() == 3.14f64.floor()); + continue_if!(ap.arg::() == 12); + continue_if!(ap.arg::() == 'a' as c_int); + continue_if!(ap.arg::().floor() == 6.18f64.floor()); + continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello")); + continue_if!(ap.arg::() == 42); + continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World")); + } + + unsafe { + check_list_2( + 3.14 as c_double, + 12 as c_long, + b'a' as c_int, + 6.28 as c_double, + c"Hello".as_ptr(), + 42 as c_int, + c"World".as_ptr(), + ); + const { + check_list_2( + 3.14 as c_double, + 12 as c_long, + b'a' as c_int, + 6.28 as c_double, + c"Hello".as_ptr(), + 42 as c_int, + c"World".as_ptr(), + ) + }; + } +} + +fn main() { + ignores_arguments(); + echo(); + forward_by_val(); + forward_by_ref(); + nested(); + various_types(); +} diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr index 4209e4bcee52..54d77b1bf3e9 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -14,13 +14,19 @@ LL | = [0; (i8::MAX + 1u8) as usize]; help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: `i8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i8` implements `Add<&i8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i8` implements `Add` + = note: `&i8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr index 2677d7956cc9..6c6472610b72 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -14,13 +14,19 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize] help: the following other types implement trait `Add` --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: `i8` implements `Add` + ::: $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: `&i8` implements `Add` + = note: in this macro invocation + --> $SRC_DIR/core/src/internal_macros.rs:LL:COL + | + = note: `&i8` implements `Add` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | = note: `i8` implements `Add<&i8>` + ::: $SRC_DIR/core/src/internal_macros.rs:LL:COL | - = note: `i8` implements `Add` + = note: `&i8` implements `Add` = note: this error originates in the macro `add_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0604]: only `u8` can be cast as `char`, not `i8` diff --git a/tests/ui/consts/const-eval/const_panic.stderr b/tests/ui/consts/const-eval/const_panic.stderr index a2036e834b0b..8e0384b2f2af 100644 --- a/tests/ui/consts/const-eval/const_panic.stderr +++ b/tests/ui/consts/const-eval/const_panic.stderr @@ -21,8 +21,6 @@ error[E0080]: evaluation panicked: not implemented | LL | const X: () = std::unimplemented!(); | ^^^^^^^^^^^^^^^^^^^^^ evaluation of `X` failed here - | - = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: hello --> $DIR/const_panic.rs:19:15 @@ -59,8 +57,6 @@ error[E0080]: evaluation panicked: not implemented | LL | const X_CORE: () = core::unimplemented!(); | ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `X_CORE` failed here - | - = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: hello --> $DIR/const_panic.rs:37:20 diff --git a/tests/ui/consts/const-eval/const_panic_2021.stderr b/tests/ui/consts/const-eval/const_panic_2021.stderr index ba771a35d036..a0181ccca391 100644 --- a/tests/ui/consts/const-eval/const_panic_2021.stderr +++ b/tests/ui/consts/const-eval/const_panic_2021.stderr @@ -21,8 +21,6 @@ error[E0080]: evaluation panicked: not implemented | LL | const D: () = std::unimplemented!(); | ^^^^^^^^^^^^^^^^^^^^^ evaluation of `D` failed here - | - = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: hello --> $DIR/const_panic_2021.rs:18:15 @@ -53,8 +51,6 @@ error[E0080]: evaluation panicked: not implemented | LL | const D_CORE: () = core::unimplemented!(); | ^^^^^^^^^^^^^^^^^^^^^^ evaluation of `D_CORE` failed here - | - = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: hello --> $DIR/const_panic_2021.rs:33:20 diff --git a/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr index e07b172d426c..a9dc43caf76a 100644 --- a/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr +++ b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr @@ -15,8 +15,6 @@ error[E0080]: evaluation panicked: not implemented | LL | const X: () = unimplemented!(); | ^^^^^^^^^^^^^^^^ evaluation of `X` failed here - | - = note: this error originates in the macro `unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr index 943695d75fce..c33d5b003042 100644 --- a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr +++ b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr @@ -4,6 +4,7 @@ warning: panic message is not a string literal LL | panic!({ "foo" }); | ^^^^^^^^^ | + = note: for more information, see = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see = note: `#[warn(non_fmt_panics)]` (part of `#[warn(rust_2021_compatibility)]`) on by default diff --git a/tests/ui/consts/const-eval/field-access-after-const-eval-fail-in-ty.stderr b/tests/ui/consts/const-eval/field-access-after-const-eval-fail-in-ty.stderr index 9d62bbc2187f..735409b77953 100644 --- a/tests/ui/consts/const-eval/field-access-after-const-eval-fail-in-ty.stderr +++ b/tests/ui/consts/const-eval/field-access-after-const-eval-fail-in-ty.stderr @@ -5,7 +5,7 @@ LL | [(); loop {}].field; | ^^^^^^^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/field-access-after-const-eval-fail-in-ty.rs:4:10 | diff --git a/tests/ui/consts/const-eval/format.rs b/tests/ui/consts/const-eval/format.rs index a8085a786e18..f25c7018f826 100644 --- a/tests/ui/consts/const-eval/format.rs +++ b/tests/ui/consts/const-eval/format.rs @@ -6,7 +6,7 @@ const fn failure() { const fn print() { println!("{:?}", 0); //~^ ERROR cannot call non-const formatting macro in constant functions - //~| ERROR cannot call non-const function `_print` in constant functions + //~| ERROR cannot call non-const function `std::io::_print` in constant functions } const fn format_args() { diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index ea191eb5c098..67bef0ce6c35 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -13,9 +13,8 @@ LL | println!("{:?}", 0); | ^^^^^^^^^^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0015]: cannot call non-const function `_print` in constant functions +error[E0015]: cannot call non-const function `std::io::_print` in constant functions --> $DIR/format.rs:7:5 | LL | println!("{:?}", 0); @@ -24,7 +23,6 @@ LL | println!("{:?}", 0); note: function `_print` is not const --> $SRC_DIR/std/src/io/stdio.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const formatting macro in constant functions --> $DIR/format.rs:13:5 diff --git a/tests/ui/consts/const-eval/heap/vec-not-made-global.rs b/tests/ui/consts/const-eval/heap/vec-not-made-global.rs new file mode 100644 index 000000000000..4f78e977e4d5 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/vec-not-made-global.rs @@ -0,0 +1,5 @@ +#![feature(const_heap)] +const V: Vec = Vec::with_capacity(1); +//~^ ERROR: encountered `const_allocate` pointer in final value that was not made global + +fn main() {} diff --git a/tests/ui/consts/const-eval/heap/vec-not-made-global.stderr b/tests/ui/consts/const-eval/heap/vec-not-made-global.stderr new file mode 100644 index 000000000000..595cbeb8df26 --- /dev/null +++ b/tests/ui/consts/const-eval/heap/vec-not-made-global.stderr @@ -0,0 +1,10 @@ +error: encountered `const_allocate` pointer in final value that was not made global + --> $DIR/vec-not-made-global.rs:2:1 + | +LL | const V: Vec = Vec::with_capacity(1); + | ^^^^^^^^^^^^^^^^^ + | + = note: use `const_make_global` to turn allocated pointers into immutable globals before returning + +error: aborting due to 1 previous error + diff --git a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr index bcb6a80a8f2b..5e2e3524ae9e 100644 --- a/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr +++ b/tests/ui/consts/const-eval/ice-unhandled-type-122191.stderr @@ -22,10 +22,16 @@ error[E0425]: cannot find function `value` in this scope --> $DIR/ice-unhandled-type-122191.rs:9:5 | LL | value() - | ^^^^^ help: a constant with a similar name exists: `VALUE` + | ^^^^^ ... LL | const VALUE: Foo = foo(); | ------------------------- similarly named constant `VALUE` defined here + | +help: a constant with a similar name exists + | +LL - value() +LL + VALUE() + | error[E0308]: mismatched types --> $DIR/ice-unhandled-type-122191.rs:17:9 diff --git a/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr index f326da8e26af..a11915d47861 100644 --- a/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr +++ b/tests/ui/consts/const-eval/infinite_loop.eval_limit.stderr @@ -8,7 +8,7 @@ LL | | } | |_________^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/infinite_loop.rs:13:18 | diff --git a/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr index f326da8e26af..a11915d47861 100644 --- a/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr +++ b/tests/ui/consts/const-eval/infinite_loop.no_ice.stderr @@ -8,7 +8,7 @@ LL | | } | |_________^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/infinite_loop.rs:13:18 | diff --git a/tests/ui/consts/const-eval/issue-44578.stderr b/tests/ui/consts/const-eval/issue-44578.stderr index fd0b9ae1e17d..7625664f9ed6 100644 --- a/tests/ui/consts/const-eval/issue-44578.stderr +++ b/tests/ui/consts/const-eval/issue-44578.stderr @@ -23,8 +23,6 @@ note: erroneous constant encountered | LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) note: erroneous constant encountered --> $DIR/issue-44578.rs:26:20 @@ -33,7 +31,6 @@ LL | println!("{}", as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-eval/issue-52475.stderr b/tests/ui/consts/const-eval/issue-52475.stderr index daaee03787f4..5ba0f8732d80 100644 --- a/tests/ui/consts/const-eval/issue-52475.stderr +++ b/tests/ui/consts/const-eval/issue-52475.stderr @@ -9,7 +9,7 @@ LL | | } | |_________^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/issue-52475.rs:2:18 | diff --git a/tests/ui/consts/const-eval/issue-70723.stderr b/tests/ui/consts/const-eval/issue-70723.stderr index 7cece4ed5d6c..50faa3353e91 100644 --- a/tests/ui/consts/const-eval/issue-70723.stderr +++ b/tests/ui/consts/const-eval/issue-70723.stderr @@ -5,7 +5,7 @@ LL | static _X: () = loop {}; | ^^^^^^^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/issue-70723.rs:1:1 | diff --git a/tests/ui/consts/const-eval/issue-85155.stderr b/tests/ui/consts/const-eval/issue-85155.stderr index 486d2adaf8cd..dfc784bc7a4f 100644 --- a/tests/ui/consts/const-eval/issue-85155.stderr +++ b/tests/ui/consts/const-eval/issue-85155.stderr @@ -5,10 +5,13 @@ LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `post_monomorphization_error::ValidateConstImm::<2, 0, 1>::VALID` failed here note: erroneous constant encountered - --> $DIR/auxiliary/post_monomorphization_error.rs:19:5 + --> $DIR/auxiliary/post_monomorphization_error.rs:13:17 | +LL | let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... LL | static_assert_imm1!(IMM1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------------------------- in this macro invocation | = note: this note originates in the macro `static_assert_imm1` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const-eval/parse_ints.stderr b/tests/ui/consts/const-eval/parse_ints.stderr index 9c9d083e7ca2..7f42e20cf8e8 100644 --- a/tests/ui/consts/const-eval/parse_ints.stderr +++ b/tests/ui/consts/const-eval/parse_ints.stderr @@ -6,8 +6,14 @@ LL | const _TOO_LOW: () = { u64::from_str_radix("12345ABCD", 1); }; | note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation note: inside `core::num::::from_ascii_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation panicked: from_ascii_radix: radix must lie in the range `[2, 36]` @@ -18,8 +24,14 @@ LL | const _TOO_HIGH: () = { u64::from_str_radix("12345ABCD", 37); }; | note: inside `core::num::::from_str_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation note: inside `core::num::::from_ascii_radix` --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation = note: this error originates in the macro `from_str_int_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-eval/ptr_fragments.rs b/tests/ui/consts/const-eval/ptr_fragments.rs index d27804084d73..f4d92127e189 100644 --- a/tests/ui/consts/const-eval/ptr_fragments.rs +++ b/tests/ui/consts/const-eval/ptr_fragments.rs @@ -70,6 +70,7 @@ const _PARTIAL_OVERWRITE: () = { #[allow(dead_code)] #[cfg(not(target_arch = "s390x"))] // u128 is less aligned on s390x, removing the padding fn fragment_in_dst_padding_gets_overwritten() { + // We can't use `repr(align)` here as that would make this not a `ScalarPair` any more. #[repr(C)] struct Pair { x: u128, diff --git a/tests/ui/consts/const-eval/ptr_fragments_in_final.rs b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs index 4037a2d23722..76f292c3f8b5 100644 --- a/tests/ui/consts/const-eval/ptr_fragments_in_final.rs +++ b/tests/ui/consts/const-eval/ptr_fragments_in_final.rs @@ -37,4 +37,40 @@ const MIXED_PTR: MaybeUninit<*const u8> = { //~ERROR: partial pointer in final v } }; +/// This has pointer bytes in the padding of the memory that the final value is read from. +/// To ensure consistent behavior, we want to *always* copy that padding, even if the value +/// could be represented as a more efficient ScalarPair. Hence this must fail to compile. +fn fragment_in_padding() -> impl Copy { + // We can't use `repr(align)` here as that would make this not a `ScalarPair` any more. + #[repr(C)] + #[derive(Clone, Copy)] + struct Thing { + x: u128, + y: usize, + // at least one pointer worth of padding + } + // Ensure there is indeed padding. + const _: () = assert!(mem::size_of::() > 16 + mem::size_of::()); + + #[derive(Clone, Copy)] + union PreservePad { + thing: Thing, + bytes: [u8; mem::size_of::()], + } + + const A: Thing = unsafe { //~ERROR: partial pointer in final value + let mut buffer = [PreservePad { bytes: [0u8; mem::size_of::()] }; 2]; + // The offset half a pointer from the end, so that copying a `Thing` copies exactly + // half the pointer. + let offset = mem::size_of::() - mem::size_of::()/2; + // Ensure this is inside the padding. + assert!(offset >= std::mem::offset_of!(Thing, y) + mem::size_of::()); + + (&raw mut buffer).cast::<&i32>().byte_add(offset).write_unaligned(&1); + buffer[0].thing + }; + + A +} + fn main() {} diff --git a/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr b/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr index 41a822416581..de0cd4db7e15 100644 --- a/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr +++ b/tests/ui/consts/const-eval/ptr_fragments_in_final.stderr @@ -14,5 +14,13 @@ LL | const MIXED_PTR: MaybeUninit<*const u8> = { | = note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value -error: aborting due to 2 previous errors +error: encountered partial pointer in final value of constant + --> $DIR/ptr_fragments_in_final.rs:61:5 + | +LL | const A: Thing = unsafe { + | ^^^^^^^^^^^^^^ + | + = note: while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value + +error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr index 2861f82ec53b..be3b539b269a 100644 --- a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr @@ -64,7 +64,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; 00 00 00 00 │ .... } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; @@ -75,7 +75,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; 00 │ . } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr index 8e6dc66a40ee..9950ac726ca7 100644 --- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr @@ -64,7 +64,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; 00 00 00 00 00 00 00 00 │ ........ } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:61:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; @@ -75,7 +75,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; 00 │ . } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/raw-bytes.rs:63:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr index f087c9960c28..47e26c3ed935 100644 --- a/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr +++ b/tests/ui/consts/const-eval/stable-metric/ctfe-fn-call.stderr @@ -5,7 +5,7 @@ LL | foo(); | ^^^^^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/ctfe-fn-call.rs:32:1 | diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr index ecb48fc62a3d..95e280398050 100644 --- a/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr +++ b/tests/ui/consts/const-eval/stable-metric/ctfe-labelled-loop.stderr @@ -11,7 +11,7 @@ LL | | } | |_____^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/ctfe-labelled-loop.rs:16:1 | diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr index a05d792c95ca..25928b766bda 100644 --- a/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr +++ b/tests/ui/consts/const-eval/stable-metric/ctfe-recursion.stderr @@ -5,7 +5,7 @@ LL | recurse(n - 1) | ^^^^^^^^^^^^^^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/ctfe-recursion.rs:13:1 | diff --git a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr index 2bb9a8a98ec4..44abf8be6bdf 100644 --- a/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr +++ b/tests/ui/consts/const-eval/stable-metric/ctfe-simple-loop.warn.stderr @@ -7,7 +7,7 @@ LL | | } | |_____^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/ctfe-simple-loop.rs:19:1 | @@ -28,7 +28,7 @@ LL | | } | |_____^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/ctfe-simple-loop.rs:20:1 | diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index e4486e3c500b..be5c6f77a087 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -15,7 +15,7 @@ error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer LL | let out_of_bounds_ptr = &ptr[255]; | ^^^^^^^^^ evaluation of `OUT_OF_BOUNDS_PTR` failed here -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:26:1 | LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; @@ -26,7 +26,7 @@ LL | const NULL_U8: NonZero = unsafe { mem::transmute(0u8) }; HEX_DUMP } -error[E0080]: constructing invalid value at .0: encountered 0, but expected something greater or equal to 1 +error[E0080]: constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1 --> $DIR/ub-nonnull.rs:28:1 | LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; diff --git a/tests/ui/consts/const-fn.rs b/tests/ui/consts/const-fn.rs index aa9c478ea633..34aaeac6462d 100644 --- a/tests/ui/consts/const-fn.rs +++ b/tests/ui/consts/const-fn.rs @@ -1,10 +1,6 @@ //@ run-pass -#![allow(stable_features)] - // A very basic test of const fn functionality. -#![feature(const_indexing)] - const fn add(x: u32, y: u32) -> u32 { x + y } diff --git a/tests/ui/typeck/issue-79040.rs b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs similarity index 100% rename from tests/ui/typeck/issue-79040.rs rename to tests/ui/consts/const-item-no-type/dont-suggest-type-error.rs diff --git a/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr new file mode 100644 index 000000000000..8f1fcc645b9c --- /dev/null +++ b/tests/ui/consts/const-item-no-type/dont-suggest-type-error.stderr @@ -0,0 +1,22 @@ +error[E0369]: cannot add `{integer}` to `&str` + --> $DIR/dont-suggest-type-error.rs:2:25 + | +LL | const FOO = "hello" + 1; + | ------- ^ - {integer} + | | + | &str + +error: missing type for `const` item + --> $DIR/dont-suggest-type-error.rs:2:14 + | +LL | const FOO = "hello" + 1; + | ^ + | +help: provide a type for the item + | +LL | const FOO: = "hello" + 1; + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/parser/issues/issue-89574.rs b/tests/ui/consts/const-item-no-type/empty-array.rs similarity index 100% rename from tests/ui/parser/issues/issue-89574.rs rename to tests/ui/consts/const-item-no-type/empty-array.rs diff --git a/tests/ui/consts/const-item-no-type/empty-array.stderr b/tests/ui/consts/const-item-no-type/empty-array.stderr new file mode 100644 index 000000000000..fe307d50353e --- /dev/null +++ b/tests/ui/consts/const-item-no-type/empty-array.stderr @@ -0,0 +1,20 @@ +error[E0282]: type annotations needed + --> $DIR/empty-array.rs:2:25 + | +LL | const EMPTY_ARRAY = []; + | ^^ cannot infer type + +error: missing type for `const` item + --> $DIR/empty-array.rs:2:22 + | +LL | const EMPTY_ARRAY = []; + | ^ + | +help: provide a type for the item + | +LL | const EMPTY_ARRAY: = []; + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/macros/issue-69396-const-no-type-in-macro.rs b/tests/ui/consts/const-item-no-type/in-macro.rs similarity index 100% rename from tests/ui/macros/issue-69396-const-no-type-in-macro.rs rename to tests/ui/consts/const-item-no-type/in-macro.rs diff --git a/tests/ui/consts/const-item-no-type/in-macro.stderr b/tests/ui/consts/const-item-no-type/in-macro.stderr new file mode 100644 index 000000000000..d6182aa11427 --- /dev/null +++ b/tests/ui/consts/const-item-no-type/in-macro.stderr @@ -0,0 +1,47 @@ +error[E0428]: the name `A` is defined multiple times + --> $DIR/in-macro.rs:4:13 + | +LL | const A = "A".$fn(); + | ^^^^^^^^^^^^^^^^^^^^ `A` redefined here +... +LL | / suite! { +LL | | len; +LL | | is_empty; +LL | | } + | |_- in this macro invocation + | + = note: `A` must be defined only once in the value namespace of this module + = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: missing type for `const` item + --> $DIR/in-macro.rs:4:20 + | +LL | const A = "A".$fn(); + | ^ help: provide a type for the constant: `: usize` +... +LL | / suite! { +LL | | len; +LL | | is_empty; +LL | | } + | |_- in this macro invocation + | + = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0121]: missing type for item + --> $DIR/in-macro.rs:4:20 + | +LL | const A = "A".$fn(); + | ^ not allowed in type signatures +... +LL | / suite! { +LL | | len; +LL | | is_empty; +LL | | } + | |_- in this macro invocation + | + = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0121, E0428. +For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/issue-100164.fixed b/tests/ui/consts/const-item-no-type/with-colon.fixed similarity index 100% rename from tests/ui/typeck/issue-100164.fixed rename to tests/ui/consts/const-item-no-type/with-colon.fixed diff --git a/tests/ui/typeck/issue-100164.rs b/tests/ui/consts/const-item-no-type/with-colon.rs similarity index 100% rename from tests/ui/typeck/issue-100164.rs rename to tests/ui/consts/const-item-no-type/with-colon.rs diff --git a/tests/ui/consts/const-item-no-type/with-colon.stderr b/tests/ui/consts/const-item-no-type/with-colon.stderr new file mode 100644 index 000000000000..adbea1f355a0 --- /dev/null +++ b/tests/ui/consts/const-item-no-type/with-colon.stderr @@ -0,0 +1,14 @@ +error: missing type for `const` item + --> $DIR/with-colon.rs:3:10 + | +LL | const _A: = 123; + | ^ help: provide a type for the constant: `i32` + +error: missing type for `const` item + --> $DIR/with-colon.rs:7:14 + | +LL | const _B: = 123; + | ^ help: provide a type for the constant: `i32` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/consts/const-block-item-macro-codegen.rs b/tests/ui/consts/const-item-with-block-body/macro-codegen.rs similarity index 100% rename from tests/ui/consts/const-block-item-macro-codegen.rs rename to tests/ui/consts/const-item-with-block-body/macro-codegen.rs diff --git a/tests/ui/consts/const-block-item.rs b/tests/ui/consts/const-item-with-block-body/static.rs similarity index 100% rename from tests/ui/consts/const-block-item.rs rename to tests/ui/consts/const-item-with-block-body/static.rs diff --git a/tests/ui/consts/const-item-with-block-body/static.stderr b/tests/ui/consts/const-item-with-block-body/static.stderr new file mode 100644 index 000000000000..feaabb92803f --- /dev/null +++ b/tests/ui/consts/const-item-with-block-body/static.stderr @@ -0,0 +1,10 @@ +warning: trait `Value` is never used + --> $DIR/static.rs:5:15 + | +LL | pub trait Value { + | ^^^^^ + | + = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/consts/const-mut-refs/issue-76510.stderr b/tests/ui/consts/const-mut-refs/issue-76510.stderr index 3a6c95141e52..82c9d523e738 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr index da6f2a28d5a8..8f54b4eda227 100644 --- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const B: *mut i32 = &mut 4; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:21:35 @@ -14,9 +14,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const B3: Option<&mut i32> = Some(&mut 42); | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0716]: temporary value dropped while borrowed --> $DIR/mut_ref_in_final.rs:24:42 @@ -86,9 +86,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static RAW_MUT_CAST_S: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:73:54 @@ -96,9 +96,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static RAW_MUT_COERCE_S: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:75:52 @@ -106,9 +106,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const RAW_MUT_CAST_C: SyncPtr = SyncPtr { x : &mut 42 as *mut _ as *const _ }; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0764]: mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/mut_ref_in_final.rs:77:53 @@ -116,9 +116,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const RAW_MUT_COERCE_C: SyncPtr = SyncPtr { x: &mut 0 }; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0080]: constructing invalid value at ..0: encountered a dangling reference (0x2a[noalloc] has no provenance) --> $DIR/mut_ref_in_final.rs:86:5 diff --git a/tests/ui/consts/const-pattern-rewrite-error-32086.stderr b/tests/ui/consts/const-pattern-rewrite-error-32086.stderr index 47616b066321..9c8ac7008709 100644 --- a/tests/ui/consts/const-pattern-rewrite-error-32086.stderr +++ b/tests/ui/consts/const-pattern-rewrite-error-32086.stderr @@ -5,7 +5,13 @@ LL | struct S(u8); | ------------- similarly named tuple struct `S` defined here ... LL | let C(a) = S(11); - | ^ help: a tuple struct with a similar name exists: `S` + | ^ + | +help: a tuple struct with a similar name exists + | +LL - let C(a) = S(11); +LL + let S(a) = S(11); + | error[E0532]: expected tuple struct or tuple variant, found constant `C` --> $DIR/const-pattern-rewrite-error-32086.rs:7:9 @@ -14,7 +20,13 @@ LL | struct S(u8); | ------------- similarly named tuple struct `S` defined here ... LL | let C(..) = S(11); - | ^ help: a tuple struct with a similar name exists: `S` + | ^ + | +help: a tuple struct with a similar name exists + | +LL - let C(..) = S(11); +LL + let S(..) = S(11); + | error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const-promoted-opaque.atomic.stderr b/tests/ui/consts/const-promoted-opaque.atomic.stderr index 64cc7b3a3292..ac31992d0631 100644 --- a/tests/ui/consts/const-promoted-opaque.atomic.stderr +++ b/tests/ui/consts/const-promoted-opaque.atomic.stderr @@ -13,9 +13,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const BAZ: &Foo = &FOO; | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0716]: temporary value dropped while borrowed --> $DIR/const-promoted-opaque.rs:40:26 diff --git a/tests/ui/consts/const-ptr-is-null.stderr b/tests/ui/consts/const-ptr-is-null.stderr index be0a1346c647..b532ed9d4c5f 100644 --- a/tests/ui/consts/const-ptr-is-null.stderr +++ b/tests/ui/consts/const-ptr-is-null.stderr @@ -5,9 +5,16 @@ LL | assert!(!ptr.wrapping_sub(512).is_null()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `MAYBE_NULL` failed inside this call | note: inside `std::ptr::const_ptr::::is_null` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + ::: $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: in this macro invocation note: inside `std::ptr::const_ptr::::is_null::compiletime` + --> $SRC_DIR/core/src/panic.rs:LL:COL --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | + = note: in this macro invocation error: aborting due to 1 previous error diff --git a/tests/ui/consts/const-return-outside-fn.rs b/tests/ui/consts/const-return-outside-fn.rs new file mode 100644 index 000000000000..c2ee8642bf4b --- /dev/null +++ b/tests/ui/consts/const-return-outside-fn.rs @@ -0,0 +1,6 @@ +//! regression test for issue +const x: () = { + return; //~ ERROR return statement outside of function body +}; + +fn main() {} diff --git a/tests/ui/consts/const-return-outside-fn.stderr b/tests/ui/consts/const-return-outside-fn.stderr new file mode 100644 index 000000000000..131d577a2547 --- /dev/null +++ b/tests/ui/consts/const-return-outside-fn.stderr @@ -0,0 +1,9 @@ +error[E0572]: return statement outside of function body + --> $DIR/const-return-outside-fn.rs:3:5 + | +LL | return; + | ^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0572`. diff --git a/tests/ui/consts/const-static-ref-to-closure.rs b/tests/ui/consts/const-static-ref-to-closure.rs new file mode 100644 index 000000000000..06b5ca5a935c --- /dev/null +++ b/tests/ui/consts/const-static-ref-to-closure.rs @@ -0,0 +1,7 @@ +//! regression test for +//@ check-pass +#![allow(dead_code)] + +const X: &'static dyn Fn() = &|| println!("ICE here"); + +fn main() {} diff --git a/tests/ui/consts/const-try-feature-gate.stderr b/tests/ui/consts/const-try-feature-gate.stderr index 62a4a5fba4ff..eb5728aaaa78 100644 --- a/tests/ui/consts/const-try-feature-gate.stderr +++ b/tests/ui/consts/const-try-feature-gate.stderr @@ -30,6 +30,7 @@ LL | Some(())?; = note: see issue #143874 for more information = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: `FromResidual` is not yet stable as a const trait --> $DIR/const-try-feature-gate.rs:4:5 diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.rs b/tests/ui/consts/const_refs_to_static-ice-121413.rs index cc368d971c05..27d5d8600b4b 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.rs +++ b/tests/ui/consts/const_refs_to_static-ice-121413.rs @@ -7,7 +7,7 @@ const REF_INTERIOR_MUT: &usize = { //~^ HELP consider importing this struct static FOO: Sync = AtomicUsize::new(0); - //~^ ERROR failed to resolve: use of undeclared type `AtomicUsize` + //~^ ERROR cannot find //~| WARN trait objects without an explicit `dyn` are deprecated //~| ERROR the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr index 89429d83b205..150b8cb079e7 100644 --- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr +++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `AtomicUsize` +error[E0433]: cannot find type `AtomicUsize` in this scope --> $DIR/const_refs_to_static-ice-121413.rs:9:24 | LL | static FOO: Sync = AtomicUsize::new(0); diff --git a/tests/ui/consts/const_transmute_type_id2.stderr b/tests/ui/consts/const_transmute_type_id2.stderr index 5646eb1257d1..b420deaa49ce 100644 --- a/tests/ui/consts/const_transmute_type_id2.stderr +++ b/tests/ui/consts/const_transmute_type_id2.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id3.stderr b/tests/ui/consts/const_transmute_type_id3.stderr index e731f496652e..9f796cda6145 100644 --- a/tests/ui/consts/const_transmute_type_id3.stderr +++ b/tests/ui/consts/const_transmute_type_id3.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id4.stderr b/tests/ui/consts/const_transmute_type_id4.stderr index b224227cf352..c844b10d78cf 100644 --- a/tests/ui/consts/const_transmute_type_id4.stderr +++ b/tests/ui/consts/const_transmute_type_id4.stderr @@ -5,7 +5,11 @@ LL | assert!(a == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id5.stderr b/tests/ui/consts/const_transmute_type_id5.stderr index 6205679ebb64..9a7384eb95b4 100644 --- a/tests/ui/consts/const_transmute_type_id5.stderr +++ b/tests/ui/consts/const_transmute_type_id5.stderr @@ -5,7 +5,11 @@ LL | assert!(b == b); | ^^^^^^ evaluation of `_` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/const_transmute_type_id6.stderr b/tests/ui/consts/const_transmute_type_id6.stderr index f5d90256e7c6..c0b35f3d1081 100644 --- a/tests/ui/consts/const_transmute_type_id6.stderr +++ b/tests/ui/consts/const_transmute_type_id6.stderr @@ -5,7 +5,11 @@ LL | id == id | ^^^^^^^^ evaluation of `X` failed inside this call | note: inside `::eq` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL --> $SRC_DIR/core/src/any.rs:LL:COL + ::: $SRC_DIR/core/src/any.rs:LL:COL + | + = note: in this macro invocation note: inside `::eq::compiletime` --> $SRC_DIR/core/src/any.rs:LL:COL = note: this error originates in the macro `$crate::intrinsics::const_eval_select` which comes from the expansion of the macro `crate::intrinsics::const_eval_select` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/consts/control-flow/issue-50577.rs b/tests/ui/consts/control-flow/issue-50577.rs index beb9a44fca52..1cecbadbbe63 100644 --- a/tests/ui/consts/control-flow/issue-50577.rs +++ b/tests/ui/consts/control-flow/issue-50577.rs @@ -1,6 +1,6 @@ fn main() { enum Foo { Drop = assert_eq!(1, 1), - //~^ ERROR `if` may be missing an `else` clause + //~^ ERROR mismatched types [E0308] } } diff --git a/tests/ui/consts/control-flow/issue-50577.stderr b/tests/ui/consts/control-flow/issue-50577.stderr index 1556c6f9c558..6f62510c8801 100644 --- a/tests/ui/consts/control-flow/issue-50577.stderr +++ b/tests/ui/consts/control-flow/issue-50577.stderr @@ -1,13 +1,9 @@ -error[E0317]: `if` may be missing an `else` clause +error[E0308]: mismatched types --> $DIR/issue-50577.rs:3:16 | LL | Drop = assert_eq!(1, 1), | ^^^^^^^^^^^^^^^^ expected `isize`, found `()` - | - = note: `if` expressions without `else` evaluate to `()` - = help: consider adding an `else` block that evaluates to the expected type - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0317`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr b/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr index 32a18469ab9e..c28f37bc1670 100644 --- a/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr +++ b/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr @@ -5,7 +5,7 @@ LL | [(); loop {}]; | ^^^^^^^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/do-not-ice-long-constant-evaluation-in-for-loop.rs:10:14 | diff --git a/tests/ui/consts/do-not-ice-on-field-access-of-err-type.stderr b/tests/ui/consts/do-not-ice-on-field-access-of-err-type.stderr index 02b8904fbded..ebf659814e73 100644 --- a/tests/ui/consts/do-not-ice-on-field-access-of-err-type.stderr +++ b/tests/ui/consts/do-not-ice-on-field-access-of-err-type.stderr @@ -5,7 +5,7 @@ LL | let array = [(); { loop {} }]; | ^^^^^^^ | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/do-not-ice-on-field-access-of-err-type.rs:5:22 | diff --git a/tests/ui/consts/issue-102117.stderr b/tests/ui/consts/issue-102117.stderr index cea355d01d7b..4440680bd7f1 100644 --- a/tests/ui/consts/issue-102117.stderr +++ b/tests/ui/consts/issue-102117.stderr @@ -2,7 +2,7 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/issue-102117.rs:17:26 | LL | type_id: TypeId::of::(), - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | | | the parameter type `T` must be valid for the static lifetime... | ...so that the type `T` will meet its required lifetime bounds @@ -16,7 +16,7 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/issue-102117.rs:17:26 | LL | type_id: TypeId::of::(), - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | | | the parameter type `T` must be valid for the static lifetime... | ...so that the type `T` will meet its required lifetime bounds diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr index 11e11adcb5ae..eebfa5d6ea40 100644 --- a/tests/ui/consts/issue-17718-const-bad-values.stderr +++ b/tests/ui/consts/issue-17718-const-bad-values.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-17718-const-borrow.stderr b/tests/ui/consts/issue-17718-const-borrow.stderr index 420a2c378a25..b801498c2028 100644 --- a/tests/ui/consts/issue-17718-const-borrow.stderr +++ b/tests/ui/consts/issue-17718-const-borrow.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const B: &'static UnsafeCell = &A; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-borrow.rs:9:39 @@ -14,9 +14,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const E: &'static UnsafeCell = &D.a; | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/issue-17718-const-borrow.rs:11:23 @@ -24,9 +24,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const F: &'static C = &D; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/issue-29914.rs b/tests/ui/consts/issue-29914.rs index 7897733c7238..36a82f5b9501 100644 --- a/tests/ui/consts/issue-29914.rs +++ b/tests/ui/consts/issue-29914.rs @@ -1,8 +1,4 @@ //@ run-pass -#![allow(stable_features)] - -#![feature(const_indexing)] - const ARR: [usize; 5] = [5, 4, 3, 2, 1]; fn main() { diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs index f2ddc928d122..0553b676bc3e 100644 --- a/tests/ui/consts/issue-94675.rs +++ b/tests/ui/consts/issue-94675.rs @@ -10,7 +10,6 @@ impl<'a> Foo<'a> { const fn spam(&mut self, baz: &mut Vec) { self.bar[0] = baz.len(); //~^ ERROR: `Vec: [const] Index<_>` is not satisfied - //~| ERROR: `Vec: [const] Index` is not satisfied //~| ERROR: `Vec: [const] IndexMut` is not satisfied } } diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index 771f2a14c305..ab7a76a90e02 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -16,17 +16,6 @@ LL | self.bar[0] = baz.len(); note: trait `IndexMut` is implemented but not `const` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -error[E0277]: the trait bound `Vec: [const] Index` is not satisfied - --> $DIR/issue-94675.rs:11:9 - | -LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ - | -note: trait `Index` is implemented but not `const` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -note: required by a bound in `std::ops::IndexMut::index_mut` - --> $SRC_DIR/core/src/ops/index.rs:LL:COL - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs index 6a6b0e666e1c..74e0a36560b0 100644 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs +++ b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.rs @@ -1,7 +1,7 @@ const fn foo(a: i32) -> Vec { vec![1, 2, 3] - //~^ ERROR allocations are not allowed - //~| ERROR cannot call non-const method + //~^ ERROR cannot call non-const + //~| ERROR cannot call non-const } fn main() {} diff --git a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr index 8e52a7aa35e1..a7e8fdf37ae2 100644 --- a/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr +++ b/tests/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -1,21 +1,21 @@ -error[E0010]: allocations are not allowed in constant functions - --> $DIR/bad_const_fn_body_ice.rs:2:5 - | -LL | vec![1, 2, 3] - | ^^^^^^^^^^^^^ allocation not allowed in constant functions - | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0015]: cannot call non-const method `slice::::into_vec::` in constant functions +error[E0015]: cannot call non-const associated function `Box::<[i32; 3]>::new_uninit` in constant functions --> $DIR/bad_const_fn_body_ice.rs:2:5 | LL | vec![1, 2, 3] | ^^^^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0015]: cannot call non-const function `std::boxed::box_assume_init_into_vec_unsafe::` in constant functions + --> $DIR/bad_const_fn_body_ice.rs:2:5 + | +LL | vec![1, 2, 3] + | ^^^^^^^^^^^^^ + | +note: function `box_assume_init_into_vec_unsafe` is not const + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error: aborting due to 2 previous errors -Some errors have detailed explanations: E0010, E0015. -For more information about an error, try `rustc --explain E0010`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/missing_span_in_backtrace.rs b/tests/ui/consts/missing_span_in_backtrace.rs index 09a11c75fd7b..b679493eb08e 100644 --- a/tests/ui/consts/missing_span_in_backtrace.rs +++ b/tests/ui/consts/missing_span_in_backtrace.rs @@ -1,6 +1,6 @@ //! Check what happens when the error occurs inside a std function that we can't print the span of. //@ ignore-backends: gcc -//@ compile-flags: -Z ui-testing=no +//@ compile-flags: -Z ui-testing=no --diagnostic-width=80 use std::{ mem::{self, MaybeUninit}, diff --git a/tests/ui/consts/missing_span_in_backtrace.stderr b/tests/ui/consts/missing_span_in_backtrace.stderr index 55dde6358286..b86911e7057b 100644 --- a/tests/ui/consts/missing_span_in_backtrace.stderr +++ b/tests/ui/consts/missing_span_in_backtrace.stderr @@ -1,12 +1,12 @@ error[E0080]: memory access failed: attempting to access 1 byte, but got ALLOC0+0x4 which is at or beyond the end of the allocation of size 4 bytes --> $DIR/missing_span_in_backtrace.rs:16:9 | -16 | / ptr::swap_nonoverlapping( -17 | | &mut x1 as *mut _ as *mut MaybeUninit, -18 | | &mut x2 as *mut _ as *mut MaybeUninit, -19 | | 10, -20 | | ); - | |_________^ evaluation of `X` failed inside this call +16 | / ... ptr::swap_nonoverlapping( +17 | | ... &mut x1 as *mut _ as *mut MaybeUninit, +18 | | ... &mut x2 as *mut _ as *mut MaybeUninit, +19 | | ... 10, +20 | | ... ); + | |_______^ evaluation of `X` failed inside this call | note: inside `swap_nonoverlapping::compiletime::>` --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL diff --git a/tests/ui/consts/partial_qualif.stderr b/tests/ui/consts/partial_qualif.stderr index b7632eb868ac..f69fa1c46c01 100644 --- a/tests/ui/consts/partial_qualif.stderr +++ b/tests/ui/consts/partial_qualif.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | &{a} | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs index 56155e519dca..4bd5f746f502 100644 --- a/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs +++ b/tests/ui/consts/precise-drop-allow-const-fn-unstable.rs @@ -2,7 +2,7 @@ //@ compile-flags: --crate-type=lib -Cinstrument-coverage -Zno-profiler-runtime //@[allow] check-pass -#![feature(staged_api, rustc_allow_const_fn_unstable)] +#![feature(staged_api, rustc_attrs)] #![stable(feature = "rust_test", since = "1.0.0")] #[stable(feature = "rust_test", since = "1.0.0")] diff --git a/tests/ui/consts/promoted_const_call3.rs b/tests/ui/consts/promoted_const_call3.rs index dc05a3b58442..82e9eac31d5c 100644 --- a/tests/ui/consts/promoted_const_call3.rs +++ b/tests/ui/consts/promoted_const_call3.rs @@ -4,12 +4,12 @@ pub const C: () = { //~^ ERROR: destructor of `String` cannot be evaluated at compile-time }; -pub const _: () = { +const _: () = { let _: &'static _ = &id(&String::new()); //~^ ERROR: destructor of `String` cannot be evaluated at compile-time }; -pub const _: () = { +const _: () = { let _: &'static _ = &std::mem::ManuallyDrop::new(String::new()); //~^ ERROR: temporary value dropped while borrowed }; diff --git a/tests/ui/consts/ptr_is_null.rs b/tests/ui/consts/ptr_is_null.rs index 8b41f5718e8d..9f8a1697fd70 100644 --- a/tests/ui/consts/ptr_is_null.rs +++ b/tests/ui/consts/ptr_is_null.rs @@ -5,12 +5,12 @@ const FOO: &usize = &42; -pub const _: () = assert!(!(FOO as *const usize).is_null()); +const _: () = assert!(!(FOO as *const usize).is_null()); -pub const _: () = assert!(!(42 as *const usize).is_null()); +const _: () = assert!(!(42 as *const usize).is_null()); -pub const _: () = assert!((0 as *const usize).is_null()); +const _: () = assert!((0 as *const usize).is_null()); -pub const _: () = assert!(std::ptr::null::().is_null()); +const _: () = assert!(std::ptr::null::().is_null()); -pub const _: () = assert!(!("foo" as *const str).is_null()); +const _: () = assert!(!("foo" as *const str).is_null()); diff --git a/tests/ui/consts/qualif_overwrite.stderr b/tests/ui/consts/qualif_overwrite.stderr index 4aaaa4b2ca90..1dc2bf7f1231 100644 --- a/tests/ui/consts/qualif_overwrite.stderr +++ b/tests/ui/consts/qualif_overwrite.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | &{a} | ^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/qualif_overwrite_2.stderr b/tests/ui/consts/qualif_overwrite_2.stderr index bc1681418765..fb8ac601c67a 100644 --- a/tests/ui/consts/qualif_overwrite_2.stderr +++ b/tests/ui/consts/qualif_overwrite_2.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | &{a.0} | ^^^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 1 previous error diff --git a/tests/ui/consts/recursive-const-in-impl.stderr b/tests/ui/consts/recursive-const-in-impl.stderr index ec5ad52fadd4..c53ce701566e 100644 --- a/tests/ui/consts/recursive-const-in-impl.stderr +++ b/tests/ui/consts/recursive-const-in-impl.stderr @@ -6,7 +6,6 @@ LL | println!("{}", Thing::::X); | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "14"]` attribute to your crate (`recursive_const_in_impl`) = note: query depth increased by 9 when simplifying constant for the type system `main::promoted[0]` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/consts/refs-to-cell-in-final.stderr b/tests/ui/consts/refs-to-cell-in-final.stderr index ac866dbe7210..e30b5aa24e76 100644 --- a/tests/ui/consts/refs-to-cell-in-final.stderr +++ b/tests/ui/consts/refs-to-cell-in-final.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | static RAW_SYNC_S: SyncPtr> = SyncPtr { x: &Cell::new(42) }; | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/refs-to-cell-in-final.rs:15:53 @@ -14,9 +14,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const RAW_SYNC_C: SyncPtr> = SyncPtr { x: &Cell::new(42) }; | ^^^^^^^^^^^^^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/refs-to-cell-in-final.rs:41:57 @@ -31,9 +31,9 @@ LL | | x LL | | }; | |_^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs deleted file mode 100644 index 93a5e8e4f458..000000000000 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ compile-flags: -Znext-solver -//@ known-bug: #110395 - -#![crate_type = "lib"] -#![feature(staged_api, const_trait_impl, const_default)] -#![stable(feature = "foo", since = "1.0.0")] - -#[stable(feature = "potato", since = "1.27.0")] -pub struct Data { - _data: u128, -} - -#[stable(feature = "potato", since = "1.27.0")] -#[rustc_const_unstable(feature = "data_foo", issue = "none")] -impl const std::fmt::Debug for Data { - fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { - Ok(()) - } -} diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr deleted file mode 100644 index 55c085396882..000000000000 --- a/tests/ui/consts/rustc-impl-const-stability.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: const `impl` for trait `Debug` which is not `const` - --> $DIR/rustc-impl-const-stability.rs:15:12 - | -LL | impl const std::fmt::Debug for Data { - | ^^^^^^^^^^^^^^^ this trait is not `const` - | - = note: marking a trait with `const` ensures all default method bodies are `const` - = note: adding a non-const method body in the future would be a breaking change - -error: aborting due to 1 previous error - diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs index d60fe7d409af..989de389180a 100644 --- a/tests/ui/consts/static-default-lifetime/elided-lifetime.rs +++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.rs @@ -16,7 +16,7 @@ impl Bar for Foo<'_> { const STATIC: &str = ""; //~^ ERROR `&` without an explicit lifetime name cannot be used here //~| WARN this was previously accepted by the compiler but is being phased out - //~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration + //~| ERROR lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration } fn main() {} diff --git a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr index bb8365b0ae56..ae4a48e4e932 100644 --- a/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr +++ b/tests/ui/consts/static-default-lifetime/elided-lifetime.stderr @@ -39,14 +39,14 @@ help: use the `'static` lifetime LL | const STATIC: &'static str = ""; | +++++++ -error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration +error[E0195]: lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration --> $DIR/elided-lifetime.rs:16:17 | LL | const STATIC: &str; - | - lifetimes in impl do not match this associated const in trait + | - lifetimes in impl do not match this associated constant in trait ... LL | const STATIC: &str = ""; - | ^ lifetimes do not match associated const in trait + | ^ lifetimes do not match associated constant in trait error: aborting due to 3 previous errors diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs index 85746df146fc..ecc163aecbf1 100644 --- a/tests/ui/consts/static-default-lifetime/static-trait-impl.rs +++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.rs @@ -9,7 +9,7 @@ impl Bar<'_> for A { const STATIC: &str = ""; //~^ ERROR `&` without an explicit lifetime name cannot be used here //~| WARN this was previously accepted by the compiler but is being phased out - //~| ERROR lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration + //~| ERROR lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration } struct B; diff --git a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr index 38d24db1317f..2bc271dccad9 100644 --- a/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr +++ b/tests/ui/consts/static-default-lifetime/static-trait-impl.stderr @@ -21,14 +21,14 @@ help: use the `'static` lifetime LL | const STATIC: &'static str = ""; | +++++++ -error[E0195]: lifetime parameters or bounds on associated const `STATIC` do not match the trait declaration +error[E0195]: lifetime parameters or bounds on associated constant `STATIC` do not match the trait declaration --> $DIR/static-trait-impl.rs:9:17 | LL | const STATIC: &'a str; - | - lifetimes in impl do not match this associated const in trait + | - lifetimes in impl do not match this associated constant in trait ... LL | const STATIC: &str = ""; - | ^ lifetimes do not match associated const in trait + | ^ lifetimes do not match associated constant in trait error: aborting due to 2 previous errors diff --git a/tests/ui/consts/timeout.stderr b/tests/ui/consts/timeout.stderr index ecefeff76e96..e96e5875058a 100644 --- a/tests/ui/consts/timeout.stderr +++ b/tests/ui/consts/timeout.stderr @@ -1,8 +1,13 @@ error: constant evaluation is taking a long time + --> $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + | --> $SRC_DIR/core/src/num/mod.rs:LL:COL + ::: $SRC_DIR/core/src/num/mod.rs:LL:COL + | + = note: in this macro invocation | = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. - If your compilation actually takes a long time, you can safely allow the lint. + If your compilation actually takes a long time, you can safely allow the lint help: the constant being evaluated --> $DIR/timeout.rs:7:1 | diff --git a/tests/ui/consts/write_to_static_via_mut_ref.stderr b/tests/ui/consts/write_to_static_via_mut_ref.stderr index ce44047f1550..be1f7178998a 100644 --- a/tests/ui/consts/write_to_static_via_mut_ref.stderr +++ b/tests/ui/consts/write_to_static_via_mut_ref.stderr @@ -4,9 +4,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static OH_NO: &mut i32 = &mut 42; | ^^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item --> $DIR/write_to_static_via_mut_ref.rs:4:5 diff --git a/tests/ui/contracts/associated-item.rs b/tests/ui/contracts/associated-item.rs index 4a2d05abbc53..86ff05f6c0f4 100644 --- a/tests/ui/contracts/associated-item.rs +++ b/tests/ui/contracts/associated-item.rs @@ -3,8 +3,8 @@ //@ compile-flags: --crate-type=lib //@ check-pass +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use extern crate core; diff --git a/tests/ui/contracts/associated-item.stderr b/tests/ui/contracts/associated-item.stderr deleted file mode 100644 index 20651026b87a..000000000000 --- a/tests/ui/contracts/associated-item.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/associated-item.rs:6:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/async-fn-contract-ice-145333.rs b/tests/ui/contracts/async-fn-contract-ice-145333.rs index a6de8a786af9..e9e2877cd2de 100644 --- a/tests/ui/contracts/async-fn-contract-ice-145333.rs +++ b/tests/ui/contracts/async-fn-contract-ice-145333.rs @@ -1,7 +1,7 @@ //@ compile-flags: --crate-type=lib //@ edition: 2021 +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete #[core::contracts::ensures(|ret| *ret)] //~^ ERROR contract annotations are not yet supported on async or gen functions diff --git a/tests/ui/contracts/async-fn-contract-ice-145333.stderr b/tests/ui/contracts/async-fn-contract-ice-145333.stderr index 77f5379e6fb5..031cff5cad1b 100644 --- a/tests/ui/contracts/async-fn-contract-ice-145333.stderr +++ b/tests/ui/contracts/async-fn-contract-ice-145333.stderr @@ -4,14 +4,5 @@ error: contract annotations are not yet supported on async or gen functions LL | #[core::contracts::ensures(|ret| *ret)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/async-fn-contract-ice-145333.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error diff --git a/tests/ui/contracts/contract-annotation-limitations.rs b/tests/ui/contracts/contract-annotation-limitations.rs index 10b3bacab5cf..0ecc1d15aa7b 100644 --- a/tests/ui/contracts/contract-annotation-limitations.rs +++ b/tests/ui/contracts/contract-annotation-limitations.rs @@ -1,8 +1,8 @@ //! Test for some of the existing limitations and the current error messages. //! Some of these limitations may be removed in the future. +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![allow(dead_code)] /// Represent a 5-star system. diff --git a/tests/ui/contracts/contract-annotation-limitations.stderr b/tests/ui/contracts/contract-annotation-limitations.stderr index 14338cf4b868..c0dc37fee4c4 100644 --- a/tests/ui/contracts/contract-annotation-limitations.stderr +++ b/tests/ui/contracts/contract-annotation-limitations.stderr @@ -10,14 +10,5 @@ error: contract annotations is only supported in functions with bodies LL | #[core::contracts::ensures(|ret| ret.is_none_or(Stars::is_valid))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-annotation-limitations.rs:4:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr b/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_const_fail.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr b/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-generics.rs b/tests/ui/contracts/contract-attributes-generics.rs index 3763ce116f84..6fd4c0a9790b 100644 --- a/tests/ui/contracts/contract-attributes-generics.rs +++ b/tests/ui/contracts/contract-attributes-generics.rs @@ -16,8 +16,8 @@ //@ [chk_fail_post] compile-flags: -Zcontract-checks=yes //@ [chk_const_fail] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] use std::ops::Sub; diff --git a/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr deleted file mode 100644 index 0630811d4f7e..000000000000 --- a/tests/ui/contracts/contract-attributes-generics.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-generics.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.chk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.rs b/tests/ui/contracts/contract-attributes-nest.rs index d367687b84e3..89bd0a2b1136 100644 --- a/tests/ui/contracts/contract-attributes-nest.rs +++ b/tests/ui/contracts/contract-attributes-nest.rs @@ -16,8 +16,8 @@ //@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes //@ [chk_fail_post] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #[core::contracts::requires(x.baz > 0)] #[core::contracts::ensures(|ret| *ret > 100)] diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.unchk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.unchk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr deleted file mode 100644 index 9ca95b8bb01a..000000000000 --- a/tests/ui/contracts/contract-attributes-nest.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-nest.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr b/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.chk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr b/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.rs b/tests/ui/contracts/contract-attributes-tail.rs index 43edfe5e803f..361725474099 100644 --- a/tests/ui/contracts/contract-attributes-tail.rs +++ b/tests/ui/contracts/contract-attributes-tail.rs @@ -16,8 +16,8 @@ //@ [chk_fail_pre] compile-flags: -Zcontract-checks=yes //@ [chk_fail_post] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #[core::contracts::requires(x.baz > 0)] #[core::contracts::ensures(|ret| *ret > 100)] diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.unchk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.unchk_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr b/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr deleted file mode 100644 index f87e7e19fa3d..000000000000 --- a/tests/ui/contracts/contract-attributes-tail.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-attributes-tail.rs:19:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-captures-via-closure-copy.rs b/tests/ui/contracts/contract-captures-via-closure-copy.rs index bc7e5b9b6f10..a5453503b4bd 100644 --- a/tests/ui/contracts/contract-captures-via-closure-copy.rs +++ b/tests/ui/contracts/contract-captures-via-closure-copy.rs @@ -1,8 +1,8 @@ //@ run-crash //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] struct Baz { baz: i32 diff --git a/tests/ui/contracts/contract-captures-via-closure-copy.stderr b/tests/ui/contracts/contract-captures-via-closure-copy.stderr deleted file mode 100644 index d92db601608f..000000000000 --- a/tests/ui/contracts/contract-captures-via-closure-copy.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-captures-via-closure-copy.rs:4:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.rs b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs index 1ec2feb045a3..5153a7b48dcd 100644 --- a/tests/ui/contracts/contract-captures-via-closure-noncopy.rs +++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.rs @@ -1,8 +1,8 @@ //@ edition:2015..2021 //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] struct Baz { baz: i32 @@ -13,7 +13,7 @@ struct Baz { #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz*2 })] // Relevant thing is this: ^^^^^^^^^^^ // because we are capturing state that is non-Copy. -//~^^^ ERROR trait bound `Baz: std::marker::Copy` is not satisfied +//~^^^ ERROR trait bound `Baz: Copy` is not satisfied fn doubler(x: Baz) -> Baz { Baz { baz: x.baz + 10 } } diff --git a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr index 29adeaec3e16..20c220e98bcc 100644 --- a/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr +++ b/tests/ui/contracts/contract-captures-via-closure-noncopy.stderr @@ -1,13 +1,4 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-captures-via-closure-noncopy.rs:4:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0277]: the trait bound `Baz: std::marker::Copy` is not satisfied in `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}` +error[E0277]: the trait bound `Baz: Copy` is not satisfied in `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}` --> $DIR/contract-captures-via-closure-noncopy.rs:13:1 | LL | #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz*2 })] @@ -18,7 +9,7 @@ LL | #[core::contracts::ensures({let old = x; move |ret:&Baz| ret.baz == old.baz | unsatisfied trait bound | required by a bound introduced by this call | - = help: within `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}`, the trait `std::marker::Copy` is not implemented for `Baz` + = help: within `{closure@$DIR/contract-captures-via-closure-noncopy.rs:13:42: 13:57}`, the trait `Copy` is not implemented for `Baz` note: required because it's used within this closure --> $DIR/contract-captures-via-closure-noncopy.rs:13:42 | @@ -32,6 +23,6 @@ LL + #[derive(Copy)] LL | struct Baz { | -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/contracts/contract-const-fn.all_pass.stderr b/tests/ui/contracts/contract-const-fn.all_pass.stderr deleted file mode 100644 index e5b1df655823..000000000000 --- a/tests/ui/contracts/contract-const-fn.all_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-const-fn.rs:17:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-const-fn.rs b/tests/ui/contracts/contract-const-fn.rs index fe8dd37b1f52..c79ab33e8ec8 100644 --- a/tests/ui/contracts/contract-const-fn.rs +++ b/tests/ui/contracts/contract-const-fn.rs @@ -14,8 +14,8 @@ //@ [all_pass] compile-flags: -Zcontract-checks=yes //@ [runtime_fail_pre] compile-flags: -Zcontract-checks=yes //@ [runtime_fail_post] compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::*; diff --git a/tests/ui/contracts/contract-const-fn.runtime_fail_post.stderr b/tests/ui/contracts/contract-const-fn.runtime_fail_post.stderr deleted file mode 100644 index e5b1df655823..000000000000 --- a/tests/ui/contracts/contract-const-fn.runtime_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-const-fn.rs:17:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contract-const-fn.runtime_fail_pre.stderr b/tests/ui/contracts/contract-const-fn.runtime_fail_pre.stderr deleted file mode 100644 index e5b1df655823..000000000000 --- a/tests/ui/contracts/contract-const-fn.runtime_fail_pre.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-const-fn.rs:17:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs b/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs index fc07729e9132..4b2d4a80237f 100644 --- a/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs +++ b/tests/ui/contracts/contracts-disabled-side-effect-declarations.rs @@ -1,6 +1,6 @@ //@ run-pass +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/contracts-disabled-side-effect-declarations.stderr b/tests/ui/contracts/contracts-disabled-side-effect-declarations.stderr deleted file mode 100644 index 4c8a12538433..000000000000 --- a/tests/ui/contracts/contracts-disabled-side-effect-declarations.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-disabled-side-effect-declarations.rs:2:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs b/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs index a3a77b0de9a2..1488b8f8d3fd 100644 --- a/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs +++ b/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs @@ -1,6 +1,6 @@ //@ run-pass +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::ensures; diff --git a/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr b/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr deleted file mode 100644 index dd9ebe9bd355..000000000000 --- a/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-disabled-side-effect-ensures.rs:2:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_ret.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_try.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_fail_yeet.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.rs b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs index 44ae07d8c95c..71c69fa83ccb 100644 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.rs +++ b/tests/ui/contracts/contracts-ensures-early-fn-exit.rs @@ -13,8 +13,8 @@ //@ [chk_fail_yeet] compile-flags: -Zcontract-checks=yes //! This test ensures that ensures clauses are checked for different return points of a function. +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![feature(yeet_expr)] /// This ensures will fail in different return points depending on the input. diff --git a/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr b/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr deleted file mode 100644 index d693fad446a4..000000000000 --- a/tests/ui/contracts/contracts-ensures-early-fn-exit.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-early-fn-exit.rs:16:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs index f01a852fbff3..0fc9e5590f02 100644 --- a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs +++ b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #[core::contracts::ensures(|ret| *ret > 0)] fn outer() -> i32 { diff --git a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr b/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr deleted file mode 100644 index 49a372b53c7d..000000000000 --- a/tests/ui/contracts/contracts-ensures-is-not-inherited-when-nesting.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-ensures-is-not-inherited-when-nesting.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs index 2c2a4a697855..3ac539adb247 100644 --- a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs +++ b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] struct Outer { outer: std::cell::Cell } diff --git a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr b/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr deleted file mode 100644 index 48898c4434ad..000000000000 --- a/tests/ui/contracts/contracts-requires-is-not-inherited-when-nesting.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contracts-requires-is-not-inherited-when-nesting.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/declared-vars-referring-to-params.rs b/tests/ui/contracts/declared-vars-referring-to-params.rs index 52885da048e2..d915dc09cfe2 100644 --- a/tests/ui/contracts/declared-vars-referring-to-params.rs +++ b/tests/ui/contracts/declared-vars-referring-to-params.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::{ensures, requires}; diff --git a/tests/ui/contracts/declared-vars-referring-to-params.stderr b/tests/ui/contracts/declared-vars-referring-to-params.stderr deleted file mode 100644 index 0ad9064e8606..000000000000 --- a/tests/ui/contracts/declared-vars-referring-to-params.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/declared-vars-referring-to-params.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/declared-vars-used-in-ensures.rs b/tests/ui/contracts/declared-vars-used-in-ensures.rs index 9703709e2b8e..ddab57483668 100644 --- a/tests/ui/contracts/declared-vars-used-in-ensures.rs +++ b/tests/ui/contracts/declared-vars-used-in-ensures.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::{ensures, requires}; diff --git a/tests/ui/contracts/declared-vars-used-in-ensures.stderr b/tests/ui/contracts/declared-vars-used-in-ensures.stderr deleted file mode 100644 index 000a1b239932..000000000000 --- a/tests/ui/contracts/declared-vars-used-in-ensures.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/declared-vars-used-in-ensures.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs b/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs index e066a95314a9..6b7896101ca0 100644 --- a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs +++ b/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.rs @@ -1,7 +1,7 @@ //@ run-pass //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::{ensures, requires}; diff --git a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.stderr b/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.stderr deleted file mode 100644 index 52b163553fba..000000000000 --- a/tests/ui/contracts/declared-vars-used-in-requires-and-ensures.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/declared-vars-used-in-requires-and-ensures.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs index 69be906782a6..fecac593f0e5 100644 --- a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs +++ b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.rs @@ -1,7 +1,7 @@ //! Checks for compilation errors related to adding contracts to non-function items. +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![allow(dead_code)] #[core::contracts::requires(true)] diff --git a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr index 0a7fff8183e0..864e94997a2e 100644 --- a/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr +++ b/tests/ui/contracts/disallow-contract-annotation-on-non-fn.stderr @@ -40,14 +40,5 @@ error: contract annotations can only be used on functions LL | #[core::contracts::requires(true)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/disallow-contract-annotation-on-non-fn.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 7 previous errors diff --git a/tests/ui/contracts/empty-ensures.rs b/tests/ui/contracts/empty-ensures.rs index d897f27bf6c9..0a5239111786 100644 --- a/tests/ui/contracts/empty-ensures.rs +++ b/tests/ui/contracts/empty-ensures.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::ensures; diff --git a/tests/ui/contracts/empty-ensures.stderr b/tests/ui/contracts/empty-ensures.stderr index 407a253bd856..6a19d234b52c 100644 --- a/tests/ui/contracts/empty-ensures.stderr +++ b/tests/ui/contracts/empty-ensures.stderr @@ -1,12 +1,3 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/empty-ensures.rs:2:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0277]: expected a `Fn(&_)` closure, found `()` --> $DIR/empty-ensures.rs:8:1 | @@ -20,6 +11,6 @@ LL | #[ensures()] note: required by a bound in `build_check_ensures` --> $SRC_DIR/core/src/contracts.rs:LL:COL -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/contracts/empty-requires.rs b/tests/ui/contracts/empty-requires.rs index e3c72dcd66a1..dedcc10d52cb 100644 --- a/tests/ui/contracts/empty-requires.rs +++ b/tests/ui/contracts/empty-requires.rs @@ -1,7 +1,7 @@ //@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/empty-requires.stderr b/tests/ui/contracts/empty-requires.stderr index b48e547b8cda..702b8a23c55e 100644 --- a/tests/ui/contracts/empty-requires.stderr +++ b/tests/ui/contracts/empty-requires.stderr @@ -1,18 +1,9 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/empty-requires.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/empty-requires.rs:9:1 | LL | #[requires()] | ^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/contracts/incomplete-feature.rs b/tests/ui/contracts/incomplete-feature.rs new file mode 100644 index 000000000000..f1351e2f87e3 --- /dev/null +++ b/tests/ui/contracts/incomplete-feature.rs @@ -0,0 +1,17 @@ +//@ run-pass +//@ compile-flags: -Zcontract-checks=yes + +// This test specifically checks that the [incomplete_features] warning is +// emitted when the `contracts` feature gate is enabled, so that it can be +// marked as `expect`ed in other tests in order to reduce duplication. +#![feature(contracts)] +//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] +extern crate core; +use core::contracts::requires; + +#[requires(true)] +fn foo() {} + +fn main() { + foo() +} diff --git a/tests/ui/contracts/incomplete-feature.stderr b/tests/ui/contracts/incomplete-feature.stderr new file mode 100644 index 000000000000..7683926df073 --- /dev/null +++ b/tests/ui/contracts/incomplete-feature.stderr @@ -0,0 +1,11 @@ +warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/incomplete-feature.rs:7:12 + | +LL | #![feature(contracts)] + | ^^^^^^^^^ + | + = note: see issue #128044 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr deleted file mode 100644 index acce6b1fbc72..000000000000 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:8:12 - | -LL | #![feature(contracts)] // to access core::contracts - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr deleted file mode 100644 index acce6b1fbc72..000000000000 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:8:12 - | -LL | #![feature(contracts)] // to access core::contracts - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.rs b/tests/ui/contracts/internal_machinery/contract-lang-items.rs index ad88ebfe22e3..d67560103644 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.rs +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.rs @@ -5,8 +5,8 @@ // //@ [chk_fail_post] run-crash +#![expect(incomplete_features)] #![feature(contracts)] // to access core::contracts -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![feature(contracts_internals)] // to access check_requires lang item #![feature(core_intrinsics)] fn foo(x: Baz) -> i32 { diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr deleted file mode 100644 index acce6b1fbc72..000000000000 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:8:12 - | -LL | #![feature(contracts)] // to access core::contracts - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/internal_machinery/lowering/basics.rs b/tests/ui/contracts/internal_machinery/lowering/basics.rs index 9160517a7932..7b3a769af825 100644 --- a/tests/ui/contracts/internal_machinery/lowering/basics.rs +++ b/tests/ui/contracts/internal_machinery/lowering/basics.rs @@ -1,6 +1,6 @@ //@ run-pass +#![expect(incomplete_features)] #![feature(contracts, cfg_contract_checks, contracts_internals, core_intrinsics)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; diff --git a/tests/ui/contracts/internal_machinery/lowering/basics.stderr b/tests/ui/contracts/internal_machinery/lowering/basics.stderr deleted file mode 100644 index 118229694a90..000000000000 --- a/tests/ui/contracts/internal_machinery/lowering/basics.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basics.rs:2:12 - | -LL | #![feature(contracts, cfg_contract_checks, contracts_internals, core_intrinsics)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/requires-block-stmt.rs b/tests/ui/contracts/requires-block-stmt.rs new file mode 100644 index 000000000000..0f0801bb65f5 --- /dev/null +++ b/tests/ui/contracts/requires-block-stmt.rs @@ -0,0 +1,22 @@ +//@ run-pass +//@ compile-flags: -Zcontract-checks=yes + +#![expect(incomplete_features)] +#![feature(contracts)] +extern crate core; +use core::contracts::requires; + +// Compound statements (those using [ExpressionWithBlock] +// (https://doc.rust-lang.org/beta/reference/expressions.html#railroad-ExpressionWithBlock)) +// like blocks, if-expressions, and loops require no trailing semicolon. This +// regression test captures the case where the last statement in the contract +// declarations has no trailing semicolon. +#[requires( + {} + true +)] +fn foo() {} + +fn main() { + foo() +} diff --git a/tests/ui/contracts/requires-bool-expr-with-semicolon.rs b/tests/ui/contracts/requires-bool-expr-with-semicolon.rs index d0b3ed661ed6..3a1a6549a343 100644 --- a/tests/ui/contracts/requires-bool-expr-with-semicolon.rs +++ b/tests/ui/contracts/requires-bool-expr-with-semicolon.rs @@ -1,7 +1,7 @@ //@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr b/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr index fd38fa4edcf5..559c710b1456 100644 --- a/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr +++ b/tests/ui/contracts/requires-bool-expr-with-semicolon.stderr @@ -1,18 +1,9 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/requires-bool-expr-with-semicolon.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/requires-bool-expr-with-semicolon.rs:9:1 | LL | #[requires(true;)] | ^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/contracts/requires-no-final-expression.rs b/tests/ui/contracts/requires-no-final-expression.rs index 474b29d63ba6..0188a9f607a3 100644 --- a/tests/ui/contracts/requires-no-final-expression.rs +++ b/tests/ui/contracts/requires-no-final-expression.rs @@ -1,7 +1,7 @@ //@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes +#![expect(incomplete_features)] #![feature(contracts)] -//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] extern crate core; use core::contracts::requires; diff --git a/tests/ui/contracts/requires-no-final-expression.stderr b/tests/ui/contracts/requires-no-final-expression.stderr index 0db164857394..ae71ee3c996c 100644 --- a/tests/ui/contracts/requires-no-final-expression.stderr +++ b/tests/ui/contracts/requires-no-final-expression.stderr @@ -1,18 +1,9 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/requires-no-final-expression.rs:3:12 - | -LL | #![feature(contracts)] - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - error[E0308]: mismatched types --> $DIR/requires-no-final-expression.rs:9:1 | LL | #[requires(let y = 1;)] | ^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/coroutine/gen_block_is_coro.stderr b/tests/ui/coroutine/gen_block_is_coro.stderr index 444f0eca1d54..fac09f600059 100644 --- a/tests/ui/coroutine/gen_block_is_coro.stderr +++ b/tests/ui/coroutine/gen_block_is_coro.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}: C --> $DIR/gen_block_is_coro.rs:7:13 | LL | fn foo() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}` LL | gen { yield 42 } | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:8:5: 8:8}` here @@ -10,7 +10,7 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}: --> $DIR/gen_block_is_coro.rs:11:13 | LL | fn bar() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}` LL | gen { yield 42 } | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:12:5: 12:8}` here @@ -18,7 +18,7 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}: --> $DIR/gen_block_is_coro.rs:15:13 | LL | fn baz() -> impl Coroutine { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the nightly-only, unstable trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}` LL | gen { yield 42 } | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:16:5: 16:8}` here diff --git a/tests/ui/coroutine/gen_fn.none.stderr b/tests/ui/coroutine/gen_fn.none.stderr index 590210641aed..8a5f86541316 100644 --- a/tests/ui/coroutine/gen_fn.none.stderr +++ b/tests/ui/coroutine/gen_fn.none.stderr @@ -1,8 +1,8 @@ -error: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen` +error: expected one of `#`, `async`, `const`, `default`, `extern`, `final`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen` --> $DIR/gen_fn.rs:4:1 | LL | gen fn foo() {} - | ^^^ expected one of 10 possible tokens + | ^^^ expected one of 11 possible tokens error: aborting due to 1 previous error diff --git a/tests/ui/coroutine/gen_fn.rs b/tests/ui/coroutine/gen_fn.rs index 2f50d5db9acf..78301cd2832c 100644 --- a/tests/ui/coroutine/gen_fn.rs +++ b/tests/ui/coroutine/gen_fn.rs @@ -2,7 +2,7 @@ //@[e2024] edition: 2024 gen fn foo() {} -//[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen` +//[none]~^ ERROR: expected one of `#`, `async`, `const`, `default`, `extern`, `final`, `fn`, `pub`, `safe`, `unsafe`, or `use`, found `gen` //[e2024]~^^ ERROR: gen blocks are experimental fn main() {} diff --git a/tests/ui/coroutine/issue-105084.rs b/tests/ui/coroutine/issue-105084.rs index cddee4990175..9dd3df5ce341 100644 --- a/tests/ui/coroutine/issue-105084.rs +++ b/tests/ui/coroutine/issue-105084.rs @@ -15,11 +15,11 @@ fn main() { let mut g = #[coroutine] || { // This is desuraged as 4 stages: - // - allocate a `*mut u8` with `exchange_malloc`; - // - create a Box that is ignored for trait computations; + // - `vec!` macro + // - `write_via_move` // - compute fields (and yields); // - assign to `t`. - let t = std::boxed::box_new((5, yield)); + let t = vec![(5, yield)]; drop(t); }; @@ -30,13 +30,12 @@ fn main() { // As it is not taken into account for trait computation, // the coroutine is `Copy`. let mut h = copy(g); - //~^ ERROR the trait bound `Box<(i32, ())>: Copy` is not satisfied in + //~^ ERROR the trait bound `Box>: Copy` is not satisfied in // We now have 2 boxes with the same backing allocation: // one inside `g` and one inside `h`. // Proceed and drop `t` in `g`. Pin::new(&mut g).resume(()); - //~^ ERROR borrow of moved value: `g` // Proceed and drop `t` in `h` -> double free! Pin::new(&mut h).resume(()); diff --git a/tests/ui/coroutine/issue-105084.stderr b/tests/ui/coroutine/issue-105084.stderr index 23c1fdc54592..208636bfa6a8 100644 --- a/tests/ui/coroutine/issue-105084.stderr +++ b/tests/ui/coroutine/issue-105084.stderr @@ -1,51 +1,26 @@ -error[E0382]: borrow of moved value: `g` - --> $DIR/issue-105084.rs:38:14 - | -LL | let mut g = #[coroutine] - | ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, which does not implement the `Copy` trait -... -LL | let mut h = copy(g); - | - value moved here -... -LL | Pin::new(&mut g).resume(()); - | ^^^^^^ value borrowed here after move - | -note: consider changing this parameter type in function `copy` to borrow instead if owning the value isn't necessary - --> $DIR/issue-105084.rs:10:21 - | -LL | fn copy(x: T) -> T { - | ---- ^ this parameter takes ownership of the value - | | - | in this function -help: consider cloning the value if the performance cost is acceptable - | -LL | let mut h = copy(g.clone()); - | ++++++++ - -error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}` +error[E0277]: the trait bound `Box>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}` --> $DIR/issue-105084.rs:32:17 | LL | || { | -- within this `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}` ... LL | let mut h = copy(g); - | ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>` + | ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box>` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/issue-105084.rs:22:41 + --> $DIR/issue-105084.rs:22:26 | -LL | let t = std::boxed::box_new((5, yield)); - | ------------------------^^^^^-- - | | | - | | yield occurs here, with `std::boxed::box_new((5, yield))` maybe used later - | has type `Box<(i32, ())>` which does not implement `Copy` +LL | let t = vec![(5, yield)]; + | ---------^^^^^-- + | | | + | | yield occurs here, with the value maybe used later + | has type `Box>` which does not implement `Copy` note: required by a bound in `copy` --> $DIR/issue-105084.rs:10:12 | LL | fn copy(x: T) -> T { | ^^^^ required by this bound in `copy` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0382. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/coroutine/stalled-coroutine-obligations.rs b/tests/ui/coroutine/stalled-coroutine-obligations.rs new file mode 100644 index 000000000000..89af3c9a583c --- /dev/null +++ b/tests/ui/coroutine/stalled-coroutine-obligations.rs @@ -0,0 +1,32 @@ +//@ edition: 2021 + +// Regression tests for #137916 and #138274 +// We now check stalled coroutine obligations eagerly at the start of `mir_borrowck`. +// So these unsatisfied bounds are caught before causing ICEs. +use std::ptr::null; + +async fn a() -> Box { + Box::new(async { + //~^ ERROR: future cannot be sent between threads safely + let non_send = null::<()>(); + &non_send; + async {}.await + }) +} + + +trait Trait {} +fn foo() -> Box { todo!() } + +fn fetch() { + async { + let fut = async { + let _x = foo(); + async {}.await; + }; + let _: Box = Box::new(fut); + //~^ ERROR: future cannot be sent between threads safely + }; +} + +fn main() {} diff --git a/tests/ui/coroutine/stalled-coroutine-obligations.stderr b/tests/ui/coroutine/stalled-coroutine-obligations.stderr new file mode 100644 index 000000000000..cbf395dd6cfb --- /dev/null +++ b/tests/ui/coroutine/stalled-coroutine-obligations.stderr @@ -0,0 +1,40 @@ +error: future cannot be sent between threads safely + --> $DIR/stalled-coroutine-obligations.rs:9:5 + | +LL | / Box::new(async { +LL | | +LL | | let non_send = null::<()>(); +LL | | &non_send; +LL | | async {}.await +LL | | }) + | |______^ future created by async block is not `Send` + | + = help: within `{async block@$DIR/stalled-coroutine-obligations.rs:9:14: 9:19}`, the trait `Send` is not implemented for `*const ()` +note: future is not `Send` as this value is used across an await + --> $DIR/stalled-coroutine-obligations.rs:13:18 + | +LL | let non_send = null::<()>(); + | -------- has type `*const ()` which is not `Send` +LL | &non_send; +LL | async {}.await + | ^^^^^ await occurs here, with `non_send` maybe used later + = note: required for the cast from `Box<{async block@$DIR/stalled-coroutine-obligations.rs:9:14: 9:19}>` to `Box` + +error: future cannot be sent between threads safely + --> $DIR/stalled-coroutine-obligations.rs:27:32 + | +LL | let _: Box = Box::new(fut); + | ^^^^^^^^^^^^^ future created by async block is not `Send` + | + = help: the trait `Send` is not implemented for `dyn Trait` +note: future is not `Send` as this value is used across an await + --> $DIR/stalled-coroutine-obligations.rs:25:22 + | +LL | let _x = foo(); + | -- has type `Box` which is not `Send` +LL | async {}.await; + | ^^^^^ await occurs here, with `_x` maybe used later + = note: required for the cast from `Box<{async block@$DIR/stalled-coroutine-obligations.rs:23:19: 23:24}>` to `Box` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/coroutine/static-closure-unexpanded.rs b/tests/ui/coroutine/static-closure-unexpanded.rs index 7cf24774deda..ac7c251c8348 100644 --- a/tests/ui/coroutine/static-closure-unexpanded.rs +++ b/tests/ui/coroutine/static-closure-unexpanded.rs @@ -1,7 +1,7 @@ // Tests that static closures are not stable in the parser grammar unless the // coroutine feature is enabled. -#[cfg(any())] +#[cfg(false)] fn foo() { let _ = static || {}; //~^ ERROR coroutine syntax is experimental diff --git a/tests/ui/coroutine/uninhabited-field.rs b/tests/ui/coroutine/uninhabited-field.rs index d6ada07ce0cb..6debd89ef4a9 100644 --- a/tests/ui/coroutine/uninhabited-field.rs +++ b/tests/ui/coroutine/uninhabited-field.rs @@ -1,11 +1,10 @@ // Test that uninhabited saved local doesn't make the entire variant uninhabited. //@ run-pass #![allow(unused)] -#![feature(assert_matches)] #![feature(coroutine_trait)] #![feature(coroutines, stmt_expr_attributes)] #![feature(never_type)] -use std::assert_matches::assert_matches; +use std::assert_matches; use std::ops::Coroutine; use std::ops::CoroutineState; use std::pin::Pin; diff --git a/tests/ui/coroutine/yield-while-ref-reborrowed.stderr b/tests/ui/coroutine/yield-while-ref-reborrowed.stderr index 0b2cc92f4b4a..836360b87303 100644 --- a/tests/ui/coroutine/yield-while-ref-reborrowed.stderr +++ b/tests/ui/coroutine/yield-while-ref-reborrowed.stderr @@ -10,8 +10,6 @@ LL | println!("{}", x); | ^ second borrow occurs here LL | Pin::new(&mut b).resume(()); | ------ first borrow later used here - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/crate-loading/missing-std-tier-3.rs b/tests/ui/crate-loading/missing-std-tier-3.rs new file mode 100644 index 000000000000..74c7db3db0ab --- /dev/null +++ b/tests/ui/crate-loading/missing-std-tier-3.rs @@ -0,0 +1,14 @@ +// Ensure that we do not recommend rustup installing tier 3 targets. + +//@ compile-flags: --target m68k-unknown-linux-gnu +//@ needs-llvm-components: m68k +//@ rustc-env:CARGO_CRATE_NAME=foo +//@ ignore-backends: gcc +#![feature(no_core)] +#![no_core] +extern crate core; +//~^ ERROR can't find crate for `core` +//~| NOTE can't find crate +//~| NOTE target may not be installed +//~| HELP consider building the standard library from source with `cargo build -Zbuild-std` +fn main() {} diff --git a/tests/ui/crate-loading/missing-std-tier-3.stderr b/tests/ui/crate-loading/missing-std-tier-3.stderr new file mode 100644 index 000000000000..197feeccd9c5 --- /dev/null +++ b/tests/ui/crate-loading/missing-std-tier-3.stderr @@ -0,0 +1,12 @@ +error[E0463]: can't find crate for `core` + --> $DIR/missing-std-tier-3.rs:9:1 + | +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ can't find crate + | + = note: the `m68k-unknown-linux-gnu` target may not be installed + = help: consider building the standard library from source with `cargo build -Zbuild-std` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0463`. diff --git a/tests/ui/issues/auxiliary/issue-12660-aux.rs b/tests/ui/cross-crate/auxiliary/aux-12660.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-12660-aux.rs rename to tests/ui/cross-crate/auxiliary/aux-12660.rs diff --git a/tests/ui/cross-crate/cross-crate-unit-struct-reexport.rs b/tests/ui/cross-crate/cross-crate-unit-struct-reexport.rs new file mode 100644 index 000000000000..2d4e0c654ef3 --- /dev/null +++ b/tests/ui/cross-crate/cross-crate-unit-struct-reexport.rs @@ -0,0 +1,13 @@ +//@ run-pass +//@ aux-build:aux-12660.rs + + +extern crate issue12660aux; + +use issue12660aux::{my_fn, MyStruct}; + +#[allow(path_statements)] +fn main() { + my_fn(MyStruct); + MyStruct; +} diff --git a/tests/ui/delegation/auxiliary/recursive-delegation-aux.rs b/tests/ui/delegation/auxiliary/recursive-delegation-aux.rs new file mode 100644 index 000000000000..5df644974f3e --- /dev/null +++ b/tests/ui/delegation/auxiliary/recursive-delegation-aux.rs @@ -0,0 +1,7 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +fn foo() {} + +reuse foo as bar; +pub reuse bar as goo; diff --git a/tests/ui/delegation/bad-resolve.rs b/tests/ui/delegation/bad-resolve.rs index 861f2b15da20..79acaec021a6 100644 --- a/tests/ui/delegation/bad-resolve.rs +++ b/tests/ui/delegation/bad-resolve.rs @@ -40,7 +40,7 @@ impl Trait for S { } mod prefix {} -reuse unresolved_prefix::{a, b, c}; //~ ERROR use of unresolved module or unlinked crate +reuse unresolved_prefix::{a, b, c}; //~ ERROR cannot find module or crate `unresolved_prefix` reuse prefix::{self, super, crate}; //~ ERROR `crate` in paths can only be used in start position fn main() {} diff --git a/tests/ui/delegation/bad-resolve.stderr b/tests/ui/delegation/bad-resolve.stderr index fc6811292a6f..6fde0bb13877 100644 --- a/tests/ui/delegation/bad-resolve.stderr +++ b/tests/ui/delegation/bad-resolve.stderr @@ -53,7 +53,13 @@ LL | fn bar() {} | -------- similarly named associated function `bar` defined here ... LL | reuse ::baz; - | ^^^ help: an associated function with a similar name exists: `bar` + | ^^^ + | +help: an associated function with a similar name exists + | +LL - reuse ::baz; +LL + reuse ::bar; + | error[E0425]: cannot find function `foo` in this scope --> $DIR/bad-resolve.rs:35:11 @@ -68,7 +74,13 @@ LL | fn foo(&self, x: i32) -> i32 { x } | ---------------------------- similarly named associated function `foo` defined here ... LL | reuse Trait::foo2 { self.0 } - | ^^^^ help: an associated function with a similar name exists: `foo` + | ^^^^ + | +help: an associated function with a similar name exists + | +LL - reuse Trait::foo2 { self.0 } +LL + reuse Trait::foo { self.0 } + | error[E0046]: not all trait items implemented, missing: `Type` --> $DIR/bad-resolve.rs:22:1 @@ -79,7 +91,7 @@ LL | type Type; LL | impl Trait for S { | ^^^^^^^^^^^^^^^^ missing `Type` in implementation -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `unresolved_prefix` +error[E0433]: cannot find module or crate `unresolved_prefix` in this scope --> $DIR/bad-resolve.rs:43:7 | LL | reuse unresolved_prefix::{a, b, c}; @@ -87,11 +99,11 @@ LL | reuse unresolved_prefix::{a, b, c}; | = help: you might be missing a crate named `unresolved_prefix` -error[E0433]: failed to resolve: `crate` in paths can only be used in start position +error[E0433]: `crate` in paths can only be used in start position --> $DIR/bad-resolve.rs:44:29 | LL | reuse prefix::{self, super, crate}; - | ^^^^^ `crate` in paths can only be used in start position + | ^^^^^ can only be used in path start position error: aborting due to 12 previous errors diff --git a/tests/ui/delegation/glob-bad-path.rs b/tests/ui/delegation/glob-bad-path.rs index 4ac9d68e8dd1..067cb651777e 100644 --- a/tests/ui/delegation/glob-bad-path.rs +++ b/tests/ui/delegation/glob-bad-path.rs @@ -5,7 +5,7 @@ trait Trait {} struct S; impl Trait for u8 { - reuse unresolved::*; //~ ERROR failed to resolve: use of unresolved module or unlinked crate `unresolved` + reuse unresolved::*; //~ ERROR cannot find module or crate `unresolved` reuse S::*; //~ ERROR expected trait, found struct `S` } diff --git a/tests/ui/delegation/glob-bad-path.stderr b/tests/ui/delegation/glob-bad-path.stderr index 15d9ca412033..7e92bc045bbd 100644 --- a/tests/ui/delegation/glob-bad-path.stderr +++ b/tests/ui/delegation/glob-bad-path.stderr @@ -4,7 +4,7 @@ error: expected trait, found struct `S` LL | reuse S::*; | ^ not a trait -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `unresolved` +error[E0433]: cannot find module or crate `unresolved` in this scope --> $DIR/glob-bad-path.rs:8:11 | LL | reuse unresolved::*; diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs index 3e0a5b36ddcf..6bf3a08ba5b4 100644 --- a/tests/ui/delegation/ice-issue-124347.rs +++ b/tests/ui/delegation/ice-issue-124347.rs @@ -1,12 +1,12 @@ #![feature(fn_delegation)] #![allow(incomplete_features)] -// FIXME(fn_delegation): `recursive delegation` error should be emitted here trait Trait { reuse Trait::foo { &self.0 } + //~^ ERROR failed to resolve delegation callee } reuse foo; -//~^ ERROR cycle detected when computing generics of `foo` +//~^ ERROR failed to resolve delegation callee fn main() {} diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr index 2955c0442034..40be6be4abfa 100644 --- a/tests/ui/delegation/ice-issue-124347.stderr +++ b/tests/ui/delegation/ice-issue-124347.stderr @@ -1,17 +1,14 @@ -error[E0391]: cycle detected when computing generics of `foo` +error: failed to resolve delegation callee + --> $DIR/ice-issue-124347.rs:5:18 + | +LL | reuse Trait::foo { &self.0 } + | ^^^ + +error: failed to resolve delegation callee --> $DIR/ice-issue-124347.rs:9:7 | LL | reuse foo; | ^^^ - | - = note: ...which immediately requires computing generics of `foo` again -note: cycle used when checking that `foo` is well-formed - --> $DIR/ice-issue-124347.rs:9:7 - | -LL | reuse foo; - | ^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/delegation/ice-issue-150673.rs b/tests/ui/delegation/ice-issue-150673.rs new file mode 100644 index 000000000000..7f041d3ce257 --- /dev/null +++ b/tests/ui/delegation/ice-issue-150673.rs @@ -0,0 +1,21 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod to_reuse { + pub fn foo() -> T { + unimplemented!() + } +} + +struct S(T); + +trait Trait { + reuse to_reuse::foo; +} + +impl Trait for S { +//~^ ERROR: missing generics for struct `S` + reuse Trait::foo; +} + +fn main() {} diff --git a/tests/ui/delegation/ice-issue-150673.stderr b/tests/ui/delegation/ice-issue-150673.stderr new file mode 100644 index 000000000000..fc817b07770e --- /dev/null +++ b/tests/ui/delegation/ice-issue-150673.stderr @@ -0,0 +1,19 @@ +error[E0107]: missing generics for struct `S` + --> $DIR/ice-issue-150673.rs:16:16 + | +LL | impl Trait for S { + | ^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `T` + --> $DIR/ice-issue-150673.rs:10:8 + | +LL | struct S(T); + | ^ - +help: add missing generic argument + | +LL | impl Trait for S { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.rs b/tests/ui/delegation/ice-line-bounds-issue-148732.rs index e44c78476021..699e7d86f258 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.rs +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.rs @@ -3,7 +3,6 @@ reuse a as b { //~| ERROR functions delegation is not yet fully implemented dbg!(b); //~^ ERROR missing lifetime specifier - //~| ERROR `fn() {b}` doesn't implement `Debug` } fn main() {} diff --git a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr index 1f43ec335448..c4f261181b10 100644 --- a/tests/ui/delegation/ice-line-bounds-issue-148732.stderr +++ b/tests/ui/delegation/ice-line-bounds-issue-148732.stderr @@ -3,9 +3,6 @@ error[E0106]: missing lifetime specifier | LL | dbg!(b); | ^^^^^^^ expected named lifetime parameter - | - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) - | error[E0425]: cannot find function `a` in this scope --> $DIR/ice-line-bounds-issue-148732.rs:1:7 @@ -20,7 +17,7 @@ LL | / reuse a as b { LL | | LL | | LL | | dbg!(b); -... | +LL | | LL | | } | |_^ | @@ -28,19 +25,7 @@ LL | | } = help: add `#![feature(fn_delegation)]` 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[E0277]: `fn() {b}` doesn't implement `Debug` - --> $DIR/ice-line-bounds-issue-148732.rs:4:5 - | -LL | reuse a as b { - | - consider calling this function -... -LL | dbg!(b); - | ^^^^^^^ the trait `Debug` is not implemented for fn item `fn() {b}` - | - = help: use parentheses to call this function: `b()` - = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) +error: aborting due to 3 previous errors -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0106, E0277, E0425, E0658. +Some errors have detailed explanations: E0106, E0425, E0658. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/delegation/impl-reuse-bad-path.rs b/tests/ui/delegation/impl-reuse-bad-path.rs new file mode 100644 index 000000000000..656be5d79d9b --- /dev/null +++ b/tests/ui/delegation/impl-reuse-bad-path.rs @@ -0,0 +1,31 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +mod unresolved { + struct S; + reuse impl unresolved for S { self.0 } + //~^ ERROR cannot find module or crate `unresolved` in this scope + //~| ERROR cannot find trait `unresolved` in this scope + + trait T {} + reuse impl T for unresolved { self.0 } + //~^ ERROR empty glob delegation is not supported + //~| ERROR cannot find type `unresolved` in this scope +} + +mod wrong_entities { + trait T {} + struct Trait; + struct S; + + reuse impl Trait for S { self.0 } + //~^ ERROR expected trait, found struct `Trait` + //~| ERROR expected trait, found struct `Trait` + + mod TraitModule {} + reuse impl TraitModule for S { self.0 } + //~^ ERROR expected trait, found module `TraitModule` + //~| ERROR expected trait, found module `TraitModule` +} + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-bad-path.stderr b/tests/ui/delegation/impl-reuse-bad-path.stderr new file mode 100644 index 000000000000..bf486260c669 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-bad-path.stderr @@ -0,0 +1,52 @@ +error: empty glob delegation is not supported + --> $DIR/impl-reuse-bad-path.rs:11:5 + | +LL | reuse impl T for unresolved { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected trait, found struct `Trait` + --> $DIR/impl-reuse-bad-path.rs:21:16 + | +LL | reuse impl Trait for S { self.0 } + | ^^^^^ not a trait + +error: expected trait, found module `TraitModule` + --> $DIR/impl-reuse-bad-path.rs:26:16 + | +LL | reuse impl TraitModule for S { self.0 } + | ^^^^^^^^^^^ not a trait + +error[E0433]: cannot find module or crate `unresolved` in this scope + --> $DIR/impl-reuse-bad-path.rs:6:16 + | +LL | reuse impl unresolved for S { self.0 } + | ^^^^^^^^^^ use of unresolved module or unlinked crate `unresolved` + +error[E0405]: cannot find trait `unresolved` in this scope + --> $DIR/impl-reuse-bad-path.rs:6:16 + | +LL | reuse impl unresolved for S { self.0 } + | ^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find type `unresolved` in this scope + --> $DIR/impl-reuse-bad-path.rs:11:22 + | +LL | reuse impl T for unresolved { self.0 } + | ^^^^^^^^^^ not found in this scope + +error[E0404]: expected trait, found struct `Trait` + --> $DIR/impl-reuse-bad-path.rs:21:16 + | +LL | reuse impl Trait for S { self.0 } + | ^^^^^ not a trait + +error[E0404]: expected trait, found module `TraitModule` + --> $DIR/impl-reuse-bad-path.rs:26:16 + | +LL | reuse impl TraitModule for S { self.0 } + | ^^^^^^^^^^^ not a trait + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0404, E0405, E0425, E0433. +For more information about an error, try `rustc --explain E0404`. diff --git a/tests/ui/delegation/impl-reuse-empty-glob.rs b/tests/ui/delegation/impl-reuse-empty-glob.rs new file mode 100644 index 000000000000..3f1314c47da6 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-empty-glob.rs @@ -0,0 +1,14 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +mod empty_glob { + trait T {} + + struct S; + + reuse impl T for S { self.0 } + //~^ ERROR empty glob delegation is not supported +} + + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-empty-glob.stderr b/tests/ui/delegation/impl-reuse-empty-glob.stderr new file mode 100644 index 000000000000..bf6bb5876351 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-empty-glob.stderr @@ -0,0 +1,8 @@ +error: empty glob delegation is not supported + --> $DIR/impl-reuse-empty-glob.rs:9:5 + | +LL | reuse impl T for S { self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/impl-reuse-illegal-places.rs b/tests/ui/delegation/impl-reuse-illegal-places.rs new file mode 100644 index 000000000000..361331d41315 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-illegal-places.rs @@ -0,0 +1,51 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +trait T { + fn f(&self) {} +} + +struct S; +impl T for S {} + +struct F(S); + +struct X { + reuse impl T for F { self.0 } + //~^ ERROR expected `:`, found keyword `impl` +} + +impl X { + reuse impl T for F { self.0 } + //~^ ERROR implementation is not supported in `trait`s or `impl`s +} + +trait Trait { + reuse impl T for F { self.0 } + //~^ ERROR implementation is not supported in `trait`s or `impl`s +} + +extern "C" { + reuse impl T for F { self.0 } + //~^ ERROR implementation is not supported in `extern` blocks +} + +mod m { + mod inner { + pub fn foo() {} + } + + reuse inner::{ + reuse impl T for F { self.0 } + //~^ ERROR expected identifier, found keyword `impl` + //~| ERROR expected one of `,`, `as`, or `}`, found keyword `impl` + //~| ERROR expected one of `,`, `as`, or `}`, found `T` + //~| ERROR expected identifier, found keyword `for` + //~| ERROR expected one of `,`, `as`, or `}`, found keyword `for` + //~| ERROR expected one of `,`, `as`, or `}`, found `F` + //~| ERROR expected one of `,`, `as`, or `}`, found `{` + } +} +//~^ ERROR expected item, found `}` + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-illegal-places.stderr b/tests/ui/delegation/impl-reuse-illegal-places.stderr new file mode 100644 index 000000000000..fb17ebdd6cee --- /dev/null +++ b/tests/ui/delegation/impl-reuse-illegal-places.stderr @@ -0,0 +1,92 @@ +error: expected `:`, found keyword `impl` + --> $DIR/impl-reuse-illegal-places.rs:14:11 + | +LL | struct X { + | - while parsing this struct +LL | reuse impl T for F { self.0 } + | ^^^^ expected `:` + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/impl-reuse-illegal-places.rs:19:5 + | +LL | reuse impl T for F { self.0 } + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: implementation is not supported in `trait`s or `impl`s + --> $DIR/impl-reuse-illegal-places.rs:24:5 + | +LL | reuse impl T for F { self.0 } + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: implementation is not supported in `extern` blocks + --> $DIR/impl-reuse-illegal-places.rs:29:5 + | +LL | reuse impl T for F { self.0 } + | ^^^^^^^^^^^^^^^^^^ + | + = help: consider moving the implementation out to a nearby module scope + +error: expected identifier, found keyword `impl` + --> $DIR/impl-reuse-illegal-places.rs:39:15 + | +LL | reuse impl T for F { self.0 } + | ^^^^ expected identifier, found keyword + +error: expected one of `,`, `as`, or `}`, found keyword `impl` + --> $DIR/impl-reuse-illegal-places.rs:39:15 + | +LL | reuse impl T for F { self.0 } + | -^^^^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected one of `,`, `as`, or `}`, found `T` + --> $DIR/impl-reuse-illegal-places.rs:39:20 + | +LL | reuse impl T for F { self.0 } + | -^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected identifier, found keyword `for` + --> $DIR/impl-reuse-illegal-places.rs:39:22 + | +LL | reuse impl T for F { self.0 } + | ^^^ expected identifier, found keyword + +error: expected one of `,`, `as`, or `}`, found keyword `for` + --> $DIR/impl-reuse-illegal-places.rs:39:22 + | +LL | reuse impl T for F { self.0 } + | -^^^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected one of `,`, `as`, or `}`, found `F` + --> $DIR/impl-reuse-illegal-places.rs:39:26 + | +LL | reuse impl T for F { self.0 } + | -^ expected one of `,`, `as`, or `}` + | | + | help: missing `,` + +error: expected one of `,`, `as`, or `}`, found `{` + --> $DIR/impl-reuse-illegal-places.rs:39:28 + | +LL | reuse impl T for F { self.0 } + | ^ expected one of `,`, `as`, or `}` + +error: expected item, found `}` + --> $DIR/impl-reuse-illegal-places.rs:48:1 + | +LL | } + | ^ expected item + | + = note: for a full list of items that can appear in modules, see + +error: aborting due to 12 previous errors + diff --git a/tests/ui/delegation/impl-reuse-negative-traits.rs b/tests/ui/delegation/impl-reuse-negative-traits.rs new file mode 100644 index 000000000000..7bcbc82f03db --- /dev/null +++ b/tests/ui/delegation/impl-reuse-negative-traits.rs @@ -0,0 +1,19 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] +#![feature(negative_impls)] + +trait Trait { + fn foo(&self); + //~^ ERROR negative impls cannot have any items [E0749] +} + +struct S; +impl Trait for S { + fn foo(&self) {} +} + +struct F(S); + +reuse impl !Trait for F { &self.0 } + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-negative-traits.stderr b/tests/ui/delegation/impl-reuse-negative-traits.stderr new file mode 100644 index 000000000000..1be6ef715920 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-negative-traits.stderr @@ -0,0 +1,9 @@ +error[E0749]: negative impls cannot have any items + --> $DIR/impl-reuse-negative-traits.rs:6:8 + | +LL | fn foo(&self); + | ^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0749`. diff --git a/tests/ui/delegation/impl-reuse-non-reuse-items.rs b/tests/ui/delegation/impl-reuse-non-reuse-items.rs new file mode 100644 index 000000000000..de7c92279218 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-reuse-items.rs @@ -0,0 +1,32 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +mod non_delegatable_items { + trait Trait { + fn method(&self); + const CONST: u8; + type Type; + #[allow(non_camel_case_types)] + type method; + } + + struct F; + impl Trait for F { + fn method(&self) {} + const CONST: u8 = 0; + type Type = u8; + type method = u8; + } + + struct S(F); + + reuse impl Trait for S { &self.0 } + //~^ ERROR item `CONST` is an associated method, which doesn't match its trait `Trait` + //~| ERROR item `Type` is an associated method, which doesn't match its trait `Trait` + //~| ERROR duplicate definitions with name `method` + //~| ERROR expected function, found associated constant `Trait::CONST` + //~| ERROR expected function, found associated type `Trait::Type` + //~| ERROR not all trait items implemented, missing: `CONST`, `Type`, `method` +} + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-non-reuse-items.stderr b/tests/ui/delegation/impl-reuse-non-reuse-items.stderr new file mode 100644 index 000000000000..9d6b0f638136 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-reuse-items.stderr @@ -0,0 +1,60 @@ +error[E0324]: item `CONST` is an associated method, which doesn't match its trait `Trait` + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | const CONST: u8; + | ---------------- item in trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error[E0324]: item `Type` is an associated method, which doesn't match its trait `Trait` + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | type Type; + | ---------- item in trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error[E0201]: duplicate definitions with name `method`: + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | fn method(&self); + | ----------------- item in trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | duplicate definition + | previous definition here + +error[E0423]: expected function, found associated constant `Trait::CONST` + --> $DIR/impl-reuse-non-reuse-items.rs:23:16 + | +LL | reuse impl Trait for S { &self.0 } + | ^^^^^ not a function + +error[E0423]: expected function, found associated type `Trait::Type` + --> $DIR/impl-reuse-non-reuse-items.rs:23:16 + | +LL | reuse impl Trait for S { &self.0 } + | ^^^^^ not a function + +error[E0046]: not all trait items implemented, missing: `CONST`, `Type`, `method` + --> $DIR/impl-reuse-non-reuse-items.rs:23:5 + | +LL | const CONST: u8; + | --------------- `CONST` from trait +LL | type Type; + | --------- `Type` from trait +LL | #[allow(non_camel_case_types)] +LL | type method; + | ----------- `method` from trait +... +LL | reuse impl Trait for S { &self.0 } + | ^^^^^^^^^^^^^^^^^^^^^^ missing `CONST`, `Type`, `method` in implementation + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0046, E0201, E0324, E0423. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.rs b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.rs new file mode 100644 index 000000000000..51ef1dc14ba8 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.rs @@ -0,0 +1,10 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +struct Trait(usize); + +#[cfg(false)] +reuse impl Trait { self.0 } +//~^ ERROR only trait impls can be reused + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.stderr b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.stderr new file mode 100644 index 000000000000..24a138016116 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl-cfg-false.stderr @@ -0,0 +1,8 @@ +error: only trait impls can be reused + --> $DIR/impl-reuse-non-trait-impl-cfg-false.rs:7:1 + | +LL | reuse impl Trait { self.0 } + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl.rs b/tests/ui/delegation/impl-reuse-non-trait-impl.rs new file mode 100644 index 000000000000..c7a9813250db --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl.rs @@ -0,0 +1,9 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +struct Trait(usize); + +reuse impl Trait { self.0 } +//~^ ERROR only trait impls can be reused + +fn main() {} diff --git a/tests/ui/delegation/impl-reuse-non-trait-impl.stderr b/tests/ui/delegation/impl-reuse-non-trait-impl.stderr new file mode 100644 index 000000000000..3987042104c3 --- /dev/null +++ b/tests/ui/delegation/impl-reuse-non-trait-impl.stderr @@ -0,0 +1,8 @@ +error: only trait impls can be reused + --> $DIR/impl-reuse-non-trait-impl.rs:6:1 + | +LL | reuse impl Trait { self.0 } + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/impl-reuse-pass.rs b/tests/ui/delegation/impl-reuse-pass.rs new file mode 100644 index 000000000000..90060b03f9ef --- /dev/null +++ b/tests/ui/delegation/impl-reuse-pass.rs @@ -0,0 +1,292 @@ +//@ check-pass + +#![allow(incomplete_features)] +#![feature(fn_delegation)] +#![feature(const_trait_impl)] +#![allow(warnings)] + +mod default { + trait T { + fn foo(&self) {} + fn bar(&self) {} + fn goo(&self) {} + } + + struct S; + impl T for S {} + + struct F(S); + reuse impl T for F { self.0 } + + fn f() { + let f = F(S{}); + + f.foo(); + f.bar(); + f.goo(); + } +} + +mod dyn_traits { + trait T { + fn foo(&self) -> Box; + } + + trait SecondTrait { + fn bar(&self); + } + + reuse impl SecondTrait for dyn T { self.foo().as_ref() } +} + +mod complex_path { + pub mod first { + pub mod second { + pub trait T { + fn foo(&self, x: usize); + } + } + } + + struct S; + impl first::second::T for S { + fn foo(&self, x: usize) { } + } + + struct F(S); + reuse impl first::second::T for F { self.0 } + + fn f() { + use complex_path::first::second::T; + + let f = F(S{}); + + f.foo(1); + } +} + +mod no_body_reuse { + trait T { + fn foo(&self) {} + fn bar(&mut self) {} + } + + struct F; + + reuse impl T for F; + + fn foo() { + let mut f = F{}; + + f.foo(); + f.bar(); + } +} + +mod unsafe_trait { + unsafe trait UnsafeTrait { + fn foo(&self) {} + fn bar(&self) {} + fn goo(&self) {} + } + + struct S; + unsafe impl UnsafeTrait for S {} + + struct F(S); + reuse unsafe impl UnsafeTrait for F { self.0 } + + fn f() { + let f = F(S{}); + + f.foo(); + f.bar(); + f.goo(); + } +} + +mod const_trait { + const trait ConstTrait { + fn foo(&self) -> usize { 0 } + fn bar(&self) -> usize { 1 } + } + + struct S; + const impl ConstTrait for S {} + + struct F(S); + reuse const impl ConstTrait for F { self.0 } + + fn f() { + let f = F(S{}); + + f.foo(); + f.bar(); + } +} + +mod different_selves { + trait T: Sized { + fn foo(&self) {} + fn boo(self) {} + fn goo(&mut self) {} + } + + struct S; + impl T for S {} + + struct F(S); + reuse impl T for F { self.0 } + + struct D(S); + macro_rules! self_0 { ($self:ident) => { $self.0 } } + + reuse impl T for D { self_0!(self) } + + fn f() { + let mut f = F(S{}); + f.foo(); + f.goo(); + f.boo(); + + let mut d = D(S{}); + d.foo(); + d.goo(); + d.boo(); + } +} + +mod macros { + trait Trait { + fn foo(&self) -> u8 { 0 } + fn bar(&self) -> u8 { 1 } + } + + impl Trait for u8 {} + struct S(u8); + + macro_rules! self_0_ref { ($self:ident) => { &$self.0 } } + + reuse impl Trait for S { self_0_ref!(self) } + + struct M(u8); + macro_rules! m { () => { M } } + reuse impl Trait for m!() { self_0_ref!(self) } + + struct S1(u8); + macro_rules! one_line_reuse { ($self:ident) => { reuse impl Trait for S1 { $self.0 } } } + one_line_reuse!(self); + + struct S2(u8); + macro_rules! one_line_reuse_expr { ($x:expr) => { reuse impl Trait for S2 { $x } } } + one_line_reuse_expr!(self.0); + + struct S3(u8); + macro_rules! s3 { () => { S3 } } + macro_rules! one_line_reuse_expr2 { ($x:expr) => { reuse impl Trait for s3!() { $x } } } + one_line_reuse_expr2!(self.0); + + fn f() { + let s = S(1); + s.foo(); + s.bar(); + + let m = M(41); + m.foo(); + m.bar(); + + let s1 = S1(2); + s1.foo(); + s1.bar(); + + let s2 = S2(4); + s2.foo(); + s2.bar(); + + let s3 = S3(5); + s3.foo(); + s3.bar(); + } +} + +mod generics { + trait Trait<'a, 'b, A, B, C> { + fn foo(&self, a: &A) {} + fn bar(&self, b: &B) {} + fn goo(&self, c: &C) {} + } + + struct S; + impl<'a, 'b, A, B, C> Trait<'a, 'b, A, B, C> for S {} + + struct F(S); + reuse impl<'a, 'b, A, B, C> Trait<'a, 'b, A, B, C> for F { &self.0 } + + struct S1; + struct F1(S1); + impl<'c, B> Trait<'static, 'c, usize, B, String> for S1 {} + reuse impl<'d, B> Trait<'static, 'd, usize, B, String> for F1 { &self.0 } + + struct S2; + struct F2(S2); + impl Trait<'static, 'static, u8, u16, u32> for S2 {} + reuse impl Trait<'static, 'static, u8, u16, u32> for F2 { &self.0 } + + fn f<'a, 'b, 'c, A, B, C>(a: A, b: B, c: C) { + let f = F(S{}); + + >::foo(&f, &a); + >::bar(&f, &b); + >::goo(&f, &c); + + let f = F1(S1{}); + >::foo(&f, &123); + >::bar(&f, &b); + >::goo(&f, &"s".to_string()); + + let f = F2(S2{}); + >::foo(&f, &1); + >::bar(&f, &2); + >::goo(&f, &3); + } +} + +mod reuse_in_different_places { + trait T { + fn foo(&self, x: usize) {} + } + + struct S; + impl T for S {} + + struct F1(S); + reuse impl T for F1 { + struct F2(S, S, S); + reuse impl T for F2 { self.1 } + + let f2 = F2(S{}, S{}, S{}); + f2.foo(123); + + &self.0 + } + + fn foo() { + struct F(S); + reuse impl T for F { self.0 } + + let f = F(S{}); + f.foo(1); + } + + fn bar() { + || { + struct F(S); + reuse impl T for F { self.0 } + + let f = F(S{}); + f.foo(1); + }; + } +} + +fn main() {} diff --git a/tests/ui/delegation/recursive-delegation-errors.rs b/tests/ui/delegation/recursive-delegation-errors.rs new file mode 100644 index 000000000000..194182e20ed0 --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-errors.rs @@ -0,0 +1,54 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + + +mod first_mod { + reuse foo; + //~^ ERROR failed to resolve delegation callee +} + +mod second_mod { + reuse foo as bar; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse bar as foo; + //~^ ERROR encountered a cycle during delegation signature resolution +} + +mod third_mod { + reuse foo as foo1; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo1 as foo2; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo2 as foo3; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo3 as foo4; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo4 as foo5; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse foo5 as foo; + //~^ ERROR encountered a cycle during delegation signature resolution +} + +mod fourth_mod { + trait Trait { + reuse Trait::foo as bar; + //~^ ERROR encountered a cycle during delegation signature resolution + reuse Trait::bar as foo; + //~^ ERROR encountered a cycle during delegation signature resolution + } +} + +mod fifth_mod { + reuse super::fifth_mod::{bar as foo, foo as bar}; + //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR encountered a cycle during delegation signature resolution + + trait GlobReuse { + reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + //~^ ERROR encountered a cycle during delegation signature resolution + //~| ERROR encountered a cycle during delegation signature resolution + //~| ERROR encountered a cycle during delegation signature resolution + } +} + +fn main() {} diff --git a/tests/ui/delegation/recursive-delegation-errors.stderr b/tests/ui/delegation/recursive-delegation-errors.stderr new file mode 100644 index 000000000000..9c4e316745ae --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-errors.stderr @@ -0,0 +1,98 @@ +error: failed to resolve delegation callee + --> $DIR/recursive-delegation-errors.rs:6:11 + | +LL | reuse foo; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:11:11 + | +LL | reuse foo as bar; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:13:11 + | +LL | reuse bar as foo; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:18:11 + | +LL | reuse foo as foo1; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:20:11 + | +LL | reuse foo1 as foo2; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:22:11 + | +LL | reuse foo2 as foo3; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:24:11 + | +LL | reuse foo3 as foo4; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:26:11 + | +LL | reuse foo4 as foo5; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:28:11 + | +LL | reuse foo5 as foo; + | ^^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:34:22 + | +LL | reuse Trait::foo as bar; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:36:22 + | +LL | reuse Trait::bar as foo; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:42:30 + | +LL | reuse super::fifth_mod::{bar as foo, foo as bar}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:42:42 + | +LL | reuse super::fifth_mod::{bar as foo, foo as bar}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:47:27 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:47:39 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ + +error: encountered a cycle during delegation signature resolution + --> $DIR/recursive-delegation-errors.rs:47:51 + | +LL | reuse GlobReuse::{foo as bar, bar as goo, goo as foo}; + | ^^^ + +error: aborting due to 16 previous errors + diff --git a/tests/ui/delegation/recursive-delegation-ice-150152.rs b/tests/ui/delegation/recursive-delegation-ice-150152.rs new file mode 100644 index 000000000000..565563c9d03d --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-ice-150152.rs @@ -0,0 +1,31 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod first_example { + mod to_reuse { pub fn foo() {} } + struct S< S >; + //~^ ERROR type parameter `S` is never used + + impl Item for S { + //~^ ERROR cannot find trait `Item` in this scope + //~| ERROR missing generics for struct `S` + reuse to_reuse::foo; + } +} + +mod second_example { + trait Trait { + reuse to_reuse::foo; + //~^ ERROR function `foo` is private + } + mod to_reuse { + fn foo() {} + } + impl Trait for S { + //~^ ERROR cannot find type `S` in this scope + reuse foo; + //~^ ERROR cannot find function `foo` in this scope + } +} + +fn main() {} diff --git a/tests/ui/delegation/recursive-delegation-ice-150152.stderr b/tests/ui/delegation/recursive-delegation-ice-150152.stderr new file mode 100644 index 000000000000..c58f0ff09291 --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-ice-150152.stderr @@ -0,0 +1,74 @@ +error[E0405]: cannot find trait `Item` in this scope + --> $DIR/recursive-delegation-ice-150152.rs:9:10 + | +LL | impl Item for S { + | ^^^^ not found in this scope + +error[E0425]: cannot find type `S` in this scope + --> $DIR/recursive-delegation-ice-150152.rs:24:20 + | +LL | impl Trait for S { + | ^ not found in this scope + | +note: struct `first_example::S` exists but is inaccessible + --> $DIR/recursive-delegation-ice-150152.rs:6:5 + | +LL | struct S< S >; + | ^^^^^^^^^^^^^^ not accessible + +error[E0425]: cannot find function `foo` in this scope + --> $DIR/recursive-delegation-ice-150152.rs:26:15 + | +LL | reuse foo; + | ^^^ not found in this scope + | +note: these functions exist but are inaccessible + --> $DIR/recursive-delegation-ice-150152.rs:5:20 + | +LL | mod to_reuse { pub fn foo() {} } + | ^^^^^^^^^^^^ `first_example::to_reuse::foo`: not accessible +... +LL | fn foo() {} + | ^^^^^^^^ `second_example::to_reuse::foo`: not accessible + +error[E0603]: function `foo` is private + --> $DIR/recursive-delegation-ice-150152.rs:18:25 + | +LL | reuse to_reuse::foo; + | ^^^ private function + | +note: the function `foo` is defined here + --> $DIR/recursive-delegation-ice-150152.rs:22:9 + | +LL | fn foo() {} + | ^^^^^^^^ + +error[E0392]: type parameter `S` is never used + --> $DIR/recursive-delegation-ice-150152.rs:6:15 + | +LL | struct S< S >; + | ^ unused type parameter + | + = help: consider removing `S`, referring to it in a field, or using a marker such as `PhantomData` + = help: if you intended `S` to be a const parameter, use `const S: /* Type */` instead + +error[E0107]: missing generics for struct `S` + --> $DIR/recursive-delegation-ice-150152.rs:9:21 + | +LL | impl Item for S { + | ^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `S` + --> $DIR/recursive-delegation-ice-150152.rs:6:12 + | +LL | struct S< S >; + | ^ - +help: add missing generic argument + | +LL | impl Item for S> { + | +++ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0107, E0392, E0405, E0425, E0603. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/delegation/recursive-delegation-pass.rs b/tests/ui/delegation/recursive-delegation-pass.rs new file mode 100644 index 000000000000..2a40986d352a --- /dev/null +++ b/tests/ui/delegation/recursive-delegation-pass.rs @@ -0,0 +1,148 @@ +//@ run-pass +//@ edition:2018 +//@ aux-crate:recursive_delegation_aux=recursive-delegation-aux.rs + +#![feature(fn_delegation)] +#![allow(incomplete_features)] +#![allow(warnings)] + +mod first_mod { + pub mod to_reuse { + pub fn foo(x: usize) -> usize { + x + 1 + } + } + + pub mod single_reuse { + reuse crate::first_mod::to_reuse::foo { self + 1 } + reuse foo as bar { self + 1 } + reuse foo as bar1 { self + 1 } + reuse bar as goo { self + 1 } + reuse goo as koo { self + 1 } + pub reuse koo as too { self + 1 } + + pub fn check() { + assert_eq!(foo(1), 3); + assert_eq!(bar(1), 4); + assert_eq!(bar1(1), 4); + assert_eq!(goo(1), 5); + assert_eq!(koo(1), 6); + assert_eq!(too(1), 7); + } + } + + mod glob_reuse { + reuse super::to_reuse::{foo as bar, foo as bar1} { self } + reuse super::glob_reuse::{bar as goo, goo as koo, koo as too} { self } + + fn check() { + bar(1); + bar1(1); + goo(1); + koo(1); + too(1); + } + } +} + +mod second_mod { + trait T { + fn foo(&self); + reuse T::foo as bar; + reuse T::bar as goo; + reuse T::goo as poo; + } + + trait TGlob { + fn xd(&self) -> &Self; + fn foo1(&self); + fn foo2(&self); + fn foo3(&self); + fn foo4(&self); + + reuse TGlob::{foo1 as bar1, foo3 as bar3, bar1 as bar11, bar11 as bar111} { self.xd() } + } + + fn check() { + struct X; + impl T for X { + fn foo(&self) {} + fn bar(&self) {} + fn goo(&self) {} + fn poo(&self) {} + } + + impl TGlob for X { + fn xd(&self) -> &Self { &self } + fn foo1(&self) {} + fn foo2(&self) {} + fn foo3(&self) {} + fn foo4(&self) {} + + fn bar1(&self) {} + fn bar3(&self) {} + fn bar11(&self) {} + fn bar111(&self) {} + } + } +} + +mod third_mod { + reuse crate::first_mod::to_reuse::foo { + reuse foo as bar { + reuse bar as goo { + bar(123) + } + + goo(123) + } + + bar(123) + } +} + +mod fourth_mod { + reuse recursive_delegation_aux::goo as bar; + reuse bar as foo; + + fn check() { + bar(); + foo(); + } +} + +mod fifth_mod { + mod m { + fn foo() { } + pub reuse foo as bar; + } + + trait T { + reuse m::bar as foo; + } + + struct X; + impl T for X {} + + trait T1 { + reuse ::foo as baz; + } + + impl T1 for X {} + + struct Y; + impl T1 for Y { + reuse ::foo as baz; + } + + fn check() { + m::bar(); + ::foo(); + ::baz(); + ::baz(); + } +} + +fn main() { + first_mod::single_reuse::check(); +} diff --git a/tests/ui/delegation/unresolved-delegation-ice-151356.rs b/tests/ui/delegation/unresolved-delegation-ice-151356.rs new file mode 100644 index 000000000000..b61e08551183 --- /dev/null +++ b/tests/ui/delegation/unresolved-delegation-ice-151356.rs @@ -0,0 +1,11 @@ +#![allow(incomplete_features)] +#![feature(fn_delegation)] + +extern "C" { + fn a() { + //~^ ERROR incorrect function inside `extern` block + reuse foo {} + } +} + +pub fn main() {} diff --git a/tests/ui/delegation/unresolved-delegation-ice-151356.stderr b/tests/ui/delegation/unresolved-delegation-ice-151356.stderr new file mode 100644 index 000000000000..407d22e477c4 --- /dev/null +++ b/tests/ui/delegation/unresolved-delegation-ice-151356.stderr @@ -0,0 +1,19 @@ +error: incorrect function inside `extern` block + --> $DIR/unresolved-delegation-ice-151356.rs:5:8 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body +LL | fn a() { + | ________^___- + | | | + | | cannot have a body +LL | | +LL | | reuse foo {} +LL | | } + | |_____- help: remove the invalid body: `;` + | + = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 1 previous error + diff --git a/tests/ui/delegation/unsupported.current.stderr b/tests/ui/delegation/unsupported.current.stderr index 5c4115630c00..9bc2eec068fe 100644 --- a/tests/ui/delegation/unsupported.current.stderr +++ b/tests/ui/delegation/unsupported.current.stderr @@ -29,31 +29,18 @@ note: ...which requires comparing an impl and trait method signature, inferring LL | reuse ToReuse::opaque_ret; | ^^^^^^^^^^ = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle -note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition - --> $DIR/unsupported.rs:33:24 - | -LL | reuse ToReuse::opaque_ret; - | ^^^^^^^^^^ + = note: cycle used when checking effective visibilities = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: recursive delegation is not supported yet - --> $DIR/unsupported.rs:46:22 - | -LL | pub reuse to_reuse2::foo; - | --- callee defined here -... -LL | reuse to_reuse1::foo; - | ^^^ - error[E0283]: type annotations needed - --> $DIR/unsupported.rs:55:18 + --> $DIR/unsupported.rs:54:18 | LL | reuse Trait::foo; | ^^^ cannot infer type | = note: cannot satisfy `_: effects::Trait` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0283, E0391. For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/unsupported.next.stderr b/tests/ui/delegation/unsupported.next.stderr index a626da9a1442..08bc49513bad 100644 --- a/tests/ui/delegation/unsupported.next.stderr +++ b/tests/ui/delegation/unsupported.next.stderr @@ -25,27 +25,18 @@ note: ...which requires comparing an impl and trait method signature, inferring LL | reuse ToReuse::opaque_ret; | ^^^^^^^^^^ = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle - = note: cycle used when computing implied outlives bounds for `::opaque_ret::{anon_assoc#0}` (hack disabled = false) + = note: cycle used when checking effective visibilities = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: recursive delegation is not supported yet - --> $DIR/unsupported.rs:46:22 - | -LL | pub reuse to_reuse2::foo; - | --- callee defined here -... -LL | reuse to_reuse1::foo; - | ^^^ - error[E0283]: type annotations needed - --> $DIR/unsupported.rs:55:18 + --> $DIR/unsupported.rs:54:18 | LL | reuse Trait::foo; | ^^^ cannot infer type | = note: cannot satisfy `_: effects::Trait` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0283, E0391. For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index 5e2bd832a4d8..1681888e34ea 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -44,7 +44,6 @@ mod recursive { } reuse to_reuse1::foo; - //~^ ERROR recursive delegation is not supported yet } mod effects { diff --git a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr index f26b43aa3ec7..b0372051f026 100644 --- a/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr +++ b/tests/ui/dep-graph/dep-graph-assoc-type-codegen.stderr @@ -1,8 +1,8 @@ error: OK - --> $DIR/dep-graph-assoc-type-codegen.rs:29:5 + --> $DIR/dep-graph-assoc-type-codegen.rs:29:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/dep-graph/dep-graph-caller-callee.stderr b/tests/ui/dep-graph/dep-graph-caller-callee.stderr index 4d06dc7f3ed3..33fe91b3500a 100644 --- a/tests/ui/dep-graph/dep-graph-caller-callee.stderr +++ b/tests/ui/dep-graph/dep-graph-caller-callee.stderr @@ -1,14 +1,14 @@ error: OK - --> $DIR/dep-graph-caller-callee.rs:21:5 + --> $DIR/dep-graph-caller-callee.rs:21:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x` to `typeck` - --> $DIR/dep-graph-caller-callee.rs:32:5 + --> $DIR/dep-graph-caller-callee.rs:32:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/dep-graph/dep-graph-check-attr.rs b/tests/ui/dep-graph/dep-graph-check-attr.rs index a45bf24f8c1f..c0697a5316f7 100644 --- a/tests/ui/dep-graph/dep-graph-check-attr.rs +++ b/tests/ui/dep-graph/dep-graph-check-attr.rs @@ -5,15 +5,15 @@ #![allow(dead_code)] #![allow(unused_variables)] -#[rustc_clean(hir_owner)] //~ ERROR attribute requires -Z query-dep-graph +#[rustc_clean(cfg = "foo")] //~ ERROR attribute requires -Z query-dep-graph fn main() {} -#[rustc_if_this_changed(hir_owner)] //~ ERROR attribute requires -Z query-dep-graph +#[rustc_if_this_changed] //~ ERROR attribute requires -Z query-dep-graph struct Foo { f: T, } -#[rustc_clean(hir_owner)] //~ ERROR attribute requires -Z query-dep-graph +#[rustc_clean(cfg = "foo")] //~ ERROR attribute requires -Z query-dep-graph type TypeAlias = Foo; #[rustc_then_this_would_need(variances_of)] //~ ERROR attribute requires -Z query-dep-graph diff --git a/tests/ui/dep-graph/dep-graph-check-attr.stderr b/tests/ui/dep-graph/dep-graph-check-attr.stderr index 46f4e4358cf6..4b651c47ac83 100644 --- a/tests/ui/dep-graph/dep-graph-check-attr.stderr +++ b/tests/ui/dep-graph/dep-graph-check-attr.stderr @@ -1,20 +1,20 @@ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:8:1 | -LL | #[rustc_clean(hir_owner)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_clean(cfg = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:11:1 | -LL | #[rustc_if_this_changed(hir_owner)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_if_this_changed] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:16:1 | -LL | #[rustc_clean(hir_owner)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_clean(cfg = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute requires -Z query-dep-graph to be enabled --> $DIR/dep-graph-check-attr.rs:19:1 diff --git a/tests/ui/dep-graph/dep-graph-struct-signature.stderr b/tests/ui/dep-graph/dep-graph-struct-signature.stderr index cfe1e62d9318..98efedc7244c 100644 --- a/tests/ui/dep-graph/dep-graph-struct-signature.stderr +++ b/tests/ui/dep-graph/dep-graph-struct-signature.stderr @@ -1,134 +1,134 @@ error: no path from `WillChange` to `type_of` - --> $DIR/dep-graph-struct-signature.rs:28:5 + --> $DIR/dep-graph-struct-signature.rs:28:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `associated_item` - --> $DIR/dep-graph-struct-signature.rs:29:5 + --> $DIR/dep-graph-struct-signature.rs:29:34 | LL | #[rustc_then_this_would_need(associated_item)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ error: no path from `WillChange` to `trait_def` - --> $DIR/dep-graph-struct-signature.rs:30:5 + --> $DIR/dep-graph-struct-signature.rs:30:34 | LL | #[rustc_then_this_would_need(trait_def)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:36:5 + --> $DIR/dep-graph-struct-signature.rs:36:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:37:5 + --> $DIR/dep-graph-struct-signature.rs:37:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:40:5 + --> $DIR/dep-graph-struct-signature.rs:40:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:41:5 + --> $DIR/dep-graph-struct-signature.rs:41:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:46:5 + --> $DIR/dep-graph-struct-signature.rs:46:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:53:5 + --> $DIR/dep-graph-struct-signature.rs:53:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:61:9 + --> $DIR/dep-graph-struct-signature.rs:61:38 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:63:9 + --> $DIR/dep-graph-struct-signature.rs:63:38 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `type_of` - --> $DIR/dep-graph-struct-signature.rs:68:5 + --> $DIR/dep-graph-struct-signature.rs:68:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `type_of` - --> $DIR/dep-graph-struct-signature.rs:75:5 + --> $DIR/dep-graph-struct-signature.rs:75:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `WillChange` to `fn_sig` - --> $DIR/dep-graph-struct-signature.rs:81:5 + --> $DIR/dep-graph-struct-signature.rs:81:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `WillChange` to `fn_sig` - --> $DIR/dep-graph-struct-signature.rs:84:5 + --> $DIR/dep-graph-struct-signature.rs:84:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `WillChange` to `typeck` - --> $DIR/dep-graph-struct-signature.rs:85:5 + --> $DIR/dep-graph-struct-signature.rs:85:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:32:9 + --> $DIR/dep-graph-struct-signature.rs:32:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `WillChange` to `fn_sig` - --> $DIR/dep-graph-struct-signature.rs:77:9 + --> $DIR/dep-graph-struct-signature.rs:77:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:48:9 + --> $DIR/dep-graph-struct-signature.rs:48:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:49:9 + --> $DIR/dep-graph-struct-signature.rs:49:38 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:55:9 + --> $DIR/dep-graph-struct-signature.rs:55:38 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-struct-signature.rs:56:9 + --> $DIR/dep-graph-struct-signature.rs:56:38 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 22 previous errors diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr index 6f56cbc8dd7a..293f918a3187 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits-same-method.stderr @@ -1,14 +1,14 @@ error: OK - --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:33:5 + --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:33:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:42:5 + --> $DIR/dep-graph-trait-impl-two-traits-same-method.rs:42:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr index 08f382cc024c..46cb0e9ea86f 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl-two-traits.stderr @@ -1,14 +1,14 @@ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl-two-traits.rs:32:5 + --> $DIR/dep-graph-trait-impl-two-traits.rs:32:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl-two-traits.rs:41:5 + --> $DIR/dep-graph-trait-impl-two-traits.rs:41:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/dep-graph/dep-graph-trait-impl.stderr b/tests/ui/dep-graph/dep-graph-trait-impl.stderr index bfee6d5c87b3..a5fce64c3a1c 100644 --- a/tests/ui/dep-graph/dep-graph-trait-impl.stderr +++ b/tests/ui/dep-graph/dep-graph-trait-impl.stderr @@ -1,32 +1,32 @@ error: OK - --> $DIR/dep-graph-trait-impl.rs:28:5 + --> $DIR/dep-graph-trait-impl.rs:28:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-trait-impl.rs:33:5 + --> $DIR/dep-graph-trait-impl.rs:33:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-trait-impl.rs:38:5 + --> $DIR/dep-graph-trait-impl.rs:38:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-trait-impl.rs:43:5 + --> $DIR/dep-graph-trait-impl.rs:43:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: no path from `x::` to `typeck` - --> $DIR/dep-graph-trait-impl.rs:56:5 + --> $DIR/dep-graph-trait-impl.rs:56:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 5 previous errors diff --git a/tests/ui/dep-graph/dep-graph-type-alias.stderr b/tests/ui/dep-graph/dep-graph-type-alias.stderr index 42ac803b22ec..9f24c1113b98 100644 --- a/tests/ui/dep-graph/dep-graph-type-alias.stderr +++ b/tests/ui/dep-graph/dep-graph-type-alias.stderr @@ -1,74 +1,74 @@ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:18:1 + --> $DIR/dep-graph-type-alias.rs:18:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:20:5 + --> $DIR/dep-graph-type-alias.rs:20:34 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:25:1 + --> $DIR/dep-graph-type-alias.rs:25:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:28:9 + --> $DIR/dep-graph-type-alias.rs:28:38 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:34:1 + --> $DIR/dep-graph-type-alias.rs:34:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: no path from `TypeAlias` to `type_of` - --> $DIR/dep-graph-type-alias.rs:42:1 + --> $DIR/dep-graph-type-alias.rs:42:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:49:1 + --> $DIR/dep-graph-type-alias.rs:49:30 | LL | #[rustc_then_this_would_need(type_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:52:1 + --> $DIR/dep-graph-type-alias.rs:52:30 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:53:1 + --> $DIR/dep-graph-type-alias.rs:53:30 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:36:5 + --> $DIR/dep-graph-type-alias.rs:36:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:44:5 + --> $DIR/dep-graph-type-alias.rs:44:34 | LL | #[rustc_then_this_would_need(fn_sig)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: OK - --> $DIR/dep-graph-type-alias.rs:45:5 + --> $DIR/dep-graph-type-alias.rs:45:34 | LL | #[rustc_then_this_would_need(typeck)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^ error: aborting due to 12 previous errors diff --git a/tests/ui/dep-graph/dep-graph-variance-alias.stderr b/tests/ui/dep-graph/dep-graph-variance-alias.stderr index e11de2452899..83ef573aad48 100644 --- a/tests/ui/dep-graph/dep-graph-variance-alias.stderr +++ b/tests/ui/dep-graph/dep-graph-variance-alias.stderr @@ -1,8 +1,8 @@ error: OK - --> $DIR/dep-graph-variance-alias.rs:19:1 + --> $DIR/dep-graph-variance-alias.rs:19:30 | LL | #[rustc_then_this_would_need(variances_of)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/deprecation/deprecated-expr-precedence.stderr b/tests/ui/deprecation/deprecated-expr-precedence.stderr index c3124cf86ef4..bd575e6b6276 100644 --- a/tests/ui/deprecation/deprecated-expr-precedence.stderr +++ b/tests/ui/deprecation/deprecated-expr-precedence.stderr @@ -5,7 +5,7 @@ LL | #[deprecated] 0 | ^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements = note: requested on the command line with `-W unused-attributes` error[E0308]: mismatched types diff --git a/tests/ui/deprecation/deprecation-sanity.rs b/tests/ui/deprecation/deprecation-sanity.rs index 45ee91741e5a..d1061dc1e170 100644 --- a/tests/ui/deprecation/deprecation-sanity.rs +++ b/tests/ui/deprecation/deprecation-sanity.rs @@ -3,7 +3,7 @@ // Various checks that deprecation attributes are used correctly mod bogus_attribute_types_1 { - #[deprecated(since = "a", note = "a", reason)] //~ ERROR unknown meta item 'reason' + #[deprecated(since = "a", note = "a", reason)] //~ ERROR malformed `deprecated` attribute input [E0539] fn f1() { } #[deprecated(since = "a", note)] //~ ERROR malformed `deprecated` attribute input [E0539] diff --git a/tests/ui/deprecation/deprecation-sanity.stderr b/tests/ui/deprecation/deprecation-sanity.stderr index 48d08b18f8bd..427d14d89c19 100644 --- a/tests/ui/deprecation/deprecation-sanity.stderr +++ b/tests/ui/deprecation/deprecation-sanity.stderr @@ -1,8 +1,10 @@ -error[E0541]: unknown meta item 'reason' - --> $DIR/deprecation-sanity.rs:6:43 +error[E0539]: malformed `deprecated` attribute input + --> $DIR/deprecation-sanity.rs:6:5 | LL | #[deprecated(since = "a", note = "a", reason)] - | ^^^^^^ expected one of `since`, `note` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^ + | | + | valid arguments are `since` or `note` error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:9:5 @@ -11,22 +13,6 @@ LL | #[deprecated(since = "a", note)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^----^^ | | | expected this to be of the form `note = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since = "a", note)] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:12:5 @@ -35,22 +21,6 @@ LL | #[deprecated(since, note = "a")] | ^^^^^^^^^^^^^-----^^^^^^^^^^^^^^ | | | expected this to be of the form `since = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since, note = "a")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:15:5 @@ -59,22 +29,6 @@ LL | #[deprecated(since = "a", note(b))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^-------^^ | | | expected this to be of the form `note = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since = "a", note(b))] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:18:5 @@ -83,22 +37,6 @@ LL | #[deprecated(since(b), note = "a")] | ^^^^^^^^^^^^^--------^^^^^^^^^^^^^^ | | | expected this to be of the form `since = "..."` - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since(b), note = "a")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error[E0539]: malformed `deprecated` attribute input --> $DIR/deprecation-sanity.rs:21:5 @@ -117,22 +55,6 @@ LL | #[deprecated("test")] | ^^^^^^^^^^^^^------^^ | | | didn't expect a literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated("test")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated("test")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated("test")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated("test")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error: multiple `deprecated` attributes --> $DIR/deprecation-sanity.rs:29:1 @@ -153,22 +75,6 @@ LL | #[deprecated(since = "a", since = "b", note = "c")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^ | | | found `since` used as a key more than once - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated(since = "a", since = "b", note = "c")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error: `#[deprecated]` attribute cannot be used on trait impl blocks --> $DIR/deprecation-sanity.rs:37:1 @@ -177,10 +83,10 @@ LL | #[deprecated = "hello"] | ^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, and use statements = note: `#[deny(useless_deprecated)]` on by default error: aborting due to 10 previous errors -Some errors have detailed explanations: E0538, E0539, E0541, E0565. +Some errors have detailed explanations: E0538, E0539, E0565. For more information about an error, try `rustc --explain E0538`. diff --git a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs index 378d0a3e7235..cdf2b76a1ccc 100644 --- a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs +++ b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs @@ -7,5 +7,5 @@ fn main() { } #[deprecated(note = test)] -//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `test` +//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found fn foo() {} diff --git a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr index cd985ab5a182..379c7f581224 100644 --- a/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr +++ b/tests/ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.stderr @@ -1,8 +1,8 @@ -error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `test` +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found expression --> $DIR/issue-66340-deprecated-attr-non-meta-grammar.rs:9:21 | LL | #[deprecated(note = test)] - | ^^^^ + | ^^^^ expressions are not allowed here | help: surround the identifier with quotation marks to make it into a string literal | diff --git a/tests/ui/deref-patterns/basic.rs b/tests/ui/deref-patterns/basic.rs deleted file mode 100644 index d76fb697f406..000000000000 --- a/tests/ui/deref-patterns/basic.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -//@ check-run-results -#![feature(string_deref_patterns)] - -fn main() { - test(Some(String::from("42"))); - test(Some(String::new())); - test(None); -} - -fn test(o: Option) { - match o { - Some("42") => println!("the answer"), - Some(_) => println!("something else?"), - None => println!("nil"), - } -} diff --git a/tests/ui/deref-patterns/default-infer.rs b/tests/ui/deref-patterns/default-infer.rs deleted file mode 100644 index 4f926175bd33..000000000000 --- a/tests/ui/deref-patterns/default-infer.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ check-pass -#![feature(string_deref_patterns)] - -fn main() { - match <_ as Default>::default() { - "" => (), - _ => unreachable!(), - } -} diff --git a/tests/ui/deref-patterns/gate.rs b/tests/ui/deref-patterns/gate.rs deleted file mode 100644 index 835fdf854d2c..000000000000 --- a/tests/ui/deref-patterns/gate.rs +++ /dev/null @@ -1,7 +0,0 @@ -// gate-test-string_deref_patterns -fn main() { - match String::new() { - "" | _ => {} - //~^ ERROR mismatched types - } -} diff --git a/tests/ui/deref-patterns/gate.stderr b/tests/ui/deref-patterns/gate.stderr deleted file mode 100644 index e3cbded339d7..000000000000 --- a/tests/ui/deref-patterns/gate.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/gate.rs:4:9 - | -LL | match String::new() { - | ------------- this expression has type `String` -LL | "" | _ => {} - | ^^ expected `String`, found `&str` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/deref/deref-in-for-loop.rs b/tests/ui/deref/deref-in-for-loop.rs new file mode 100644 index 000000000000..26921c3f1dda --- /dev/null +++ b/tests/ui/deref/deref-in-for-loop.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ run-pass +// Test that regionck uses the right memcat for patterns in for loops +// and doesn't ICE. + + +fn main() { + for &&x in Some(&0_usize).iter() { + assert_eq!(x, 0) + } +} diff --git a/tests/ui/derived-errors/issue-31997-1.stderr b/tests/ui/derived-errors/issue-31997-1.stderr index 40485027a660..2fb830ac41fc 100644 --- a/tests/ui/derived-errors/issue-31997-1.stderr +++ b/tests/ui/derived-errors/issue-31997-1.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `HashMap` +error[E0433]: cannot find type `HashMap` in this scope --> $DIR/issue-31997-1.rs:20:19 | LL | let mut map = HashMap::new(); diff --git a/tests/ui/derives/copy-drop-mutually-exclusive.rs b/tests/ui/derives/copy-drop-mutually-exclusive.rs index 5147605910d7..64cd5bf594b0 100644 --- a/tests/ui/derives/copy-drop-mutually-exclusive.rs +++ b/tests/ui/derives/copy-drop-mutually-exclusive.rs @@ -1,14 +1,14 @@ //! Regression test for issue #20126: Copy and Drop traits are mutually exclusive -#[derive(Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented -struct Foo; +#[derive(Copy, Clone)] +struct Foo; //~ ERROR the trait `Copy` cannot be implemented impl Drop for Foo { fn drop(&mut self) {} } -#[derive(Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented -struct Bar(::std::marker::PhantomData); +#[derive(Copy, Clone)] +struct Bar(::std::marker::PhantomData); //~ ERROR the trait `Copy` cannot be implemented impl Drop for Bar { fn drop(&mut self) {} diff --git a/tests/ui/derives/copy-drop-mutually-exclusive.stderr b/tests/ui/derives/copy-drop-mutually-exclusive.stderr index 771bbc925695..ab2d086c7f5f 100644 --- a/tests/ui/derives/copy-drop-mutually-exclusive.stderr +++ b/tests/ui/derives/copy-drop-mutually-exclusive.stderr @@ -1,14 +1,30 @@ error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor - --> $DIR/copy-drop-mutually-exclusive.rs:3:10 + --> $DIR/copy-drop-mutually-exclusive.rs:4:8 | LL | #[derive(Copy, Clone)] - | ^^^^ `Copy` not allowed on types with destructors + | ---- in this derive macro expansion +LL | struct Foo; + | ^^^ `Copy` not allowed on types with destructors + | +note: destructor declared here + --> $DIR/copy-drop-mutually-exclusive.rs:7:5 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^^^^^^^^^^ error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor - --> $DIR/copy-drop-mutually-exclusive.rs:10:10 + --> $DIR/copy-drop-mutually-exclusive.rs:11:8 | LL | #[derive(Copy, Clone)] - | ^^^^ `Copy` not allowed on types with destructors + | ---- in this derive macro expansion +LL | struct Bar(::std::marker::PhantomData); + | ^^^ `Copy` not allowed on types with destructors + | +note: destructor declared here + --> $DIR/copy-drop-mutually-exclusive.rs:14:5 + | +LL | fn drop(&mut self) {} + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/derives/derive-assoc-type-not-impl.stderr b/tests/ui/derives/derive-assoc-type-not-impl.stderr index 13ba80243a5e..ca968910fde4 100644 --- a/tests/ui/derives/derive-assoc-type-not-impl.stderr +++ b/tests/ui/derives/derive-assoc-type-not-impl.stderr @@ -11,10 +11,13 @@ LL | Bar:: { x: 1 }.clone(); | ^^^^^ method cannot be called on `Bar` due to unsatisfied trait bounds | note: trait bound `NotClone: Clone` was not satisfied - --> $DIR/derive-assoc-type-not-impl.rs:6:10 + --> $DIR/derive-assoc-type-not-impl.rs:7:12 | LL | #[derive(Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ----- in this derive macro expansion +LL | struct Bar { + | ^ type parameter would need to implement `Clone` + = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `NotClone` with `#[derive(Clone)]` | LL + #[derive(Clone)] diff --git a/tests/ui/derives/derive-debug-generic-with-lifetime.rs b/tests/ui/derives/derive-debug-generic-with-lifetime.rs new file mode 100644 index 000000000000..430ade071795 --- /dev/null +++ b/tests/ui/derives/derive-debug-generic-with-lifetime.rs @@ -0,0 +1,10 @@ +//! regression test for +//@ check-pass +#![allow(dead_code)] +#[derive(Debug)] +struct Message<'a, P: 'a = &'a [u8]> { + header: &'a [u8], + payload: P, +} + +fn main() {} diff --git a/tests/ui/derives/derive-debug-newtype-unsized-slice.rs b/tests/ui/derives/derive-debug-newtype-unsized-slice.rs new file mode 100644 index 000000000000..c735d9f039d2 --- /dev/null +++ b/tests/ui/derives/derive-debug-newtype-unsized-slice.rs @@ -0,0 +1,7 @@ +//! regression test for +//@ check-pass +#![allow(dead_code)] +#[derive(Debug)] +struct Row([T]); + +fn main() {} diff --git a/tests/ui/derives/derive-debug-uninhabited-enum.stderr b/tests/ui/derives/derive-debug-uninhabited-enum.stderr index 4911b6b6cded..90f4d34b1c5c 100644 --- a/tests/ui/derives/derive-debug-uninhabited-enum.stderr +++ b/tests/ui/derives/derive-debug-uninhabited-enum.stderr @@ -9,7 +9,7 @@ LL | Void(Void), | = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis = note: `-W dead-code` implied by `-W unused` - = help: to override `-W unused` add `#[allow(dead_code)]` + = help: to override `-W unused` add `#[expect(dead_code)]` or `#[allow(dead_code)]` warning: 1 warning emitted diff --git a/tests/ui/derives/derive-hygiene-struct-builder.rs b/tests/ui/derives/derive-hygiene-struct-builder.rs new file mode 100644 index 000000000000..95245a3b3f5a --- /dev/null +++ b/tests/ui/derives/derive-hygiene-struct-builder.rs @@ -0,0 +1,10 @@ +//! regression test for +//! struct named "builder" conflicted with derive macro internals. +//@ run-pass +#![allow(dead_code)] +#![allow(non_camel_case_types)] + +#[derive(Debug)] +struct builder; + +fn main() {} diff --git a/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr b/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr index e0cb3c1b43da..42dc8d46b575 100644 --- a/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr +++ b/tests/ui/derives/derives-span-Eq-enum-struct-variant.stderr @@ -7,7 +7,7 @@ LL | #[derive(Eq,PartialEq)] LL | x: Error | ^^^^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/derives/derives-span-Eq-enum.stderr b/tests/ui/derives/derives-span-Eq-enum.stderr index 2f09b9ea385f..ef1d9e3242ad 100644 --- a/tests/ui/derives/derives-span-Eq-enum.stderr +++ b/tests/ui/derives/derives-span-Eq-enum.stderr @@ -7,7 +7,7 @@ LL | #[derive(Eq,PartialEq)] LL | Error | ^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/derives/derives-span-Eq-struct.stderr b/tests/ui/derives/derives-span-Eq-struct.stderr index c16d9118e10f..bae7bb0361df 100644 --- a/tests/ui/derives/derives-span-Eq-struct.stderr +++ b/tests/ui/derives/derives-span-Eq-struct.stderr @@ -7,7 +7,7 @@ LL | struct Struct { LL | x: Error | ^^^^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/derives/derives-span-Eq-tuple-struct.stderr b/tests/ui/derives/derives-span-Eq-tuple-struct.stderr index dac295eed919..13396cb27246 100644 --- a/tests/ui/derives/derives-span-Eq-tuple-struct.stderr +++ b/tests/ui/derives/derives-span-Eq-tuple-struct.stderr @@ -7,7 +7,7 @@ LL | struct Struct( LL | Error | ^^^^^ the trait `Eq` is not implemented for `Error` | -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL help: consider annotating `Error` with `#[derive(Eq)]` | diff --git a/tests/ui/derives/deriving-copyclone.stderr b/tests/ui/derives/deriving-copyclone.stderr index befff8802804..20a73ffdcfbf 100644 --- a/tests/ui/derives/deriving-copyclone.stderr +++ b/tests/ui/derives/deriving-copyclone.stderr @@ -7,10 +7,12 @@ LL | is_copy(B { a: 1, b: C }); | required by a bound introduced by this call | note: required for `B` to implement `Copy` - --> $DIR/deriving-copyclone.rs:9:10 + --> $DIR/deriving-copyclone.rs:10:8 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ---- in this derive macro expansion +LL | struct B { + | ^ - type parameter would need to implement `Copy` note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 | @@ -30,10 +32,13 @@ LL | is_clone(B { a: 1, b: C }); | required by a bound introduced by this call | note: required for `B` to implement `Clone` - --> $DIR/deriving-copyclone.rs:9:16 + --> $DIR/deriving-copyclone.rs:10:8 | LL | #[derive(Copy, Clone)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ----- in this derive macro expansion +LL | struct B { + | ^ - type parameter would need to implement `Clone` + = help: consider manually implementing `Clone` to avoid undesired bounds note: required by a bound in `is_clone` --> $DIR/deriving-copyclone.rs:19:16 | @@ -53,10 +58,12 @@ LL | is_copy(B { a: 1, b: D }); | required by a bound introduced by this call | note: required for `B` to implement `Copy` - --> $DIR/deriving-copyclone.rs:9:10 + --> $DIR/deriving-copyclone.rs:10:8 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ---- in this derive macro expansion +LL | struct B { + | ^ - type parameter would need to implement `Copy` note: required by a bound in `is_copy` --> $DIR/deriving-copyclone.rs:18:15 | diff --git a/tests/ui/derives/deriving-meta-unknown-trait.stderr b/tests/ui/derives/deriving-meta-unknown-trait.stderr index 7ee90ae9eb0c..1cf31502dfb8 100644 --- a/tests/ui/derives/deriving-meta-unknown-trait.stderr +++ b/tests/ui/derives/deriving-meta-unknown-trait.stderr @@ -2,23 +2,33 @@ error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: a derive macro with a similar name exists: `Eq` + | ^^^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here +help: a derive macro with a similar name exists + | +LL - #[derive(Eqr)] +LL + #[derive(Eq)] + | error: cannot find derive macro `Eqr` in this scope --> $DIR/deriving-meta-unknown-trait.rs:1:10 | LL | #[derive(Eqr)] - | ^^^ help: a derive macro with a similar name exists: `Eq` + | ^^^ | --> $SRC_DIR/core/src/cmp.rs:LL:COL | = note: similarly named derive macro `Eq` defined here | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: a derive macro with a similar name exists + | +LL - #[derive(Eqr)] +LL + #[derive(Eq)] + | error: aborting due to 2 previous errors diff --git a/tests/ui/derives/deriving-with-repr-packed-2.stderr b/tests/ui/derives/deriving-with-repr-packed-2.stderr index b62c67d9a9da..6bd3fff39790 100644 --- a/tests/ui/derives/deriving-with-repr-packed-2.stderr +++ b/tests/ui/derives/deriving-with-repr-packed-2.stderr @@ -21,10 +21,14 @@ LL | let x: Foo = Foo(NonCopy, NonCopy, NonCopy); note: the following trait bounds were not satisfied: `NonCopy: Clone` `NonCopy: Copy` - --> $DIR/deriving-with-repr-packed-2.rs:5:16 + --> $DIR/deriving-with-repr-packed-2.rs:7:16 | LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] - | ^^^^^ unsatisfied trait bound introduced in this `derive` macro + | ----- in this derive macro expansion +LL | #[repr(packed)] +LL | pub struct Foo(T, T, T); + | ^ type parameter would need to implement `Clone` + = help: consider manually implementing the trait to avoid undesired bounds help: consider annotating `NonCopy` with `#[derive(Clone, Copy)]` | LL + #[derive(Clone, Copy)] diff --git a/tests/ui/derives/issue-97343.stderr b/tests/ui/derives/issue-97343.stderr index 27691f571884..c033a3d227c1 100644 --- a/tests/ui/derives/issue-97343.stderr +++ b/tests/ui/derives/issue-97343.stderr @@ -2,12 +2,11 @@ error[E0109]: type arguments are not allowed on type parameter `Irrelevant` --> $DIR/issue-97343.rs:4:23 | LL | #[derive(Debug)] - | ----- - | | - | not allowed on type parameter `Irrelevant` - | in this derive macro expansion + | ----- in this derive macro expansion LL | pub struct Irrelevant { - | ^^^^^^^^^^ type argument not allowed + | ---------- ^^^^^^^^^^ type argument not allowed + | | + | not allowed on type parameter `Irrelevant` | note: type parameter `Irrelevant` defined here --> $DIR/issue-97343.rs:4:23 diff --git a/tests/ui/derives/nonsense-input-to-debug.stderr b/tests/ui/derives/nonsense-input-to-debug.stderr index 7c97ca93cfc9..207d7b1969de 100644 --- a/tests/ui/derives/nonsense-input-to-debug.stderr +++ b/tests/ui/derives/nonsense-input-to-debug.stderr @@ -13,8 +13,6 @@ LL | should_be_vec_t: vec![T], | expected type | in this macro invocation | this macro call doesn't expand to a type - | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0392]: type parameter `T` is never used --> $DIR/nonsense-input-to-debug.rs:5:17 diff --git a/tests/ui/deriving/built-in-proc-macro-scope.stdout b/tests/ui/deriving/built-in-proc-macro-scope.stdout index 4fbce5edb819..e2a9119af3d6 100644 --- a/tests/ui/deriving/built-in-proc-macro-scope.stdout +++ b/tests/ui/deriving/built-in-proc-macro-scope.stdout @@ -6,7 +6,6 @@ //@ edition:2015 #![feature(derive_coerce_pointee)] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index a40dece22a26..2a05d77f8f6d 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -18,7 +18,6 @@ #![allow(dead_code)] #![allow(deprecated)] #![feature(derive_from)] -#[macro_use] extern crate std; #[prelude_import] use std::prelude::rust_2021::*; @@ -52,7 +51,7 @@ impl ::core::default::Default for Empty { #[automatically_derived] impl ::core::hash::Hash for Empty { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {} + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {} } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Empty { } @@ -66,7 +65,7 @@ impl ::core::cmp::Eq for Empty { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Empty { @@ -124,7 +123,7 @@ impl ::core::default::Default for Point { #[automatically_derived] impl ::core::hash::Hash for Point { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.x, state); ::core::hash::Hash::hash(&self.y, state) } @@ -143,7 +142,7 @@ impl ::core::cmp::Eq for Point { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -212,7 +211,7 @@ impl ::core::default::Default for PackedPoint { #[automatically_derived] impl ::core::hash::Hash for PackedPoint { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&{ self.x }, state); ::core::hash::Hash::hash(&{ self.y }, state) } @@ -231,7 +230,7 @@ impl ::core::cmp::Eq for PackedPoint { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -298,7 +297,7 @@ impl ::core::convert::From for TupleSingleField { #[automatically_derived] impl ::core::hash::Hash for TupleSingleField { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.0, state) } } @@ -314,7 +313,7 @@ impl ::core::cmp::Eq for TupleSingleField { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -373,7 +372,7 @@ impl ::core::convert::From for SingleField { #[automatically_derived] impl ::core::hash::Hash for SingleField { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.foo, state) } } @@ -389,7 +388,7 @@ impl ::core::cmp::Eq for SingleField { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -466,7 +465,7 @@ impl ::core::default::Default for Big { #[automatically_derived] impl ::core::hash::Hash for Big { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.b1, state); ::core::hash::Hash::hash(&self.b2, state); ::core::hash::Hash::hash(&self.b3, state); @@ -494,7 +493,7 @@ impl ::core::cmp::Eq for Big { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -742,7 +741,7 @@ impl ::core::convert::From<[u32]> for Unsized { #[automatically_derived] impl ::core::hash::Hash for Unsized { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.0, state) } } @@ -758,7 +757,7 @@ impl ::core::cmp::Eq for Unsized { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq<[u32]>; } } @@ -830,7 +829,7 @@ impl impl ::core::hash::Hash for Generic where T::A: ::core::hash::Hash { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&self.t, state); ::core::hash::Hash::hash(&self.ta, state); ::core::hash::Hash::hash(&self.u, state) @@ -853,7 +852,7 @@ impl ::core::cmp::Eq for #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -947,7 +946,7 @@ impl where T::A: ::core::hash::Hash + ::core::marker::Copy { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { ::core::hash::Hash::hash(&{ self.0 }, state); ::core::hash::Hash::hash(&{ self.1 }, state); ::core::hash::Hash::hash(&{ self.2 }, state) @@ -975,7 +974,7 @@ impl () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; @@ -1044,7 +1043,7 @@ impl ::core::fmt::Debug for Enum0 { #[automatically_derived] impl ::core::hash::Hash for Enum0 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { match *self {} } } @@ -1060,7 +1059,7 @@ impl ::core::cmp::Eq for Enum0 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Enum0 { @@ -1106,7 +1105,7 @@ impl ::core::fmt::Debug for Enum1 { #[automatically_derived] impl ::core::hash::Hash for Enum1 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { match self { Enum1::Single { x: __self_0 } => ::core::hash::Hash::hash(__self_0, state), @@ -1130,7 +1129,7 @@ impl ::core::cmp::Eq for Enum1 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; } } @@ -1182,7 +1181,7 @@ impl ::core::default::Default for Fieldless1 { #[automatically_derived] impl ::core::hash::Hash for Fieldless1 { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {} + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {} } #[automatically_derived] impl ::core::marker::StructuralPartialEq for Fieldless1 { } @@ -1196,7 +1195,7 @@ impl ::core::cmp::Eq for Fieldless1 { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless1 { @@ -1252,7 +1251,7 @@ impl ::core::default::Default for Fieldless { #[automatically_derived] impl ::core::hash::Hash for Fieldless { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state) } @@ -1273,7 +1272,7 @@ impl ::core::cmp::Eq for Fieldless { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () {} + fn assert_receiver_is_total_eq(&self) {} } #[automatically_derived] impl ::core::cmp::PartialOrd for Fieldless { @@ -1346,7 +1345,7 @@ impl ::core::default::Default for Mixed { #[automatically_derived] impl ::core::hash::Hash for Mixed { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1383,7 +1382,7 @@ impl ::core::cmp::Eq for Mixed { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; let _: ::core::cmp::AssertParamIsEq>; @@ -1546,7 +1545,7 @@ impl ::core::fmt::Debug for Fielded { #[automatically_derived] impl ::core::hash::Hash for Fielded { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1581,7 +1580,7 @@ impl ::core::cmp::Eq for Fielded { #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; @@ -1667,7 +1666,7 @@ impl ::core::fmt::Debug for impl ::core::hash::Hash for EnumGeneric { #[inline] - fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () { + fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) { let __self_discr = ::core::intrinsics::discriminant_value(self); ::core::hash::Hash::hash(&__self_discr, state); match self { @@ -1703,7 +1702,7 @@ impl ::core::cmp::Eq for #[inline] #[doc(hidden)] #[coverage(off)] - fn assert_receiver_is_total_eq(&self) -> () { + fn assert_receiver_is_total_eq(&self) { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq; } diff --git a/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout b/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout index 89300a5c6d0c..ace45c4d760f 100644 --- a/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout +++ b/tests/ui/deriving/deriving-coerce-pointee-expanded.stdout @@ -4,7 +4,6 @@ //@ compile-flags: -Zunpretty=expanded //@ edition: 2015 #![feature(derive_coerce_pointee)] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/deriving/issue-103157.stderr b/tests/ui/deriving/issue-103157.stderr index 51d4d0a89745..0e4a3f75db3f 100644 --- a/tests/ui/deriving/issue-103157.stderr +++ b/tests/ui/deriving/issue-103157.stderr @@ -18,7 +18,7 @@ LL | Float(Option), u16 and 4 others = note: required for `Option` to implement `Eq` -note: required by a bound in `AssertParamIsEq` +note: required by a bound in `std::cmp::AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/deriving/proc-macro-attribute-mixing.stdout b/tests/ui/deriving/proc-macro-attribute-mixing.stdout index b81110682d68..e82f1780d095 100644 --- a/tests/ui/deriving/proc-macro-attribute-mixing.stdout +++ b/tests/ui/deriving/proc-macro-attribute-mixing.stdout @@ -12,7 +12,6 @@ //@ edition: 2015 #![feature(derive_coerce_pointee)] -#[macro_use] extern crate std; #[prelude_import] use ::std::prelude::rust_2015::*; diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr index 2af24130a1e5..075e4bf0384d 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr @@ -1,22 +1,28 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:11:1 + --> $DIR/does_not_acccept_args.rs:12:1 | -LL | #[diagnostic::do_not_recommend(not_accepted)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diagnostic::do_not_recommend(if, crate, do yeet, false, dyn, abstract, gen, not_accepted)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:15:1 + --> $DIR/does_not_acccept_args.rs:16:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:19:1 + --> $DIR/does_not_acccept_args.rs:20:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 3 warnings emitted +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:24:1 + | +LL | #[diagnostic::do_not_recommend(x = y + z)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr index 2af24130a1e5..075e4bf0384d 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr @@ -1,22 +1,28 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:11:1 + --> $DIR/does_not_acccept_args.rs:12:1 | -LL | #[diagnostic::do_not_recommend(not_accepted)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diagnostic::do_not_recommend(if, crate, do yeet, false, dyn, abstract, gen, not_accepted)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:15:1 + --> $DIR/does_not_acccept_args.rs:16:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:19:1 + --> $DIR/does_not_acccept_args.rs:20:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 3 warnings emitted +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:24:1 + | +LL | #[diagnostic::do_not_recommend(x = y + z)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs index 5c21c045e10a..943b5a37f938 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs @@ -7,8 +7,9 @@ trait Foo {} trait Bar {} trait Baz {} +trait Boo {} -#[diagnostic::do_not_recommend(not_accepted)] +#[diagnostic::do_not_recommend(if, crate, do yeet, false, dyn, abstract, gen, not_accepted)] //~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments impl Foo for T where T: Send {} @@ -20,4 +21,8 @@ impl Bar for T where T: Send {} //~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments impl Baz for T where T: Send {} +#[diagnostic::do_not_recommend(x = y + z)] +//~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments +impl Boo for T where T: Send {} + fn main() {} diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs index c0af549e2d01..f7babae3aa7c 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.rs @@ -6,7 +6,7 @@ pub struct Foo; #[diagnostic::on_const(message = "tadaa", note = "boing")] -//~^ ERROR: `#[diagnostic::on_const]` can only be applied to trait impls +//~^ ERROR: `#[diagnostic::on_const]` can only be applied to non-const trait impls impl const PartialEq for Foo { fn eq(&self, _other: &Foo) -> bool { true diff --git a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr index baa0b11f798b..f92ea501696e 100644 --- a/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr +++ b/tests/ui/diagnostic_namespace/on_const/misplaced_attr.stderr @@ -13,14 +13,14 @@ note: the lint level is defined here LL | #![deny(misplaced_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `#[diagnostic::on_const]` can only be applied to trait impls +error: `#[diagnostic::on_const]` can only be applied to non-const trait impls --> $DIR/misplaced_attr.rs:8:1 | LL | #[diagnostic::on_const(message = "tadaa", note = "boing")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | impl const PartialEq for Foo { - | ---------------------------- not a trait impl + | ---------------------------- this is a const trait impl error: `#[diagnostic::on_const]` can only be applied to trait impls --> $DIR/misplaced_attr.rs:16:1 diff --git a/tests/ui/did_you_mean/println-typo.stderr b/tests/ui/did_you_mean/println-typo.stderr index 7dd6fbba620b..471d49b6ee2e 100644 --- a/tests/ui/did_you_mean/println-typo.stderr +++ b/tests/ui/did_you_mean/println-typo.stderr @@ -2,11 +2,16 @@ error: cannot find macro `prinltn` in this scope --> $DIR/println-typo.rs:4:5 | LL | prinltn!(); - | ^^^^^^^ help: a macro with a similar name exists: `println` + | ^^^^^^^ | --> $SRC_DIR/std/src/macros.rs:LL:COL | = note: similarly named macro `println` defined here +help: a macro with a similar name exists + | +LL - prinltn!(); +LL + println!(); + | error: aborting due to 1 previous error diff --git a/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr index 502f81518785..d677152314dc 100644 --- a/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr +++ b/tests/ui/did_you_mean/typo-suggestion-improvement-46332.stderr @@ -5,7 +5,13 @@ LL | struct TyUint {} | ------------- similarly named struct `TyUint` defined here ... LL | TyUInt {}; - | ^^^^^^ help: a struct with a similar name exists (notice the capitalization): `TyUint` + | ^^^^^^ + | +help: a struct with a similar name exists (notice the capitalization) + | +LL - TyUInt {}; +LL + TyUint {}; + | error: aborting due to 1 previous error diff --git a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs index bbab6f877487..b007425bd375 100644 --- a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs +++ b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.rs @@ -2,12 +2,18 @@ mod a {} macro_rules! m { () => { - use a::$crate; //~ ERROR unresolved import `a::$crate` - use a::$crate::b; //~ ERROR `$crate` in paths can only be used in start position - type A = a::$crate; //~ ERROR `$crate` in paths can only be used in start position + use a::$crate; //~ ERROR: unresolved import `a::$crate` + //~^ NOTE: no `$crate` in `a` + use a::$crate::b; //~ ERROR: `$crate` in paths can only be used in start position + //~^ NOTE: can only be used in path start position + type A = a::$crate; //~ ERROR: `$crate` in paths can only be used in start position + //~^ NOTE: can only be used in path start position } } m!(); +//~^ NOTE: in this expansion +//~| NOTE: in this expansion +//~| NOTE: in this expansion fn main() {} diff --git a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr index d46029710d6f..fc49e4c3dc3d 100644 --- a/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr +++ b/tests/ui/dollar-crate/dollar-crate-is-keyword-2.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position - --> $DIR/dollar-crate-is-keyword-2.rs:6:16 +error[E0433]: `$crate` in paths can only be used in start position + --> $DIR/dollar-crate-is-keyword-2.rs:7:16 | LL | use a::$crate::b; - | ^^^^^^ `$crate` in paths can only be used in start position + | ^^^^^^ can only be used in path start position ... LL | m!(); | ---- in this macro invocation @@ -20,11 +20,11 @@ LL | m!(); | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0433]: failed to resolve: `$crate` in paths can only be used in start position - --> $DIR/dollar-crate-is-keyword-2.rs:7:21 +error[E0433]: `$crate` in paths can only be used in start position + --> $DIR/dollar-crate-is-keyword-2.rs:9:21 | LL | type A = a::$crate; - | ^^^^^^ `$crate` in paths can only be used in start position + | ^^^^^^ can only be used in path start position ... LL | m!(); | ---- in this macro invocation diff --git a/tests/ui/drop/drop-conflicting-impls.rs b/tests/ui/drop/drop-conflicting-impls.rs new file mode 100644 index 000000000000..fba3462a24b2 --- /dev/null +++ b/tests/ui/drop/drop-conflicting-impls.rs @@ -0,0 +1,13 @@ +//! regression test for issue +struct MyStruct; + +impl Drop for MyStruct { + fn drop(&mut self) {} +} + +impl Drop for MyStruct { + //~^ ERROR conflicting implementations of trait + fn drop(&mut self) {} +} + +fn main() {} diff --git a/tests/ui/drop/drop-conflicting-impls.stderr b/tests/ui/drop/drop-conflicting-impls.stderr new file mode 100644 index 000000000000..ee310f498d37 --- /dev/null +++ b/tests/ui/drop/drop-conflicting-impls.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Drop` for type `MyStruct` + --> $DIR/drop-conflicting-impls.rs:8:1 + | +LL | impl Drop for MyStruct { + | ---------------------- first implementation here +... +LL | impl Drop for MyStruct { + | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyStruct` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/dropck/cleanup-arm-conditional.rs b/tests/ui/dropck/cleanup-arm-conditional.rs index 31331f24d6f6..7afbf9595da5 100644 --- a/tests/ui/dropck/cleanup-arm-conditional.rs +++ b/tests/ui/dropck/cleanup-arm-conditional.rs @@ -1,13 +1,9 @@ //@ run-pass -#![allow(stable_features)] #![allow(unused_imports)] // Test that cleanup scope for temporaries created in a match // arm is confined to the match arm itself. - -#![feature(os)] - use std::os; struct Test { x: isize } diff --git a/tests/ui/dynamically-sized-types/dst-coerce-custom.rs b/tests/ui/dst/dst-coerce-custom.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-coerce-custom.rs rename to tests/ui/dst/dst-coerce-custom.rs diff --git a/tests/ui/dynamically-sized-types/dst-coerce-rc.rs b/tests/ui/dst/dst-coerce-rc.rs similarity index 93% rename from tests/ui/dynamically-sized-types/dst-coerce-rc.rs rename to tests/ui/dst/dst-coerce-rc.rs index 5ec7853a8e82..490cfaca7de9 100644 --- a/tests/ui/dynamically-sized-types/dst-coerce-rc.rs +++ b/tests/ui/dst/dst-coerce-rc.rs @@ -1,10 +1,7 @@ //@ run-pass #![allow(unused_variables)] -#![allow(stable_features)] // Test a very simple custom DST coercion. -#![feature(core, rc_weak)] - use std::cell::RefCell; use std::rc::{Rc, Weak}; diff --git a/tests/ui/dynamically-sized-types/dst-coercions.rs b/tests/ui/dst/dst-coercions.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-coercions.rs rename to tests/ui/dst/dst-coercions.rs diff --git a/tests/ui/dynamically-sized-types/dst-coercions.stderr b/tests/ui/dst/dst-coercions.stderr similarity index 100% rename from tests/ui/dynamically-sized-types/dst-coercions.stderr rename to tests/ui/dst/dst-coercions.stderr diff --git a/tests/ui/dynamically-sized-types/dst-deref-mut.rs b/tests/ui/dst/dst-deref-mut.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-deref-mut.rs rename to tests/ui/dst/dst-deref-mut.rs diff --git a/tests/ui/dynamically-sized-types/dst-deref.rs b/tests/ui/dst/dst-deref.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-deref.rs rename to tests/ui/dst/dst-deref.rs diff --git a/tests/ui/dynamically-sized-types/dst-field-align.rs b/tests/ui/dst/dst-field-align.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-field-align.rs rename to tests/ui/dst/dst-field-align.rs diff --git a/tests/ui/dst/dst-index.rs b/tests/ui/dst/dst-index-fail.rs similarity index 100% rename from tests/ui/dst/dst-index.rs rename to tests/ui/dst/dst-index-fail.rs diff --git a/tests/ui/dst/dst-index-fail.stderr b/tests/ui/dst/dst-index-fail.stderr new file mode 100644 index 000000000000..a5481e9ad673 --- /dev/null +++ b/tests/ui/dst/dst-index-fail.stderr @@ -0,0 +1,28 @@ +error[E0161]: cannot move a value of type `str` + --> $DIR/dst-index-fail.rs:31:5 + | +LL | S[0]; + | ^^^^ the size of `str` cannot be statically determined + +error[E0161]: cannot move a value of type `dyn Debug` + --> $DIR/dst-index-fail.rs:34:5 + | +LL | T[0]; + | ^^^^ the size of `dyn Debug` cannot be statically determined + +error[E0507]: cannot move out of index of `S` + --> $DIR/dst-index-fail.rs:31:5 + | +LL | S[0]; + | ^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of index of `T` + --> $DIR/dst-index-fail.rs:34:5 + | +LL | T[0]; + | ^^^^ move occurs because value has type `dyn Debug`, which does not implement the `Copy` trait + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0161, E0507. +For more information about an error, try `rustc --explain E0161`. diff --git a/tests/ui/dynamically-sized-types/dst-index.rs b/tests/ui/dst/dst-index-success.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-index.rs rename to tests/ui/dst/dst-index-success.rs diff --git a/tests/ui/dst/dst-index.stderr b/tests/ui/dst/dst-index.stderr deleted file mode 100644 index d38af3f89c21..000000000000 --- a/tests/ui/dst/dst-index.stderr +++ /dev/null @@ -1,28 +0,0 @@ -error[E0161]: cannot move a value of type `str` - --> $DIR/dst-index.rs:31:5 - | -LL | S[0]; - | ^^^^ the size of `str` cannot be statically determined - -error[E0161]: cannot move a value of type `dyn Debug` - --> $DIR/dst-index.rs:34:5 - | -LL | T[0]; - | ^^^^ the size of `dyn Debug` cannot be statically determined - -error[E0507]: cannot move out of index of `S` - --> $DIR/dst-index.rs:31:5 - | -LL | S[0]; - | ^^^^ move occurs because value has type `str`, which does not implement the `Copy` trait - -error[E0507]: cannot move out of index of `T` - --> $DIR/dst-index.rs:34:5 - | -LL | T[0]; - | ^^^^ move occurs because value has type `dyn Debug`, which does not implement the `Copy` trait - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0161, E0507. -For more information about an error, try `rustc --explain E0161`. diff --git a/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs b/tests/ui/dst/dst-irrefutable-bind.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs rename to tests/ui/dst/dst-irrefutable-bind.rs diff --git a/tests/ui/dynamically-sized-types/dst-raw.rs b/tests/ui/dst/dst-raw.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-raw.rs rename to tests/ui/dst/dst-raw.rs diff --git a/tests/ui/dynamically-sized-types/dst-struct-sole.rs b/tests/ui/dst/dst-struct-sole.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-struct-sole.rs rename to tests/ui/dst/dst-struct-sole.rs diff --git a/tests/ui/dynamically-sized-types/dst-struct.rs b/tests/ui/dst/dst-struct.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-struct.rs rename to tests/ui/dst/dst-struct.rs diff --git a/tests/ui/dynamically-sized-types/dst-trait.rs b/tests/ui/dst/dst-trait.rs similarity index 100% rename from tests/ui/dynamically-sized-types/dst-trait.rs rename to tests/ui/dst/dst-trait.rs diff --git a/tests/ui/dst/unsized-str-mutability.rs b/tests/ui/dst/unsized-str-mutability.rs new file mode 100644 index 000000000000..d84fa001fd67 --- /dev/null +++ b/tests/ui/dst/unsized-str-mutability.rs @@ -0,0 +1,8 @@ +//! regression test for +//! Test that HIR ty lowering doesn't forget about mutability of `&mut str`. +//@ run-pass + +fn main() { + fn foo(_: &mut T) {} + let _f: fn(&mut str) = foo; +} diff --git a/tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs b/tests/ui/duplicate/inherent-impls-overlap-check/auxiliary/repeat.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/auxiliary/repeat.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/auxiliary/repeat.rs diff --git a/tests/ui/duplicate/inherent-impls-overlap-check/disjoint-ref-mut-method.rs b/tests/ui/duplicate/inherent-impls-overlap-check/disjoint-ref-mut-method.rs new file mode 100644 index 000000000000..d4594b2e2c95 --- /dev/null +++ b/tests/ui/duplicate/inherent-impls-overlap-check/disjoint-ref-mut-method.rs @@ -0,0 +1,14 @@ +//! regression test for +//@ check-pass +#![allow(dead_code)] + +struct Foo(T); + +impl<'a, T> Foo<&'a T> { + fn foo(&self) {} +} +impl<'a, T> Foo<&'a mut T> { + fn foo(&self) {} +} + +fn main() {} diff --git a/tests/ui/inherent-impls-overlap-check/no-overlap.rs b/tests/ui/duplicate/inherent-impls-overlap-check/no-overlap.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/no-overlap.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/no-overlap.rs diff --git a/tests/ui/inherent-impls-overlap-check/overlap.rs b/tests/ui/duplicate/inherent-impls-overlap-check/overlap.rs similarity index 100% rename from tests/ui/inherent-impls-overlap-check/overlap.rs rename to tests/ui/duplicate/inherent-impls-overlap-check/overlap.rs diff --git a/tests/ui/inherent-impls-overlap-check/overlap.stderr b/tests/ui/duplicate/inherent-impls-overlap-check/overlap.stderr similarity index 100% rename from tests/ui/inherent-impls-overlap-check/overlap.stderr rename to tests/ui/duplicate/inherent-impls-overlap-check/overlap.stderr diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs new file mode 100644 index 000000000000..f4193f18352d --- /dev/null +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.rs @@ -0,0 +1,14 @@ +//@ needs-rustc-debug-assertions + +struct NonGeneric {} + +#[derive(Default)] +//~^ ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~| ERROR: struct takes 0 generic arguments but 1 generic argument was supplied +struct NonGeneric<'a, const N: usize> {} +//~^ ERROR: struct takes 0 lifetime arguments but 1 lifetime argument was supplied +//~| ERROR: struct takes 0 generic arguments but 1 generic argument was supplied +//~| ERROR: lifetime parameter `'a` is never used +//~| ERROR: the name `NonGeneric` is defined multiple times + +pub fn main() {} diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr new file mode 100644 index 000000000000..0d6aaaf5186d --- /dev/null +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive-default-133965.stderr @@ -0,0 +1,78 @@ +error[E0428]: the name `NonGeneric` is defined multiple times + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:1 + | +LL | struct NonGeneric {} + | ----------------- previous definition of the type `NonGeneric` here +... +LL | struct NonGeneric<'a, const N: usize> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonGeneric` redefined here + | + = note: `NonGeneric` must be defined only once in the type namespace of this module + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 lifetime arguments +... +LL | struct NonGeneric<'a, const N: usize> {} + | -- help: remove the lifetime argument + | +note: struct defined here, with 0 lifetime parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:5:10 + | +LL | #[derive(Default)] + | ^^^^^^^ expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:19 + | +LL | struct NonGeneric<'a, const N: usize> {} + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:8 + | +LL | struct NonGeneric<'a, const N: usize> {} + | ^^^^^^^^^^ -- help: remove the lifetime argument + | | + | expected 0 lifetime arguments + | +note: struct defined here, with 0 lifetime parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:8:8 + | +LL | struct NonGeneric<'a, const N: usize> {} + | ^^^^^^^^^^ - help: remove the unnecessary generic argument + | | + | expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive-default-133965.rs:3:8 + | +LL | struct NonGeneric {} + | ^^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0107, E0392, E0428. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs index f3bf299aa65f..e946c0c5350e 100644 --- a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs @@ -8,12 +8,12 @@ struct NotSM; #[derive(PartialEq, Eq)] -//~^ ERROR struct takes 0 generic arguments -//~| ERROR struct takes 0 generic arguments -//~| ERROR struct takes 0 generic arguments -//~| ERROR struct takes 0 generic arguments +//~^ ERROR: struct takes 0 generic arguments struct NotSM(T); -//~^ ERROR the name `NotSM` is defined multiple times -//~| ERROR no field `0` +//~^ ERROR: struct takes 0 generic arguments +//~| ERROR: struct takes 0 generic arguments +//~| ERROR: struct takes 0 generic arguments +//~| ERROR: the name `NotSM` is defined multiple times +//~| ERROR: no field `0` fn main() {} diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr index 32c3cf440316..e80cf35d81e1 100644 --- a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr +++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `NotSM` is defined multiple times - --> $DIR/multiple-types-with-same-name-and-derive.rs:15:1 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:1 | LL | struct NotSM; | ------------- previous definition of the type `NotSM` here @@ -10,10 +10,10 @@ LL | struct NotSM(T); = note: `NotSM` must be defined only once in the type namespace of this module error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive.rs:10:10 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:8 | -LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ expected 0 generic arguments +LL | struct NotSM(T); + | ^^^^^ expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 @@ -30,27 +30,27 @@ LL | #[derive(PartialEq, Eq)] note: struct defined here, with 0 generic parameters --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 | +LL | struct NotSM; + | ^^^^^ + +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:8 + | +LL | struct NotSM(T); + | ^^^^^ expected 0 generic arguments + | +note: struct defined here, with 0 generic parameters + --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 + | LL | struct NotSM; | ^^^^^ = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive.rs:10:21 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:8 | -LL | #[derive(PartialEq, Eq)] - | ^^ expected 0 generic arguments - | -note: struct defined here, with 0 generic parameters - --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 - | -LL | struct NotSM; - | ^^^^^ - -error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/multiple-types-with-same-name-and-derive.rs:10:10 - | -LL | #[derive(PartialEq, Eq)] - | ^^^^^^^^^ expected 0 generic arguments +LL | struct NotSM(T); + | ^^^^^ expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8 @@ -60,7 +60,7 @@ LL | struct NotSM; = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0609]: no field `0` on type `&NotSM` - --> $DIR/multiple-types-with-same-name-and-derive.rs:15:17 + --> $DIR/multiple-types-with-same-name-and-derive.rs:12:17 | LL | struct NotSM(T); | ^ unknown field diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds.stderr index 21ba90301173..717d8949e2d8 100644 --- a/tests/ui/dyn-compatibility/assoc_type_bounds.stderr +++ b/tests/ui/dyn-compatibility/assoc_type_bounds.stderr @@ -5,7 +5,7 @@ LL | type Bar | -------- `Bar` defined here ... LL | fn foo(_: &dyn Foo<()>) {} - | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>` + | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = /* Type */>` error[E0191]: the value of the associated type `Bar` in `Foo` must be specified --> $DIR/assoc_type_bounds.rs:11:16 @@ -14,7 +14,7 @@ LL | type Bar | -------- `Bar` defined here ... LL | fn bar(_: &dyn Foo) {} - | ^^^^^^^^ help: specify the associated type: `Foo` + | ^^^^^^^^ help: specify the associated type: `Foo` error: aborting due to 2 previous errors diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr index 5c4163b19693..9ddded9addfa 100644 --- a/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr +++ b/tests/ui/dyn-compatibility/assoc_type_bounds2.stderr @@ -5,7 +5,7 @@ LL | type Bar | -------- `Bar` defined here ... LL | fn foo(_: &dyn Foo<()>) {} - | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>` + | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = /* Type */>` error[E0191]: the value of the associated type `Bar` in `Foo` must be specified --> $DIR/assoc_type_bounds2.rs:11:16 @@ -14,7 +14,7 @@ LL | type Bar | -------- `Bar` defined here ... LL | fn bar(_: &dyn Foo) {} - | ^^^^^^^^ help: specify the associated type: `Foo` + | ^^^^^^^^ help: specify the associated type: `Foo` error: aborting due to 2 previous errors diff --git a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.stderr b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.stderr index 5438faaaf054..8f75f19f571a 100644 --- a/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.stderr +++ b/tests/ui/dyn-compatibility/assoc_type_bounds_sized_others.stderr @@ -5,7 +5,7 @@ LL | type Bop; | -------- `Bop` defined here ... LL | fn foo(_: &dyn Foo) {} - | ^^^ help: specify the associated type: `Foo` + | ^^^ help: specify the associated type: `Foo` error[E0191]: the value of the associated type `Bop` in `Bar` must be specified --> $DIR/assoc_type_bounds_sized_others.rs:22:16 @@ -14,7 +14,7 @@ LL | type Bop; | -------- `Bop` defined here ... LL | fn bar(_: &dyn Bar) {} - | ^^^ help: specify the associated type: `Bar` + | ^^^ help: specify the associated type: `Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/dyn-compatibility/associated-consts.stderr b/tests/ui/dyn-compatibility/associated-consts.stderr index dc64c93a577e..a92557ea7b8b 100644 --- a/tests/ui/dyn-compatibility/associated-consts.stderr +++ b/tests/ui/dyn-compatibility/associated-consts.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` is not dyn compatible - --> $DIR/associated-consts.rs:8:31 + --> $DIR/associated-consts.rs:8:35 | LL | fn make_bar(t: &T) -> &dyn Bar { - | ^^^^^^^ `Bar` is not dyn compatible + | ^^^ `Bar` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Bar { | --- this trait is not dyn compatible... LL | const X: usize; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `X` = help: consider moving `X` to another trait error: aborting due to 1 previous error diff --git a/tests/ui/dyn-compatibility/default-param-self-projection.stderr b/tests/ui/dyn-compatibility/default-param-self-projection.stderr index ea252a99b048..86f85f4da8e6 100644 --- a/tests/ui/dyn-compatibility/default-param-self-projection.stderr +++ b/tests/ui/dyn-compatibility/default-param-self-projection.stderr @@ -7,11 +7,11 @@ LL | trait A::E> {} LL | let B: &dyn A = &(); | ^ | - = note: because the parameter default references `Self`, the parameter must be specified on the object type -help: set the type parameter to the desired type + = note: because the parameter default references `Self`, the parameter must be specified on the trait object type +help: explicitly specify the type parameter | -LL | let B: &dyn A = &(); - | +++ +LL | let B: &dyn A = &(); + | +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr b/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr index cfebd5d69470..1189c8dc2a6a 100644 --- a/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr +++ b/tests/ui/dyn-compatibility/gat-incompatible-supertrait.stderr @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Super { | ----- this trait is not dyn compatible... LL | type Assoc<'a>; - | ^^^^^ ...because it contains the generic associated type `Assoc` + | ^^^^^ ...because it contains generic associated type `Assoc` = help: consider moving `Assoc` to another trait error: aborting due to 1 previous error diff --git a/tests/ui/dyn-compatibility/metasized.rs b/tests/ui/dyn-compatibility/metasized.rs new file mode 100644 index 000000000000..ff233c5ca764 --- /dev/null +++ b/tests/ui/dyn-compatibility/metasized.rs @@ -0,0 +1,25 @@ +//@ run-pass +//! This test and `sized-*.rs` and `pointeesized.rs` test that dyn-compatibility correctly +//! handles sizedness traits, which are special in several parts of the compiler. +#![feature(sized_hierarchy)] +use std::marker::MetaSized; + +trait Foo: std::fmt::Debug + MetaSized {} + +impl Foo for T {} + +fn unsize_sized(x: Box) -> Box { + x +} + +fn unsize_subtrait(x: Box) -> Box { + x +} + +fn main() { + let _bx = unsize_sized(Box::new(vec![1, 2, 3])); + + let bx: Box = Box::new(vec![1, 2, 3]); + let _ = format!("{bx:?}"); + let _bx = unsize_subtrait(bx); +} diff --git a/tests/ui/dyn-compatibility/missing-assoc-type.stderr b/tests/ui/dyn-compatibility/missing-assoc-type.stderr index 5a7560682f2e..5a5dc20590d0 100644 --- a/tests/ui/dyn-compatibility/missing-assoc-type.stderr +++ b/tests/ui/dyn-compatibility/missing-assoc-type.stderr @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Foo { | --- this trait is not dyn compatible... LL | type Bar; - | ^^^ ...because it contains the generic associated type `Bar` + | ^^^ ...because it contains generic associated type `Bar` = help: consider moving `Bar` to another trait error: aborting due to 1 previous error diff --git a/tests/ui/dyn-compatibility/no-duplicate-e0038.stderr b/tests/ui/dyn-compatibility/no-duplicate-e0038.stderr index 94037387c3e1..bef580bcedb5 100644 --- a/tests/ui/dyn-compatibility/no-duplicate-e0038.stderr +++ b/tests/ui/dyn-compatibility/no-duplicate-e0038.stderr @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Tr { | -- this trait is not dyn compatible... LL | const N: usize; - | ^ ...because it contains this associated `const` + | ^ ...because it contains associated const `N` = help: consider moving `N` to another trait = help: only type `u8` implements `Tr`; consider using it directly instead. diff --git a/tests/ui/dyn-compatibility/pointeesized.rs b/tests/ui/dyn-compatibility/pointeesized.rs new file mode 100644 index 000000000000..863abd704ead --- /dev/null +++ b/tests/ui/dyn-compatibility/pointeesized.rs @@ -0,0 +1,17 @@ +//@ run-pass +//! This test and `sized-*.rs` and `metasized.rs` test that dyn-compatibility correctly +//! handles sizedness traits, which are special in several parts of the compiler. +#![feature(sized_hierarchy)] +// PointeeSized is effectively removed before reaching the trait solver, +// so it's as though it wasn't even mentioned in the trait list. +use std::marker::PointeeSized; + +fn main() { + let dyn_ref: &(dyn PointeeSized + Send) = &42; + let dyn_ref: &dyn Send = dyn_ref; + let _dyn_ref: &(dyn PointeeSized + Send) = dyn_ref; + assert_eq!( + std::any::TypeId::of::(), + std::any::TypeId::of::(), + ); +} diff --git a/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr b/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr index 3d89b52d522d..f39be936f417 100644 --- a/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr +++ b/tests/ui/dyn-compatibility/require-assoc-for-all-super-substs.stderr @@ -5,7 +5,7 @@ LL | type Assoc: Default; | ------------------- `Assoc` defined here ... LL | let q: as Sup>::Assoc = Default::default(); - | ^^^^^^^^^^^^^ help: specify the associated type: `Dyn` + | ^^^^^^^^^^^^^ help: specify the associated type: `Dyn` error: aborting due to 1 previous error diff --git a/tests/ui/dyn-compatibility/sized-3.rs b/tests/ui/dyn-compatibility/sized-3.rs new file mode 100644 index 000000000000..84ee391445e7 --- /dev/null +++ b/tests/ui/dyn-compatibility/sized-3.rs @@ -0,0 +1,29 @@ +//! This test and `metasized.rs` and `pointeesized.rs` test that dyn-compatibility correctly +//! handles the different sizedness traits, which are special in several parts of the compiler. + +trait Foo: std::fmt::Debug + Sized {} + +impl Foo for T {} + +fn unsize_sized(x: Box) -> Box { + //~^ ERROR the trait `Sized` is not dyn compatible + x +} + +fn unsize_subtrait(x: Box) -> Box { + //~^ ERROR the trait `Foo` is not dyn compatible + //~| ERROR the trait `Sized` is not dyn compatible + x +} + +fn main() { + let _bx = unsize_sized(Box::new(vec![1, 2, 3])); + //~^ ERROR the trait `Sized` is not dyn compatible + + let bx: Box = Box::new(vec![1, 2, 3]); + //~^ ERROR the trait `Foo` is not dyn compatible + let _ = format!("{bx:?}"); + let _bx = unsize_subtrait(bx); + //~^ ERROR the trait `Foo` is not dyn compatible + //~| ERROR the trait `Sized` is not dyn compatible +} diff --git a/tests/ui/dyn-compatibility/sized-3.stderr b/tests/ui/dyn-compatibility/sized-3.stderr new file mode 100644 index 000000000000..88d3bb5810fe --- /dev/null +++ b/tests/ui/dyn-compatibility/sized-3.stderr @@ -0,0 +1,88 @@ +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/sized-3.rs:8:47 + | +LL | fn unsize_sized(x: Box) -> Box { + | ^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/sized-3.rs:13:27 + | +LL | fn unsize_subtrait(x: Box) -> Box { + | ^^^^^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/sized-3.rs:4:30 + | +LL | trait Foo: std::fmt::Debug + Sized {} + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/sized-3.rs:13:44 + | +LL | fn unsize_subtrait(x: Box) -> Box { + | ^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/sized-3.rs:20:15 + | +LL | let _bx = unsize_sized(Box::new(vec![1, 2, 3])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/sized-3.rs:23:21 + | +LL | let bx: Box = Box::new(vec![1, 2, 3]); + | ^^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/sized-3.rs:4:30 + | +LL | trait Foo: std::fmt::Debug + Sized {} + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Foo` is not dyn compatible + --> $DIR/sized-3.rs:26:31 + | +LL | let _bx = unsize_subtrait(bx); + | ^^ `Foo` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/sized-3.rs:4:30 + | +LL | trait Foo: std::fmt::Debug + Sized {} + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait is not dyn compatible... + +error[E0038]: the trait `Sized` is not dyn compatible + --> $DIR/sized-3.rs:26:15 + | +LL | let _bx = unsize_subtrait(bx); + | ^^^^^^^^^^^^^^^^^^^ `Sized` is not dyn compatible + | + = note: the trait is not dyn compatible because it requires `Self: Sized` + = note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr index ba4ce4753995..a8c2f512a9ad 100644 --- a/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr +++ b/tests/ui/dyn-compatibility/supertrait-mentions-GAT.stderr @@ -18,7 +18,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable --> $DIR/supertrait-mentions-GAT.rs:4:10 | LL | type Gat<'a> - | ^^^ ...because it contains the generic associated type `Gat` + | ^^^ ...because it contains generic associated type `Gat` ... LL | trait SuperTrait: for<'a> GatTrait = T> { | ---------- this trait is not dyn compatible... diff --git a/tests/ui/dyn-compatibility/trait-alias-self-projection.rs b/tests/ui/dyn-compatibility/trait-alias-self-projection.rs deleted file mode 100644 index 0badb738809e..000000000000 --- a/tests/ui/dyn-compatibility/trait-alias-self-projection.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![feature(trait_alias)] -trait B = Fn() -> Self; -type D = &'static dyn B; -//~^ ERROR E0411 - -fn a() -> D { - unreachable!(); -} - -fn main() { - _ = a(); -} diff --git a/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr b/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr deleted file mode 100644 index dccee02e9cd1..000000000000 --- a/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0411]: `Self` is not allowed in type aliases - --> $DIR/trait-alias-self-projection.rs:3:19 - | -LL | type D = &'static dyn B; - | ^^^^^ `Self` is only available in impls, traits, and concrete type definitions - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0411`. diff --git a/tests/ui/dyn-compatibility/type-projection-behind-trait-alias-mentions-self.rs b/tests/ui/dyn-compatibility/type-projection-behind-trait-alias-mentions-self.rs new file mode 100644 index 000000000000..9122ddaaff7b --- /dev/null +++ b/tests/ui/dyn-compatibility/type-projection-behind-trait-alias-mentions-self.rs @@ -0,0 +1,18 @@ +// Check that we reject type projections behind trait aliases that mention `Self`. +// +// The author of the trait object type can't fix this unlike the supertrait bound +// equivalent where they just need to explicitly specify the assoc type. + +// issue: + +#![feature(trait_alias)] + +trait F = Fn() -> Self; + +trait G = H; +trait H { type T: ?Sized; } + +fn main() { + let _: dyn F; //~ ERROR associated type binding in trait object type mentions `Self` + let _: dyn G; //~ ERROR associated type binding in trait object type mentions `Self` +} diff --git a/tests/ui/dyn-compatibility/type-projection-behind-trait-alias-mentions-self.stderr b/tests/ui/dyn-compatibility/type-projection-behind-trait-alias-mentions-self.stderr new file mode 100644 index 000000000000..0b7fb55a908c --- /dev/null +++ b/tests/ui/dyn-compatibility/type-projection-behind-trait-alias-mentions-self.stderr @@ -0,0 +1,20 @@ +error: associated type binding in trait object type mentions `Self` + --> $DIR/type-projection-behind-trait-alias-mentions-self.rs:16:12 + | +LL | trait F = Fn() -> Self; + | ---- this binding mentions `Self` +... +LL | let _: dyn F; + | ^^^^^ contains a mention of `Self` + +error: associated type binding in trait object type mentions `Self` + --> $DIR/type-projection-behind-trait-alias-mentions-self.rs:17:12 + | +LL | trait G = H; + | -------- this binding mentions `Self` +... +LL | let _: dyn G; + | ^^^^^ contains a mention of `Self` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr index 0d53fb024aca..c0e794cee292 100644 --- a/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr +++ b/tests/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr @@ -5,7 +5,7 @@ LL | pub mod dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see note: the lint level is defined here --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:11:9 | @@ -20,7 +20,7 @@ LL | pub struct dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:22:16 @@ -29,7 +29,7 @@ LL | use outer_mod::dyn::dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:22:21 @@ -38,7 +38,7 @@ LL | use outer_mod::dyn::dyn; | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:29:11 @@ -47,7 +47,7 @@ LL | match dyn { dyn => {} } | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:29:17 @@ -56,7 +56,7 @@ LL | match dyn { dyn => {} } | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:34:17 @@ -65,7 +65,7 @@ LL | macro_defn::dyn(); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:44:18 @@ -74,7 +74,7 @@ LL | macro_rules! dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:12 @@ -83,7 +83,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:34 @@ -92,7 +92,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:52:39 @@ -101,7 +101,7 @@ LL | pub fn dyn() -> ::outer_mod::dyn::dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:59:22 @@ -110,7 +110,7 @@ LL | ::outer_mod::dyn::dyn | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:59:27 @@ -119,7 +119,7 @@ LL | ::outer_mod::dyn::dyn | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:68:23 @@ -128,7 +128,7 @@ LL | pub fn boxed() -> dyn!( | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 + = note: for more information, see error: aborting due to 14 previous errors diff --git a/tests/ui/editions/edition-raw-pointer-method-2015.stderr b/tests/ui/editions/edition-raw-pointer-method-2015.stderr index 3d8b3f633ce8..ad8beb049f9f 100644 --- a/tests/ui/editions/edition-raw-pointer-method-2015.stderr +++ b/tests/ui/editions/edition-raw-pointer-method-2015.stderr @@ -5,7 +5,7 @@ LL | let _ = y.is_null(); | ^^^^^^^ | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 + = note: for more information, see note: the lint level is defined here --> $DIR/edition-raw-pointer-method-2015.rs:5:8 | diff --git a/tests/ui/eii/attribute_targets.rs b/tests/ui/eii/attribute_targets.rs new file mode 100644 index 000000000000..a62915fe2609 --- /dev/null +++ b/tests/ui/eii/attribute_targets.rs @@ -0,0 +1,63 @@ +#![feature(extern_item_impls)] +// Check whether the EII attributes do target checking properly. + +#[eii] +fn foo() {} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +const A: usize = 3; + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +macro_rules! foo_impl { + () => {}; +} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +struct Foo; + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +impl Foo { + #[foo] + //~^ ERROR `#[foo]` is only valid on functions + #[eii] + //~^ ERROR `#[eii]` is only valid on functions + fn foo_impl() {} +} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +trait Bar { + #[foo] + //~^ ERROR `#[foo]` is only valid on functions + #[eii] + //~^ ERROR `#[eii]` is only valid on functions + fn foo_impl(); +} + +#[foo] +//~^ ERROR `#[foo]` is only valid on functions +#[eii] +//~^ ERROR `#[eii]` is only valid on functions +impl Bar for Foo { + #[foo] + //~^ ERROR `#[foo]` is only valid on functions + #[eii] + //~^ ERROR `#[eii]` is only valid on functions + fn foo_impl() {} +} + +fn main() {} diff --git a/tests/ui/eii/attribute_targets.stderr b/tests/ui/eii/attribute_targets.stderr new file mode 100644 index 000000000000..bf04c323c95c --- /dev/null +++ b/tests/ui/eii/attribute_targets.stderr @@ -0,0 +1,110 @@ +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:7:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:9:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:13:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:15:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:21:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:23:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:27:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:29:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:32:5 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:34:5 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:39:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:41:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:44:5 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:46:5 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:51:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:53:1 + | +LL | #[eii] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/attribute_targets.rs:56:5 + | +LL | #[foo] + | ^^^^^^ + +error: `#[eii]` is only valid on functions + --> $DIR/attribute_targets.rs:58:5 + | +LL | #[eii] + | ^^^^^^ + +error: aborting due to 18 previous errors + diff --git a/tests/ui/eii/auxiliary/other_crate_privacy1.rs b/tests/ui/eii/auxiliary/other_crate_privacy1.rs new file mode 100644 index 000000000000..41160cd1fe39 --- /dev/null +++ b/tests/ui/eii/auxiliary/other_crate_privacy1.rs @@ -0,0 +1,18 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +#[eii(eii1)] +fn decl1(x: u64); + +mod private { + #[eii(eii2)] + pub fn decl2(x: u64); +} + +pub use private::eii2 as eii3; +pub use private::decl2 as decl3; + +pub fn local_call_decl1(x: u64) { + decl1(x) +} diff --git a/tests/ui/eii/auxiliary/other_crate_privacy2.rs b/tests/ui/eii/auxiliary/other_crate_privacy2.rs new file mode 100644 index 000000000000..9fb19298f09f --- /dev/null +++ b/tests/ui/eii/auxiliary/other_crate_privacy2.rs @@ -0,0 +1,22 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +// does have an impl but can't be called +#[eii(eii1)] +fn decl1(x: u64); + +#[eii(eii2)] +pub fn decl2(x: u64); + +mod private { + #[eii(eii3)] + pub fn decl3(x: u64); +} + +pub use private::eii3 as eii4; +pub use private::decl3 as decl4; + +pub fn local_call_decl1(x: u64) { + decl1(x) +} diff --git a/tests/ui/eii/default/auxiliary/decl_with_default.rs b/tests/ui/eii/default/auxiliary/decl_with_default.rs new file mode 100644 index 000000000000..8d962c19c94d --- /dev/null +++ b/tests/ui/eii/default/auxiliary/decl_with_default.rs @@ -0,0 +1,8 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +#[eii(eii1)] +pub fn decl1(x: u64) { + println!("default {x}"); +} diff --git a/tests/ui/eii/default/auxiliary/impl1.rs b/tests/ui/eii/default/auxiliary/impl1.rs new file mode 100644 index 000000000000..3510ea1eb3f2 --- /dev/null +++ b/tests/ui/eii/default/auxiliary/impl1.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl_with_default.rs +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +extern crate decl_with_default as decl; + + +#[unsafe(decl::eii1)] //~ ERROR multiple implementations of `#[eii1]` +fn other(x: u64) { + println!("1{x}"); +} diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs new file mode 100644 index 000000000000..b479baa80444 --- /dev/null +++ b/tests/ui/eii/default/call_default.rs @@ -0,0 +1,26 @@ +//@ no-prefer-dynamic +//@ aux-build: decl_with_default.rs +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Functions can have target-cpu applied. On apple-darwin this is super important, +// since you can have binaries which mix x86 and aarch64 code that are compatible +// with both architectures. So we can't just reject target_cpu on EIIs since apple +// puts them on by default. The problem: we generate aliases. And aliases cannot +// get target_cpu applied to them. So, instead we should, in the case of functions, +// generate a shim function. For statics aliases should keep working in theory. +// In fact, aliases are only necessary for statics. For functions we could just +// always generate a shim and a previous version of EII did so but I was sad +// that that'd never support statics. +//@ ignore-macos +// Tests EIIs with default implementations. +// When there's no explicit declaration, the default should be called from the declaring crate. +#![feature(extern_item_impls)] + +extern crate decl_with_default; + +fn main() { + decl_with_default::decl1(10); +} diff --git a/tests/ui/eii/default/call_default.run.stdout b/tests/ui/eii/default/call_default.run.stdout new file mode 100644 index 000000000000..1e49486f6aaf --- /dev/null +++ b/tests/ui/eii/default/call_default.run.stdout @@ -0,0 +1 @@ +default 10 diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs new file mode 100644 index 000000000000..94b2aa552a1e --- /dev/null +++ b/tests/ui/eii/default/call_impl.rs @@ -0,0 +1,19 @@ +//@ no-prefer-dynamic +//@ aux-build: decl_with_default.rs +//@ aux-build: impl1.rs +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests EIIs with default implementations. +// When an explicit implementation is given in one dependency, and the declaration is in another, +// the explicit implementation is preferred. +#![feature(extern_item_impls)] + +extern crate decl_with_default; +extern crate impl1; + +fn main() { + decl_with_default::decl1(10); +} diff --git a/tests/ui/eii/default/call_impl.run.stdout b/tests/ui/eii/default/call_impl.run.stdout new file mode 100644 index 000000000000..bc6298e80ad4 --- /dev/null +++ b/tests/ui/eii/default/call_impl.run.stdout @@ -0,0 +1 @@ +110 diff --git a/tests/ui/eii/default/local_crate.rs b/tests/ui/eii/default/local_crate.rs new file mode 100644 index 000000000000..d98c2fac4234 --- /dev/null +++ b/tests/ui/eii/default/local_crate.rs @@ -0,0 +1,17 @@ +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests EIIs with default implementations. +// In the same crate, when there's no explicit declaration, the default should be called. +#![feature(extern_item_impls)] + +#[eii(eii1)] +pub fn decl1(x: u64) { + println!("default {x}"); +} + +fn main() { + decl1(4); +} diff --git a/tests/ui/eii/default/local_crate.run.stdout b/tests/ui/eii/default/local_crate.run.stdout new file mode 100644 index 000000000000..032082d92b72 --- /dev/null +++ b/tests/ui/eii/default/local_crate.run.stdout @@ -0,0 +1 @@ +default 4 diff --git a/tests/ui/eii/default/local_crate_explicit.rs b/tests/ui/eii/default/local_crate_explicit.rs new file mode 100644 index 000000000000..a4cc54fcd31f --- /dev/null +++ b/tests/ui/eii/default/local_crate_explicit.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests EIIs with default implementations. +// In the same crate, the explicit implementation should get priority. +#![feature(extern_item_impls)] + +#[eii(eii1)] +pub fn decl1(x: u64) { + //~^ WARN function `decl1` is never used + println!("default {x}"); +} + +#[eii1] +pub fn decl2(x: u64) { + println!("explicit {x}"); +} + +fn main() { + decl1(4); +} diff --git a/tests/ui/eii/default/local_crate_explicit.run.stdout b/tests/ui/eii/default/local_crate_explicit.run.stdout new file mode 100644 index 000000000000..d7ce3a9fb8ba --- /dev/null +++ b/tests/ui/eii/default/local_crate_explicit.run.stdout @@ -0,0 +1 @@ +explicit 4 diff --git a/tests/ui/eii/default/local_crate_explicit.stderr b/tests/ui/eii/default/local_crate_explicit.stderr new file mode 100644 index 000000000000..d80acf14c516 --- /dev/null +++ b/tests/ui/eii/default/local_crate_explicit.stderr @@ -0,0 +1,10 @@ +warning: function `decl1` is never used + --> $DIR/local_crate_explicit.rs:11:8 + | +LL | pub fn decl1(x: u64) { + | ^^^^^ + | + = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/eii/default/multiple-default-impls-same-name.rs b/tests/ui/eii/default/multiple-default-impls-same-name.rs new file mode 100644 index 000000000000..080e0a46b755 --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls-same-name.rs @@ -0,0 +1,19 @@ +#![crate_type = "lib"] +#![feature(extern_item_impls)] +// `eii` expands to, among other things, `macro eii() {}`. +// If we have two eiis named the same thing, we have a duplicate definition +// for that macro. The compiler happily continues compiling on duplicate +// definitions though, to emit as many diagnostics as possible. +// However, in the case of eiis, this can break the assumption that every +// eii has only one default implementation, since the default for both eiis will +// name resolve to the same eii definiton (since the other definition was duplicate) +// This test tests for the previously-ICE that occurred when this assumption +// (of 1 default) was broken which was reported in #149982. + +#[eii(eii1)] +fn a() {} + +#[eii(eii1)] +//~^ ERROR the name `eii1` is defined multiple times +fn a() {} +//~^ ERROR the name `a` is defined multiple times diff --git a/tests/ui/eii/default/multiple-default-impls-same-name.stderr b/tests/ui/eii/default/multiple-default-impls-same-name.stderr new file mode 100644 index 000000000000..20544fcfeeba --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls-same-name.stderr @@ -0,0 +1,25 @@ +error[E0428]: the name `a` is defined multiple times + --> $DIR/multiple-default-impls-same-name.rs:18:1 + | +LL | fn a() {} + | ------ previous definition of the value `a` here +... +LL | fn a() {} + | ^^^^^^ `a` redefined here + | + = note: `a` must be defined only once in the value namespace of this module + +error[E0428]: the name `eii1` is defined multiple times + --> $DIR/multiple-default-impls-same-name.rs:16:1 + | +LL | #[eii(eii1)] + | ------------ previous definition of the macro `eii1` here +... +LL | #[eii(eii1)] + | ^^^^^^^^^^^^ `eii1` redefined here + | + = note: `eii1` must be defined only once in the macro namespace of this module + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui/eii/default/multiple-default-impls.rs b/tests/ui/eii/default/multiple-default-impls.rs new file mode 100644 index 000000000000..8d2ad0c1e137 --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] +#![feature(extern_item_impls)] +// `eii` expands to, among other things, `macro eii() {}`. +// If we have two eiis named the same thing, we have a duplicate definition +// for that macro. The compiler happily continues compiling on duplicate +// definitions though, to emit as many diagnostics as possible. +// However, in the case of eiis, this can break the assumption that every +// eii has only one default implementation, since the default for both eiis will +// name resolve to the same eii definiton (since the other definition was duplicate) +// This test tests for the previously-ICE that occurred when this assumption +// (of 1 default) was broken which was reported in #149982. + +#[eii(eii1)] +fn a() {} + +#[eii(eii1)] +//~^ ERROR the name `eii1` is defined multiple times +fn b() {} diff --git a/tests/ui/eii/default/multiple-default-impls.stderr b/tests/ui/eii/default/multiple-default-impls.stderr new file mode 100644 index 000000000000..b270b2346cd5 --- /dev/null +++ b/tests/ui/eii/default/multiple-default-impls.stderr @@ -0,0 +1,14 @@ +error[E0428]: the name `eii1` is defined multiple times + --> $DIR/multiple-default-impls.rs:16:1 + | +LL | #[eii(eii1)] + | ------------ previous definition of the macro `eii1` here +... +LL | #[eii(eii1)] + | ^^^^^^^^^^^^ `eii1` redefined here + | + = note: `eii1` must be defined only once in the macro namespace of this module + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui/eii/duplicate/auxiliary/decl.rs b/tests/ui/eii/duplicate/auxiliary/decl.rs new file mode 100644 index 000000000000..2a0661715bfd --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/decl.rs @@ -0,0 +1,6 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +#[eii(eii1)] +fn decl1(x: u64); diff --git a/tests/ui/eii/duplicate/auxiliary/impl1.rs b/tests/ui/eii/duplicate/auxiliary/impl1.rs new file mode 100644 index 000000000000..e99932c69b90 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl1.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("1{x}"); +} diff --git a/tests/ui/eii/duplicate/auxiliary/impl2.rs b/tests/ui/eii/duplicate/auxiliary/impl2.rs new file mode 100644 index 000000000000..3a09c824b829 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl2.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("2{x}"); +} diff --git a/tests/ui/eii/duplicate/auxiliary/impl3.rs b/tests/ui/eii/duplicate/auxiliary/impl3.rs new file mode 100644 index 000000000000..09bdd8509da2 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl3.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("3{x}"); +} diff --git a/tests/ui/eii/duplicate/auxiliary/impl4.rs b/tests/ui/eii/duplicate/auxiliary/impl4.rs new file mode 100644 index 000000000000..fd68a83de125 --- /dev/null +++ b/tests/ui/eii/duplicate/auxiliary/impl4.rs @@ -0,0 +1,12 @@ +//@ no-prefer-dynamic +//@ aux-build: decl.rs +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +extern crate decl; + + +#[unsafe(decl::eii1)] +fn other(x: u64) { + println!("4{x}"); +} diff --git a/tests/ui/eii/duplicate/duplicate1.rs b/tests/ui/eii/duplicate/duplicate1.rs new file mode 100644 index 000000000000..3269778aca0c --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate1.rs @@ -0,0 +1,16 @@ +//@ no-prefer-dynamic +//@ aux-build: impl1.rs +//@ aux-build: impl2.rs +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// tests that EIIs error properly, even if the conflicting implementations live in another crate. +#![feature(extern_item_impls)] + +// has a span but in the other crate +//~? ERROR multiple implementations of `#[eii1]` + +extern crate impl1; +extern crate impl2; + +fn main() {} diff --git a/tests/ui/eii/duplicate/duplicate1.stderr b/tests/ui/eii/duplicate/duplicate1.stderr new file mode 100644 index 000000000000..54cc141f8869 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate1.stderr @@ -0,0 +1,15 @@ +error: multiple implementations of `#[eii1]` + --> $DIR/auxiliary/impl1.rs:10:1 + | +LL | fn other(x: u64) { + | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` + | + ::: $DIR/auxiliary/impl2.rs:10:1 + | +LL | fn other(x: u64) { + | ---------------- also implemented here in crate `impl2` + | + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/duplicate/duplicate2.rs b/tests/ui/eii/duplicate/duplicate2.rs new file mode 100644 index 000000000000..4c883d28d74a --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate2.rs @@ -0,0 +1,18 @@ +//@ no-prefer-dynamic +//@ aux-build: impl1.rs +//@ aux-build: impl2.rs +//@ aux-build: impl3.rs +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests the error message when there are multiple implementations of an EII in many crates. +#![feature(extern_item_impls)] + +// has a span but in the other crate +//~? ERROR multiple implementations of `#[eii1]` + +extern crate impl1; +extern crate impl2; +extern crate impl3; + +fn main() {} diff --git a/tests/ui/eii/duplicate/duplicate2.stderr b/tests/ui/eii/duplicate/duplicate2.stderr new file mode 100644 index 000000000000..033e43c8b2fb --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate2.stderr @@ -0,0 +1,16 @@ +error: multiple implementations of `#[eii1]` + --> $DIR/auxiliary/impl1.rs:10:1 + | +LL | fn other(x: u64) { + | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` + | + ::: $DIR/auxiliary/impl2.rs:10:1 + | +LL | fn other(x: u64) { + | ---------------- also implemented here in crate `impl2` + | + = note: in addition to these two, another implementation was found in crate `impl3` + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/duplicate/duplicate3.rs b/tests/ui/eii/duplicate/duplicate3.rs new file mode 100644 index 000000000000..b04676074509 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate3.rs @@ -0,0 +1,20 @@ +//@ no-prefer-dynamic +//@ aux-build: impl1.rs +//@ aux-build: impl2.rs +//@ aux-build: impl3.rs +//@ aux-build: impl4.rs +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests the error message when there are multiple implementations of an EII in many crates. +#![feature(extern_item_impls)] + +// has a span but in the other crate +//~? ERROR multiple implementations of `#[eii1]` + +extern crate impl1; +extern crate impl2; +extern crate impl3; +extern crate impl4; + +fn main() {} diff --git a/tests/ui/eii/duplicate/duplicate3.stderr b/tests/ui/eii/duplicate/duplicate3.stderr new file mode 100644 index 000000000000..801d40e69c55 --- /dev/null +++ b/tests/ui/eii/duplicate/duplicate3.stderr @@ -0,0 +1,16 @@ +error: multiple implementations of `#[eii1]` + --> $DIR/auxiliary/impl1.rs:10:1 + | +LL | fn other(x: u64) { + | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` + | + ::: $DIR/auxiliary/impl2.rs:10:1 + | +LL | fn other(x: u64) { + | ---------------- also implemented here in crate `impl2` + | + = note: in addition to these two, more implementations were also found in the following crates: `impl3`, `impl4` + = help: an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs new file mode 100644 index 000000000000..d8118f8417a0 --- /dev/null +++ b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs @@ -0,0 +1,7 @@ +//@ compile-flags: --crate-type rlib +//@ build-pass +#![feature(extern_item_impls)] + +macro_rules! foo_impl { () => {} } +#[eii] +fn foo_impl() {} diff --git a/tests/ui/eii/duplicate/multiple_decls.rs b/tests/ui/eii/duplicate/multiple_decls.rs new file mode 100644 index 000000000000..f7646630cab4 --- /dev/null +++ b/tests/ui/eii/duplicate/multiple_decls.rs @@ -0,0 +1,17 @@ +// Tests whether only one EII attribute cane be applied to a signature. +#![feature(extern_item_impls)] + +#[eii(a)] +#[eii(b)] +//~^ ERROR `#[eii]` can only be specified once +fn a(x: u64); + +#[a] +fn implementation(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + a(42); +} diff --git a/tests/ui/eii/duplicate/multiple_decls.stderr b/tests/ui/eii/duplicate/multiple_decls.stderr new file mode 100644 index 000000000000..e9e68ea74629 --- /dev/null +++ b/tests/ui/eii/duplicate/multiple_decls.stderr @@ -0,0 +1,14 @@ +error: `#[eii]` can only be specified once + --> $DIR/multiple_decls.rs:5:1 + | +LL | #[eii(b)] + | ^^^^^^^^^ + | +note: specified again here + --> $DIR/multiple_decls.rs:4:1 + | +LL | #[eii(a)] + | ^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/duplicate/multiple_impls.rs b/tests/ui/eii/duplicate/multiple_impls.rs new file mode 100644 index 000000000000..c02c783223ac --- /dev/null +++ b/tests/ui/eii/duplicate/multiple_impls.rs @@ -0,0 +1,25 @@ +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests whether one function could implement two EIIs. +#![feature(extern_item_impls)] + +#[eii] +fn a(x: u64); + +#[eii] +fn b(x: u64); + +#[a] +#[b] +fn implementation(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + a(42); + b(42); +} diff --git a/tests/ui/eii/duplicate/multiple_impls.run.stdout b/tests/ui/eii/duplicate/multiple_impls.run.stdout new file mode 100644 index 000000000000..daaac9e30302 --- /dev/null +++ b/tests/ui/eii/duplicate/multiple_impls.run.stdout @@ -0,0 +1,2 @@ +42 +42 diff --git a/tests/ui/eii/error_statement_position.rs b/tests/ui/eii/error_statement_position.rs new file mode 100644 index 000000000000..75d87595b9e3 --- /dev/null +++ b/tests/ui/eii/error_statement_position.rs @@ -0,0 +1,17 @@ +#![feature(extern_item_impls)] +// EIIs cannot be used in statement position. +// This is also a regression test for an ICE (https://github.com/rust-lang/rust/issues/149980). + +fn main() { + struct Bar; + + #[eii] + //~^ ERROR `#[eii]` is only valid on functions + impl Bar {} + + + // Even on functions, eiis in statement position are rejected + #[eii] + //~^ ERROR `#[eii]` can only be used on functions inside a module + fn foo() {} +} diff --git a/tests/ui/eii/error_statement_position.stderr b/tests/ui/eii/error_statement_position.stderr new file mode 100644 index 000000000000..f14e6c33e64f --- /dev/null +++ b/tests/ui/eii/error_statement_position.stderr @@ -0,0 +1,17 @@ +error: `#[eii]` is only valid on functions + --> $DIR/error_statement_position.rs:8:5 + | +LL | #[eii] + | ^^^^^^ + +error: `#[eii]` can only be used on functions inside a module + --> $DIR/error_statement_position.rs:14:5 + | +LL | #[eii] + | ^^^^^^ +LL | +LL | fn foo() {} + | --- `#[eii]` is used on this item, which is part of another item's local scope + +error: aborting due to 2 previous errors + diff --git a/tests/ui/eii/errors.rs b/tests/ui/eii/errors.rs new file mode 100644 index 000000000000..5fcf33336b40 --- /dev/null +++ b/tests/ui/eii/errors.rs @@ -0,0 +1,45 @@ +//@ compile-flags: --crate-type rlib +// Tests all the kinds of errors when EII attributes are used with wrong syntax. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] //~ ERROR `#[eii_declaration(...)]` is only valid on macros +fn hello() { + #[eii_declaration(bar)] //~ ERROR `#[eii_declaration(...)]` is only valid on macros + let x = 3 + 3; +} + +#[eii_declaration] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration()] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration(bar, hello)] //~ ERROR expected this argument to be "unsafe" +#[eii_declaration(bar, "unsafe", hello)] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration(bar, hello, "unsafe")] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration = "unsafe"] //~ ERROR `#[eii_declaration(...)]` expects a list of one or two elements +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] //~ ERROR `#[foo]` is only valid on functions +static X: u64 = 4; +#[foo] //~ ERROR `#[foo]` is only valid on functions +const Y: u64 = 4; +#[foo] //~ ERROR `#[foo]` is only valid on functions +macro bar() {} + +#[foo()] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +#[foo(default, bar)] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +#[foo("default")] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +#[foo = "default"] +//~^ ERROR `#[foo]` expected no arguments or a single argument: `#[foo(default)]` +fn other(x: u64) -> u64 { + x +} diff --git a/tests/ui/eii/errors.stderr b/tests/ui/eii/errors.stderr new file mode 100644 index 000000000000..c7eb96a9c219 --- /dev/null +++ b/tests/ui/eii/errors.stderr @@ -0,0 +1,98 @@ +error: `#[eii_declaration(...)]` is only valid on macros + --> $DIR/errors.rs:8:1 + | +LL | #[eii_declaration(bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_declaration(...)]` is only valid on macros + --> $DIR/errors.rs:10:5 + | +LL | #[eii_declaration(bar)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_declaration(...)]` expects a list of one or two elements + --> $DIR/errors.rs:14:1 + | +LL | #[eii_declaration] + | ^^^^^^^^^^^^^^^^^^ + +error: `#[eii_declaration(...)]` expects a list of one or two elements + --> $DIR/errors.rs:15:1 + | +LL | #[eii_declaration()] + | ^^^^^^^^^^^^^^^^^^^^ + +error: expected this argument to be "unsafe" + --> $DIR/errors.rs:16:24 + | +LL | #[eii_declaration(bar, hello)] + | ^^^^^ + | +note: the second argument is optional + --> $DIR/errors.rs:16:24 + | +LL | #[eii_declaration(bar, hello)] + | ^^^^^ + +error: `#[eii_declaration(...)]` expects a list of one or two elements + --> $DIR/errors.rs:17:1 + | +LL | #[eii_declaration(bar, "unsafe", hello)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_declaration(...)]` expects a list of one or two elements + --> $DIR/errors.rs:18:1 + | +LL | #[eii_declaration(bar, hello, "unsafe")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[eii_declaration(...)]` expects a list of one or two elements + --> $DIR/errors.rs:19:1 + | +LL | #[eii_declaration = "unsafe"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/errors.rs:28:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/errors.rs:30:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[foo]` is only valid on functions + --> $DIR/errors.rs:32:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:35:1 + | +LL | #[foo()] + | ^^^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:37:1 + | +LL | #[foo(default, bar)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:39:1 + | +LL | #[foo("default")] + | ^^^^^^^^^^^^^^^^^ + +error: `#[foo]` expected no arguments or a single argument: `#[foo(default)]` + --> $DIR/errors.rs:41:1 + | +LL | #[foo = "default"] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 15 previous errors + diff --git a/tests/ui/eii/linking/auxiliary/codegen_cross_crate_other_crate.rs b/tests/ui/eii/linking/auxiliary/codegen_cross_crate_other_crate.rs new file mode 100644 index 000000000000..7e0ba5f971c3 --- /dev/null +++ b/tests/ui/eii/linking/auxiliary/codegen_cross_crate_other_crate.rs @@ -0,0 +1,6 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(extern_item_impls)] + +#[eii(eii1)] +pub fn decl1(x: u64); diff --git a/tests/ui/eii/linking/codegen_cross_crate.rs b/tests/ui/eii/linking/codegen_cross_crate.rs new file mode 100644 index 000000000000..4016712e7504 --- /dev/null +++ b/tests/ui/eii/linking/codegen_cross_crate.rs @@ -0,0 +1,24 @@ +//@ run-pass +//@ check-run-results +//@ aux-build: codegen_cross_crate_other_crate.rs +//@ compile-flags: -O +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests whether calling EIIs works with the declaration in another crate. +#![feature(extern_item_impls)] + +extern crate codegen_cross_crate_other_crate as codegen; + +#[codegen::eii1] +fn eii1_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + eii1_impl(21); + // through the alias + codegen::decl1(42); +} diff --git a/tests/ui/eii/linking/codegen_cross_crate.run.stdout b/tests/ui/eii/linking/codegen_cross_crate.run.stdout new file mode 100644 index 000000000000..960b54672100 --- /dev/null +++ b/tests/ui/eii/linking/codegen_cross_crate.run.stdout @@ -0,0 +1,2 @@ +21 +42 diff --git a/tests/ui/eii/linking/codegen_single_crate.rs b/tests/ui/eii/linking/codegen_single_crate.rs new file mode 100644 index 000000000000..8e85c354bba1 --- /dev/null +++ b/tests/ui/eii/linking/codegen_single_crate.rs @@ -0,0 +1,23 @@ +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests whether calling EIIs works with the declaration in the same crate. +#![feature(extern_item_impls)] + +#[eii] +fn hello(x: u64); + +#[hello] +fn hello_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + hello_impl(21); + // through the alias + hello(42); +} diff --git a/tests/ui/eii/linking/codegen_single_crate.run.stdout b/tests/ui/eii/linking/codegen_single_crate.run.stdout new file mode 100644 index 000000000000..960b54672100 --- /dev/null +++ b/tests/ui/eii/linking/codegen_single_crate.run.stdout @@ -0,0 +1,2 @@ +21 +42 diff --git a/tests/ui/eii/linking/same-symbol.rs b/tests/ui/eii/linking/same-symbol.rs new file mode 100644 index 000000000000..baf36ff4f5a0 --- /dev/null +++ b/tests/ui/eii/linking/same-symbol.rs @@ -0,0 +1,31 @@ +//@ run-pass +//@ check-run-results +//@ ignore-backends: gcc +// FIXME: linking on windows (speciifcally mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +#![feature(extern_item_impls)] + +pub mod a { + #[eii(foo)] + pub fn foo(); +} + +pub mod b { + #[eii(foo)] + pub fn foo(); +} + +#[a::foo] +fn a_foo_impl() { + println!("foo1"); +} + +#[b::foo] +fn b_foo_impl() { + println!("foo2"); +} + +fn main() { + a::foo(); + b::foo(); +} diff --git a/tests/ui/eii/linking/same-symbol.run.stdout b/tests/ui/eii/linking/same-symbol.run.stdout new file mode 100644 index 000000000000..463021151d29 --- /dev/null +++ b/tests/ui/eii/linking/same-symbol.run.stdout @@ -0,0 +1,2 @@ +foo1 +foo2 diff --git a/tests/ui/eii/privacy1.rs b/tests/ui/eii/privacy1.rs new file mode 100644 index 000000000000..72aec83d2cee --- /dev/null +++ b/tests/ui/eii/privacy1.rs @@ -0,0 +1,34 @@ +//@ run-pass +//@ check-run-results +//@ aux-build: other_crate_privacy1.rs +//@ ignore-backends: gcc +// FIXME: linking on windows (specifically mingw) not yet supported, see tracking issue #125418 +//@ ignore-windows +// Tests whether re-exports work. +#![feature(extern_item_impls)] + +extern crate other_crate_privacy1 as codegen; + +#[codegen::eii1] +fn eii1_impl(x: u64) { + println!("{x:?}") +} + + +#[codegen::eii3] +fn eii3_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + eii1_impl(21); + // through the alias + codegen::local_call_decl1(42); + + // directly + eii3_impl(12); + // through the alias + codegen::decl3(24); +} diff --git a/tests/ui/eii/privacy1.run.stdout b/tests/ui/eii/privacy1.run.stdout new file mode 100644 index 000000000000..c76239918563 --- /dev/null +++ b/tests/ui/eii/privacy1.run.stdout @@ -0,0 +1,4 @@ +21 +42 +12 +24 diff --git a/tests/ui/eii/privacy2.rs b/tests/ui/eii/privacy2.rs new file mode 100644 index 000000000000..c11061f311ed --- /dev/null +++ b/tests/ui/eii/privacy2.rs @@ -0,0 +1,27 @@ +//@ aux-build:other_crate_privacy2.rs +// Tests whether name resolution respects privacy properly. +#![feature(extern_item_impls)] + +extern crate other_crate_privacy2 as codegen; + +// has a span but in the other crate +//~? ERROR `#[eii2]` required, but not found +//~? ERROR `#[eii3]` required, but not found + +#[codegen::eii1] +fn eii1_impl(x: u64) { + println!("{x:?}") +} + +#[codegen::eii3] //~ ERROR cannot find `eii3` in `codegen` +fn eii3_impl(x: u64) { + println!("{x:?}") +} + +// what you would write: +fn main() { + // directly + eii1_impl(21); + // through the alias + codegen::decl1(42); //~ ERROR function `decl1` is private +} diff --git a/tests/ui/eii/privacy2.stderr b/tests/ui/eii/privacy2.stderr new file mode 100644 index 000000000000..f0a04bf63561 --- /dev/null +++ b/tests/ui/eii/privacy2.stderr @@ -0,0 +1,38 @@ +error[E0433]: cannot find `eii3` in `codegen` + --> $DIR/privacy2.rs:16:12 + | +LL | #[codegen::eii3] + | ^^^^ could not find `eii3` in `codegen` + +error[E0603]: function `decl1` is private + --> $DIR/privacy2.rs:26:14 + | +LL | codegen::decl1(42); + | ^^^^^ private function + | +note: the function `decl1` is defined here + --> $DIR/auxiliary/other_crate_privacy2.rs:7:1 + | +LL | fn decl1(x: u64); + | ^^^^^^^^^^^^^^^^^ + +error: `#[eii2]` required, but not found + --> $DIR/auxiliary/other_crate_privacy2.rs:9:7 + | +LL | #[eii(eii2)] + | ^^^^ expected because `#[eii2]` was declared here in crate `other_crate_privacy2` + | + = help: expected at least one implementation in crate `privacy2` or any of its dependencies + +error: `#[eii3]` required, but not found + --> $DIR/auxiliary/other_crate_privacy2.rs:13:11 + | +LL | #[eii(eii3)] + | ^^^^ expected because `#[eii3]` was declared here in crate `other_crate_privacy2` + | + = help: expected at least one implementation in crate `privacy2` or any of its dependencies + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0433, E0603. +For more information about an error, try `rustc --explain E0433`. diff --git a/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs b/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs new file mode 100644 index 000000000000..95ae5d923b60 --- /dev/null +++ b/tests/ui/eii/type_checking/auxiliary/cross_crate_eii_declaration.rs @@ -0,0 +1,14 @@ +//@ no-prefer-dynamic +#![crate_type = "rlib"] +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +pub macro foo() {} + +unsafe extern "Rust" { + pub safe fn bar(x: u64) -> u64; +} diff --git a/tests/ui/eii/type_checking/cross_crate_type_ok.rs b/tests/ui/eii/type_checking/cross_crate_type_ok.rs new file mode 100644 index 000000000000..157d659bfd64 --- /dev/null +++ b/tests/ui/eii/type_checking/cross_crate_type_ok.rs @@ -0,0 +1,19 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +//@ aux-build: cross_crate_eii_declaration.rs +// Tests whether calling EIIs works with the declaration in another crate. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +extern crate cross_crate_eii_declaration; + +#[unsafe(cross_crate_eii_declaration::foo)] +fn other(x: u64) -> u64 { + x +} + +fn main() { + cross_crate_eii_declaration::bar(0); +} diff --git a/tests/ui/eii/type_checking/cross_crate_wrong_ty.rs b/tests/ui/eii/type_checking/cross_crate_wrong_ty.rs new file mode 100644 index 000000000000..7ae1a5995a86 --- /dev/null +++ b/tests/ui/eii/type_checking/cross_crate_wrong_ty.rs @@ -0,0 +1,19 @@ +//@ compile-flags: --crate-type rlib +//@ aux-build: cross_crate_eii_declaration.rs +// Tests whether the type checking still works properly when the declaration is in another crate. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +extern crate cross_crate_eii_declaration; + +#[unsafe(cross_crate_eii_declaration::foo)] +fn other() -> u64 { +//~^ ERROR `other` has 0 parameters but #[foo] requires it to have 1 + 0 +} + +fn main() { + cross_crate_eii_declaration::bar(0); +} diff --git a/tests/ui/eii/type_checking/cross_crate_wrong_ty.stderr b/tests/ui/eii/type_checking/cross_crate_wrong_ty.stderr new file mode 100644 index 000000000000..b2190a075b63 --- /dev/null +++ b/tests/ui/eii/type_checking/cross_crate_wrong_ty.stderr @@ -0,0 +1,16 @@ +error[E0806]: `other` has 0 parameters but #[foo] requires it to have 1 + --> $DIR/cross_crate_wrong_ty.rs:12:1 + | +LL | #[unsafe(cross_crate_eii_declaration::foo)] + | ------------------------------------------- required because of this attribute +LL | fn other() -> u64 { + | ^^^^^^^^^^^^^^^^^ expected 1 parameter, found 0 + | + ::: $DIR/auxiliary/cross_crate_eii_declaration.rs:13:5 + | +LL | pub safe fn bar(x: u64) -> u64; + | ------------------------------- requires 1 parameter + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/eii/type_checking/generic_implementation.rs b/tests/ui/eii/type_checking/generic_implementation.rs new file mode 100644 index 000000000000..489fd2e645d8 --- /dev/null +++ b/tests/ui/eii/type_checking/generic_implementation.rs @@ -0,0 +1,13 @@ +//@ check-fail +// Check that type parameters on EIIs are properly rejected. +// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983. +#![feature(extern_item_impls)] + +#[eii] +fn foo(); + +#[foo] +fn foo_impl() {} +//~^ ERROR `foo_impl` cannot have generic parameters other than lifetimes + +fn main() {} diff --git a/tests/ui/eii/type_checking/generic_implementation.stderr b/tests/ui/eii/type_checking/generic_implementation.stderr new file mode 100644 index 000000000000..17a71998423d --- /dev/null +++ b/tests/ui/eii/type_checking/generic_implementation.stderr @@ -0,0 +1,12 @@ +error: `foo_impl` cannot have generic parameters other than lifetimes + --> $DIR/generic_implementation.rs:10:1 + | +LL | #[foo] + | ------ required by this attribute +LL | fn foo_impl() {} + | ^^^^^^^^^^^^^^^^ + | + = help: `#[foo]` marks the implementation of an "externally implementable item" + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/type_checking/subtype_1.rs b/tests/ui/eii/type_checking/subtype_1.rs new file mode 100644 index 000000000000..d853bc4e7e3d --- /dev/null +++ b/tests/ui/eii/type_checking/subtype_1.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: +// Tests whether it's not ok when the lifetimes are different between the decl and impl. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar<'a, 'b>(x: &'b u64) -> &'a u64; +} + +#[foo] +fn other<'a, 'b>(x: &'b u64) -> &'b u64 { + //~^ ERROR lifetime parameters or bounds of `other` do not match the declaration + &0 +} + +fn main() { + bar(&0); +} diff --git a/tests/ui/eii/type_checking/subtype_1.stderr b/tests/ui/eii/type_checking/subtype_1.stderr new file mode 100644 index 000000000000..6a4ef6e16f9d --- /dev/null +++ b/tests/ui/eii/type_checking/subtype_1.stderr @@ -0,0 +1,13 @@ +error: lifetime parameters or bounds of `other` do not match the declaration + --> $DIR/subtype_1.rs:18:9 + | +LL | safe fn bar<'a, 'b>(x: &'b u64) -> &'a u64; + | -------- lifetimes in impl do not match this signature +... +LL | #[foo] + | ------ required because of this attribute +LL | fn other<'a, 'b>(x: &'b u64) -> &'b u64 { + | ^^^^^^^^ lifetimes do not match + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/type_checking/subtype_2.rs b/tests/ui/eii/type_checking/subtype_2.rs new file mode 100644 index 000000000000..d2b2eb073de2 --- /dev/null +++ b/tests/ui/eii/type_checking/subtype_2.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: +// Tests whether it's not ok when the implementation is less general. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar<'a>(x: &'static u64) -> &'a u64; +} + +#[foo] +fn other<'a>(x: &'a u64) -> &'static u64 { + //~^ ERROR lifetime parameters or bounds of `other` do not match the declaration + &0 +} + +fn main() { + bar(&0); +} diff --git a/tests/ui/eii/type_checking/subtype_2.stderr b/tests/ui/eii/type_checking/subtype_2.stderr new file mode 100644 index 000000000000..5c925ca380e0 --- /dev/null +++ b/tests/ui/eii/type_checking/subtype_2.stderr @@ -0,0 +1,13 @@ +error: lifetime parameters or bounds of `other` do not match the declaration + --> $DIR/subtype_2.rs:18:9 + | +LL | safe fn bar<'a>(x: &'static u64) -> &'a u64; + | ---- lifetimes in impl do not match this signature +... +LL | #[foo] + | ------ required because of this attribute +LL | fn other<'a>(x: &'a u64) -> &'static u64 { + | ^^^^ lifetimes do not match + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/type_checking/subtype_3.rs b/tests/ui/eii/type_checking/subtype_3.rs new file mode 100644 index 000000000000..458bacf4a772 --- /dev/null +++ b/tests/ui/eii/type_checking/subtype_3.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +// Uses manual desugaring of EII internals: +// Tests whether it's ok when the implementation is more general. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar<'a>(x: &'a u64) -> &'a u64; +} + +#[foo] +fn other<'a>(x: &'a u64) -> &'static u64 { + &0 +} + +fn main() { + bar(&0); +} diff --git a/tests/ui/eii/type_checking/subtype_4.rs b/tests/ui/eii/type_checking/subtype_4.rs new file mode 100644 index 000000000000..6f1e4253dd73 --- /dev/null +++ b/tests/ui/eii/type_checking/subtype_4.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +// Uses manual desugaring of EII internals: +// Tests whether it's ok when giving the right types. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other(x: u64) -> u64 { + x +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/type_checking/type_params_149983.rs b/tests/ui/eii/type_checking/type_params_149983.rs new file mode 100644 index 000000000000..6dc9b309712e --- /dev/null +++ b/tests/ui/eii/type_checking/type_params_149983.rs @@ -0,0 +1,10 @@ +//@ check-fail +// Check that type parameters on EIIs are properly rejected. +// Specifically a regression test for https://github.com/rust-lang/rust/issues/149983. +#![feature(extern_item_impls)] + +#[eii] +fn foo() {} +//~^ ERROR externally implementable items may not have type parameters + +fn main() {} diff --git a/tests/ui/eii/type_checking/type_params_149983.stderr b/tests/ui/eii/type_checking/type_params_149983.stderr new file mode 100644 index 000000000000..11f06e6c88e2 --- /dev/null +++ b/tests/ui/eii/type_checking/type_params_149983.stderr @@ -0,0 +1,11 @@ +error[E0044]: externally implementable items may not have type parameters + --> $DIR/type_params_149983.rs:7:1 + | +LL | fn foo() {} + | ^^^^^^^^^^^ can't have type parameters + | + = help: replace the type parameters with concrete types like `u32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0044`. diff --git a/tests/ui/eii/type_checking/wrong_ret_ty.rs b/tests/ui/eii/type_checking/wrong_ret_ty.rs new file mode 100644 index 000000000000..8ee81a4f2465 --- /dev/null +++ b/tests/ui/eii/type_checking/wrong_ret_ty.rs @@ -0,0 +1,23 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: tests whether the return type matches. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other(_x: u64) { + //~^ ERROR function `other` has a type that is incompatible with the declaration +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/type_checking/wrong_ret_ty.stderr b/tests/ui/eii/type_checking/wrong_ret_ty.stderr new file mode 100644 index 000000000000..0f7e9580aa37 --- /dev/null +++ b/tests/ui/eii/type_checking/wrong_ret_ty.stderr @@ -0,0 +1,26 @@ +error[E0806]: function `other` has a type that is incompatible with the declaration of `#[foo]` + --> $DIR/wrong_ret_ty.rs:17:18 + | +LL | fn other(_x: u64) { + | ^ expected `u64`, found `()` + | +note: expected this because of this attribute + --> $DIR/wrong_ret_ty.rs:16:1 + | +LL | #[foo] + | ^^^^^^ +note: type in declaration + --> $DIR/wrong_ret_ty.rs:13:28 + | +LL | safe fn bar(x: u64) -> u64; + | ^^^ + = note: expected signature `fn(_) -> u64` + found signature `fn(_) -> ()` +help: change the output type to match the declaration + | +LL | fn other(_x: u64) -> u64 { + | ++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/eii/type_checking/wrong_ty.rs b/tests/ui/eii/type_checking/wrong_ty.rs new file mode 100644 index 000000000000..625af6e11dbf --- /dev/null +++ b/tests/ui/eii/type_checking/wrong_ty.rs @@ -0,0 +1,24 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: tests whether the types of parameters match. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other(x: usize) -> u64 { + //~^ ERROR function `other` has a type that is incompatible with the declaration + 3 +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/type_checking/wrong_ty.stderr b/tests/ui/eii/type_checking/wrong_ty.stderr new file mode 100644 index 000000000000..0513cec97fae --- /dev/null +++ b/tests/ui/eii/type_checking/wrong_ty.stderr @@ -0,0 +1,27 @@ +error[E0806]: function `other` has a type that is incompatible with the declaration of `#[foo]` + --> $DIR/wrong_ty.rs:17:13 + | +LL | fn other(x: usize) -> u64 { + | ^^^^^ expected `u64`, found `usize` + | +note: expected this because of this attribute + --> $DIR/wrong_ty.rs:16:1 + | +LL | #[foo] + | ^^^^^^ +note: type in declaration + --> $DIR/wrong_ty.rs:13:20 + | +LL | safe fn bar(x: u64) -> u64; + | ^^^ + = note: expected signature `fn(u64) -> _` + found signature `fn(usize) -> _` +help: change the parameter type to match the declaration + | +LL - fn other(x: usize) -> u64 { +LL + fn other(x: u64) -> u64 { + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/eii/type_checking/wrong_ty_2.rs b/tests/ui/eii/type_checking/wrong_ty_2.rs new file mode 100644 index 000000000000..2e477b5b6fcc --- /dev/null +++ b/tests/ui/eii/type_checking/wrong_ty_2.rs @@ -0,0 +1,24 @@ +//@ compile-flags: --crate-type rlib +// Uses manual desugaring of EII internals: tests whether the number of parameters matches. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar)] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] +fn other() -> u64 { + //~^ ERROR `other` has 0 parameters but #[foo] requires it to have + 3 +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/type_checking/wrong_ty_2.stderr b/tests/ui/eii/type_checking/wrong_ty_2.stderr new file mode 100644 index 000000000000..327d28e41370 --- /dev/null +++ b/tests/ui/eii/type_checking/wrong_ty_2.stderr @@ -0,0 +1,14 @@ +error[E0806]: `other` has 0 parameters but #[foo] requires it to have 1 + --> $DIR/wrong_ty_2.rs:17:1 + | +LL | safe fn bar(x: u64) -> u64; + | --- requires 1 parameter +... +LL | #[foo] + | ------ required because of this attribute +LL | fn other() -> u64 { + | ^^^^^^^^^^^^^^^^^ expected 1 parameter, found 0 + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/eii/unsafe_impl_err.rs b/tests/ui/eii/unsafe_impl_err.rs new file mode 100644 index 000000000000..a6d24c47ae21 --- /dev/null +++ b/tests/ui/eii/unsafe_impl_err.rs @@ -0,0 +1,23 @@ +//@ compile-flags: --crate-type rlib +// Tests whether it's an error to implement an unsafe EII safely. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar, "unsafe")] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[foo] //~ ERROR `#[foo]` is unsafe to implement +fn other(x: u64) -> u64 { + x +} + +fn main() { + bar(0); +} diff --git a/tests/ui/eii/unsafe_impl_err.stderr b/tests/ui/eii/unsafe_impl_err.stderr new file mode 100644 index 000000000000..eb917a65bb52 --- /dev/null +++ b/tests/ui/eii/unsafe_impl_err.stderr @@ -0,0 +1,13 @@ +error: `#[foo]` is unsafe to implement + --> $DIR/unsafe_impl_err.rs:16:1 + | +LL | #[foo] + | ^^^^^^ + | +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe(foo)] + | +++++++ + + +error: aborting due to 1 previous error + diff --git a/tests/ui/eii/unsafe_impl_ok.rs b/tests/ui/eii/unsafe_impl_ok.rs new file mode 100644 index 000000000000..1af6d63eb7cf --- /dev/null +++ b/tests/ui/eii/unsafe_impl_ok.rs @@ -0,0 +1,25 @@ +//@ compile-flags: --crate-type rlib +//@ check-pass +// Uses manual desugaring of EII internals: +// Tests whether it's okay to implement an unsafe EII with an unsafe implementation. +#![feature(extern_item_impls)] +#![feature(decl_macro)] +#![feature(rustc_attrs)] +#![feature(eii_internals)] + +#[eii_declaration(bar, "unsafe")] +#[rustc_builtin_macro(eii_shared_macro)] +macro foo() {} + +unsafe extern "Rust" { + safe fn bar(x: u64) -> u64; +} + +#[unsafe(foo)] +fn other(x: u64) -> u64 { + x +} + +fn main() { + bar(0); +} diff --git a/tests/ui/empty/empty-struct-unit-expr.rs b/tests/ui/empty/empty-struct-unit-expr.rs index c71ea3bdce72..5a0d57edb13d 100644 --- a/tests/ui/empty/empty-struct-unit-expr.rs +++ b/tests/ui/empty/empty-struct-unit-expr.rs @@ -1,4 +1,5 @@ // Can't use unit struct as constructor function +// related issue //@ aux-build:empty-struct.rs @@ -8,7 +9,7 @@ use empty_struct::*; struct Empty2; enum E { - Empty4 + Empty4, } fn main() { diff --git a/tests/ui/empty/empty-struct-unit-expr.stderr b/tests/ui/empty/empty-struct-unit-expr.stderr index e97209527fe3..511c144f926c 100644 --- a/tests/ui/empty/empty-struct-unit-expr.stderr +++ b/tests/ui/empty/empty-struct-unit-expr.stderr @@ -1,5 +1,5 @@ error[E0618]: expected function, found struct `Empty2` - --> $DIR/empty-struct-unit-expr.rs:15:14 + --> $DIR/empty-struct-unit-expr.rs:16:14 | LL | struct Empty2; | ------------- struct `Empty2` defined here @@ -16,9 +16,9 @@ LL + let e2 = Empty2; | error[E0618]: expected function, found enum variant `E::Empty4` - --> $DIR/empty-struct-unit-expr.rs:16:14 + --> $DIR/empty-struct-unit-expr.rs:17:14 | -LL | Empty4 +LL | Empty4, | ------ enum variant `E::Empty4` defined here ... LL | let e4 = E::Empty4(); @@ -33,7 +33,7 @@ LL + let e4 = E::Empty4; | error[E0618]: expected function, found struct `XEmpty2` - --> $DIR/empty-struct-unit-expr.rs:18:15 + --> $DIR/empty-struct-unit-expr.rs:19:15 | LL | let xe2 = XEmpty2(); | ^^^^^^^-- @@ -47,7 +47,7 @@ LL + let xe2 = XEmpty2; | error[E0618]: expected function, found enum variant `XE::XEmpty4` - --> $DIR/empty-struct-unit-expr.rs:19:15 + --> $DIR/empty-struct-unit-expr.rs:20:15 | LL | let xe4 = XE::XEmpty4(); | ^^^^^^^^^^^-- diff --git a/tests/ui/entry-point/imported_main_conflict_lib.rs b/tests/ui/entry-point/imported_main_conflict_lib.rs new file mode 100644 index 000000000000..b50e37951ede --- /dev/null +++ b/tests/ui/entry-point/imported_main_conflict_lib.rs @@ -0,0 +1,10 @@ +// Tests that ambiguously glob importing main doesn't fail to compile in non-executable crates +// Regression test for #149412 +//@ check-pass +#![crate_type = "lib"] + +mod m1 { pub(crate) fn main() {} } +mod m2 { pub(crate) fn main() {} } + +use m1::*; +use m2::*; diff --git a/tests/ui/enum-discriminant/discriminant_value.rs b/tests/ui/enum-discriminant/discriminant_value.rs index 0d6b9166c26a..dc3d9cb83cca 100644 --- a/tests/ui/enum-discriminant/discriminant_value.rs +++ b/tests/ui/enum-discriminant/discriminant_value.rs @@ -1,6 +1,5 @@ //@ run-pass -#![allow(stable_features)] -#![feature(core, core_intrinsics)] +#![feature(core_intrinsics)] extern crate core; use core::intrinsics::discriminant_value; diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index e3e1755e14dd..9b97ad4aeac7 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -16,7 +16,7 @@ error: layout_of(UnsignedAroundZero) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -52,7 +52,7 @@ error: layout_of(UnsignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -73,7 +73,7 @@ error: layout_of(UnsignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -94,7 +94,7 @@ error: layout_of(UnsignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -134,7 +134,7 @@ error: layout_of(SignedAroundZero) = Layout { offsets: [ Size(0 bytes), ], - memory_index: [ + in_memory_order: [ 0, ], }, @@ -170,7 +170,7 @@ error: layout_of(SignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -191,7 +191,7 @@ error: layout_of(SignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, @@ -212,7 +212,7 @@ error: layout_of(SignedAroundZero) = Layout { }, fields: Arbitrary { offsets: [], - memory_index: [], + in_memory_order: [], }, largest_niche: None, uninhabited: false, diff --git a/tests/ui/enum/assoc-fn-call-on-variant.rs b/tests/ui/enum/assoc-fn-call-on-variant.rs index 0886e7dcd8d8..c85d00eb0de8 100644 --- a/tests/ui/enum/assoc-fn-call-on-variant.rs +++ b/tests/ui/enum/assoc-fn-call-on-variant.rs @@ -12,5 +12,6 @@ impl E { } fn main() { - E::A::f(); //~ ERROR failed to resolve: `A` is a variant, not a module + E::A::f(); //~ ERROR cannot find module `A` in `E` + //~^ NOTE: `A` is a variant, not a module } diff --git a/tests/ui/enum/assoc-fn-call-on-variant.stderr b/tests/ui/enum/assoc-fn-call-on-variant.stderr index ee75870ad394..ab7049e22f4b 100644 --- a/tests/ui/enum/assoc-fn-call-on-variant.stderr +++ b/tests/ui/enum/assoc-fn-call-on-variant.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: `A` is a variant, not a module +error[E0433]: cannot find module `A` in `E` --> $DIR/assoc-fn-call-on-variant.rs:15:8 | LL | E::A::f(); diff --git a/tests/ui/enum/enum-discriminant-missing-variant.rs b/tests/ui/enum/enum-discriminant-missing-variant.rs new file mode 100644 index 000000000000..1bdbfb1fbcd4 --- /dev/null +++ b/tests/ui/enum/enum-discriminant-missing-variant.rs @@ -0,0 +1,6 @@ +//! regression test for issue +pub enum SomeEnum { + B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found +} + +fn main() {} diff --git a/tests/ui/enum/enum-discriminant-missing-variant.stderr b/tests/ui/enum/enum-discriminant-missing-variant.stderr new file mode 100644 index 000000000000..ef98a93e86f6 --- /dev/null +++ b/tests/ui/enum/enum-discriminant-missing-variant.stderr @@ -0,0 +1,17 @@ +error[E0599]: no variant or associated item named `A` found for enum `SomeEnum` in the current scope + --> $DIR/enum-discriminant-missing-variant.rs:3:19 + | +LL | pub enum SomeEnum { + | ----------------- variant or associated item `A` not found for this enum +LL | B = SomeEnum::A, + | ^ variant or associated item not found in `SomeEnum` + | +help: there is a variant with a similar name + | +LL - B = SomeEnum::A, +LL + B = SomeEnum::B, + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/enum/enum-nonexisting-field.rs b/tests/ui/enum/enum-nonexisting-field.rs new file mode 100644 index 000000000000..837430340f33 --- /dev/null +++ b/tests/ui/enum/enum-nonexisting-field.rs @@ -0,0 +1,10 @@ +//! regression test for + +enum Homura { + Akemi { madoka: () } +} + +fn main() { + let homura = Homura::Akemi { kaname: () }; + //~^ ERROR variant `Homura::Akemi` has no field named `kaname` +} diff --git a/tests/ui/enum/enum-nonexisting-field.stderr b/tests/ui/enum/enum-nonexisting-field.stderr new file mode 100644 index 000000000000..22bfa08dadb3 --- /dev/null +++ b/tests/ui/enum/enum-nonexisting-field.stderr @@ -0,0 +1,11 @@ +error[E0559]: variant `Homura::Akemi` has no field named `kaname` + --> $DIR/enum-nonexisting-field.rs:8:34 + | +LL | let homura = Homura::Akemi { kaname: () }; + | ^^^^^^ `Homura::Akemi` does not have this field + | + = note: available fields are: `madoka` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0559`. diff --git a/tests/ui/enum/enum-variant-no-field.rs b/tests/ui/enum/enum-variant-no-field.rs new file mode 100644 index 000000000000..a69766b7c48d --- /dev/null +++ b/tests/ui/enum/enum-variant-no-field.rs @@ -0,0 +1,9 @@ +//! regression test for https://github.com/rust-lang/rust/issues/23253 +enum Foo { + Bar, +} + +fn main() { + Foo::Bar.a; + //~^ ERROR no field `a` on type `Foo` +} diff --git a/tests/ui/enum/enum-variant-no-field.stderr b/tests/ui/enum/enum-variant-no-field.stderr new file mode 100644 index 000000000000..4d02bf876189 --- /dev/null +++ b/tests/ui/enum/enum-variant-no-field.stderr @@ -0,0 +1,9 @@ +error[E0609]: no field `a` on type `Foo` + --> $DIR/enum-variant-no-field.rs:7:14 + | +LL | Foo::Bar.a; + | ^ unknown field + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0609`. diff --git a/tests/ui/enum/enum-with-uninhabited-variant.rs b/tests/ui/enum/enum-with-uninhabited-variant.rs new file mode 100644 index 000000000000..8dfa492e6ea5 --- /dev/null +++ b/tests/ui/enum/enum-with-uninhabited-variant.rs @@ -0,0 +1,14 @@ +//! regression test for issue https://github.com/rust-lang/rust/issues/50442 +//@ run-pass +#![allow(dead_code)] +enum Void {} + +enum Foo { + A(i32), + B(Void), + C(i32), +} + +fn main() { + let _foo = Foo::A(0); +} diff --git a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr index ac8e1c5fa858..4ac5dfb8d228 100644 --- a/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr +++ b/tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr @@ -12,16 +12,6 @@ LL | | drop((x.0, x.1, x.2)); | | --- use occurs due to use in closure LL | | }); | |_________- value moved here, in previous iteration of loop - | -help: consider moving the expression out of the loop so it is only moved once - | -LL ~ let mut value = std::thread::spawn(use || { -LL + -LL + drop((x.0, x.1, x.2)); -LL + }); -LL ~ for _ in 0..10 { -LL ~ let handler = value; - | error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0010-teach.rs b/tests/ui/error-codes/E0010-teach.rs deleted file mode 100644 index 0eef24783873..000000000000 --- a/tests/ui/error-codes/E0010-teach.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ compile-flags: -Z teach - -#![allow(warnings)] - -const CON: Vec = vec![1, 2, 3]; //~ ERROR E0010 -//~| ERROR cannot call non-const method -fn main() {} diff --git a/tests/ui/error-codes/E0010-teach.stderr b/tests/ui/error-codes/E0010-teach.stderr deleted file mode 100644 index 82bbe01aef79..000000000000 --- a/tests/ui/error-codes/E0010-teach.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0010]: allocations are not allowed in constants - --> $DIR/E0010-teach.rs:5:23 - | -LL | const CON: Vec = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ allocation not allowed in constants - | - = note: The runtime heap is not yet available at compile-time, so no runtime heap allocations can be created. - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0015]: cannot call non-const method `slice::::into_vec::` in constants - --> $DIR/E0010-teach.rs:5:23 - | -LL | const CON: Vec = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0010, E0015. -For more information about an error, try `rustc --explain E0010`. diff --git a/tests/ui/error-codes/E0010.rs b/tests/ui/error-codes/E0010.rs deleted file mode 100644 index edb96714dd32..000000000000 --- a/tests/ui/error-codes/E0010.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![allow(warnings)] - -const CON: Vec = vec![1, 2, 3]; //~ ERROR E0010 -//~| ERROR cannot call non-const method -fn main() {} diff --git a/tests/ui/error-codes/E0010.stderr b/tests/ui/error-codes/E0010.stderr deleted file mode 100644 index 87b722b5f656..000000000000 --- a/tests/ui/error-codes/E0010.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0010]: allocations are not allowed in constants - --> $DIR/E0010.rs:3:23 - | -LL | const CON: Vec = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ allocation not allowed in constants - | - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0015]: cannot call non-const method `slice::::into_vec::` in constants - --> $DIR/E0010.rs:3:23 - | -LL | const CON: Vec = vec![1, 2, 3]; - | ^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0010, E0015. -For more information about an error, try `rustc --explain E0010`. diff --git a/tests/ui/error-codes/E0017.stderr b/tests/ui/error-codes/E0017.stderr index fcc57b9e5c3c..70186165d862 100644 --- a/tests/ui/error-codes/E0017.stderr +++ b/tests/ui/error-codes/E0017.stderr @@ -19,9 +19,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | const CR: &'static mut i32 = &mut C; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0017.rs:11:39 @@ -52,9 +52,9 @@ error[E0764]: mutable borrows of temporaries that have their lifetime extended u LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ this mutable borrow refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 3 previous errors; 2 warnings emitted diff --git a/tests/ui/error-codes/E0030-teach.stderr b/tests/ui/error-codes/E0030-teach.stderr index 50c7d1eee1f4..81c9236b0037 100644 --- a/tests/ui/error-codes/E0030-teach.stderr +++ b/tests/ui/error-codes/E0030-teach.stderr @@ -4,7 +4,7 @@ error[E0030]: lower bound for range pattern must be less than or equal to upper LL | 1000 ..= 5 => {} | ^^^^^^^^^^ lower bound larger than upper bound | - = note: When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range. + = note: when matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0059.stderr b/tests/ui/error-codes/E0059.stderr index d26fadcdbfa7..43191db8be10 100644 --- a/tests/ui/error-codes/E0059.stderr +++ b/tests/ui/error-codes/E0059.stderr @@ -2,7 +2,7 @@ error[E0059]: type parameter to bare `Fn` trait must be a tuple --> $DIR/E0059.rs:3:11 | LL | fn foo>(f: F) -> F::Output { f(3) } - | ^^^^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` | note: required by a bound in `Fn` --> $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -11,7 +11,7 @@ error[E0277]: `i32` is not a tuple --> $DIR/E0059.rs:3:41 | LL | fn foo>(f: F) -> F::Output { f(3) } - | ^^^^ the trait `Tuple` is not implemented for `i32` + | ^^^^ the nightly-only, unstable trait `std::marker::Tuple` is not implemented for `i32` error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit --> $DIR/E0059.rs:3:41 diff --git a/tests/ui/error-codes/E0116.stderr b/tests/ui/error-codes/E0116.stderr index 1ea5a57f46db..20e3b196226a 100644 --- a/tests/ui/error-codes/E0116.stderr +++ b/tests/ui/error-codes/E0116.stderr @@ -4,7 +4,8 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher LL | impl Vec {} | ^^^^^^^^^^^^ impl for type defined outside of crate | - = note: define and implement a trait or new type instead + = help: consider defining a trait and implementing it for the type or using a newtype wrapper like `struct MyType(ExternalType);` and implement it + = note: for more details about the orphan rules, see error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0152-duplicate-lang-items.rs b/tests/ui/error-codes/E0152-duplicate-lang-items.rs index f707b72f9b2b..4b243205dc48 100644 --- a/tests/ui/error-codes/E0152-duplicate-lang-items.rs +++ b/tests/ui/error-codes/E0152-duplicate-lang-items.rs @@ -3,7 +3,7 @@ //! //! Issue: -//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta" //@ dont-require-annotations: NOTE #![feature(lang_items)] diff --git a/tests/ui/error-codes/E0152-duplicate-lang-items.stderr b/tests/ui/error-codes/E0152-duplicate-lang-items.stderr index 2fe0d18fc2f4..55d5206b42ce 100644 --- a/tests/ui/error-codes/E0152-duplicate-lang-items.stderr +++ b/tests/ui/error-codes/E0152-duplicate-lang-items.stderr @@ -9,7 +9,7 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `E0152_duplicate_lang_items` depends on) - = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta = note: second definition in the local crate (`E0152_duplicate_lang_items`) error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0152.rs b/tests/ui/error-codes/E0152.rs index 565e92baf02e..53c7c027eff3 100644 --- a/tests/ui/error-codes/E0152.rs +++ b/tests/ui/error-codes/E0152.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" +//@ normalize-stderr: "loaded from .*liballoc-.*.rmeta" -> "loaded from SYSROOT/liballoc-*.rmeta" #![feature(lang_items)] #[lang = "owned_box"] diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr index dbea7e6d27fb..73df5803e839 100644 --- a/tests/ui/error-codes/E0152.stderr +++ b/tests/ui/error-codes/E0152.stderr @@ -5,7 +5,7 @@ LL | struct Foo(T); | ^^^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `alloc` (which `std` depends on) - = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib + = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rmeta = note: second definition in the local crate (`E0152`) error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0184.rs b/tests/ui/error-codes/E0184.rs index 0c448e4ad8bc..64cc1f0d1538 100644 --- a/tests/ui/error-codes/E0184.rs +++ b/tests/ui/error-codes/E0184.rs @@ -1,5 +1,5 @@ -#[derive(Copy)] //~ ERROR E0184 -struct Foo; +#[derive(Copy)] +struct Foo; //~ ERROR E0184 impl Drop for Foo { fn drop(&mut self) { diff --git a/tests/ui/error-codes/E0184.stderr b/tests/ui/error-codes/E0184.stderr index 1a7df9ac095a..13294959bc3c 100644 --- a/tests/ui/error-codes/E0184.stderr +++ b/tests/ui/error-codes/E0184.stderr @@ -1,8 +1,16 @@ error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor - --> $DIR/E0184.rs:1:10 + --> $DIR/E0184.rs:2:8 | LL | #[derive(Copy)] - | ^^^^ `Copy` not allowed on types with destructors + | ---- in this derive macro expansion +LL | struct Foo; + | ^^^ `Copy` not allowed on types with destructors + | +note: destructor declared here + --> $DIR/E0184.rs:5:5 + | +LL | fn drop(&mut self) { + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0191.stderr b/tests/ui/error-codes/E0191.stderr index 63974fd6cbbb..6fbb20839777 100644 --- a/tests/ui/error-codes/E0191.stderr +++ b/tests/ui/error-codes/E0191.stderr @@ -5,7 +5,7 @@ LL | type Bar; | -------- `Bar` defined here ... LL | type Foo = dyn Trait; - | ^^^^^ help: specify the associated type: `Trait` + | ^^^^^ help: specify the associated type: `Trait` error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0220.stderr b/tests/ui/error-codes/E0220.stderr index 0e0b5c7084cc..48197c9a8ccf 100644 --- a/tests/ui/error-codes/E0220.stderr +++ b/tests/ui/error-codes/E0220.stderr @@ -11,7 +11,7 @@ LL | type Bar; | -------- `Bar` defined here ... LL | type Foo = dyn Trait; - | ^^^^^^^^^^^^ help: specify the associated type: `Trait` + | ^^^^^^^^^^^^ help: specify the associated type: `Trait` error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0264.rs b/tests/ui/error-codes/E0264.rs index 6adaf01fb524..855644796ed4 100644 --- a/tests/ui/error-codes/E0264.rs +++ b/tests/ui/error-codes/E0264.rs @@ -1,8 +1,8 @@ #![feature(lang_items)] extern "C" { - #[lang = "cake"] - fn cake(); //~ ERROR E0264 + #[lang = "copy"] + fn copy(); //~ ERROR E0264 } fn main() {} diff --git a/tests/ui/error-codes/E0264.stderr b/tests/ui/error-codes/E0264.stderr index 3503fb229e4f..6442f42e689d 100644 --- a/tests/ui/error-codes/E0264.stderr +++ b/tests/ui/error-codes/E0264.stderr @@ -1,7 +1,7 @@ -error[E0264]: unknown external lang item: `cake` +error[E0264]: unknown external lang item: `copy` --> $DIR/E0264.rs:5:5 | -LL | fn cake(); +LL | fn copy(); | ^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0277-4.rs b/tests/ui/error-codes/E0277-4.rs new file mode 100644 index 000000000000..ead57f00dde5 --- /dev/null +++ b/tests/ui/error-codes/E0277-4.rs @@ -0,0 +1,50 @@ +use std::fmt::Display; + +trait ImplicitTrait { + fn foo(&self); +} + +trait ExplicitTrait { + fn foo(&self); +} + +trait DisplayTrait { + fn foo(&self); +} + +trait UnimplementedTrait { + fn foo(&self); +} + +// Implicitly requires `T: Sized`. +impl ImplicitTrait for T { + fn foo(&self) {} +} + +// Explicitly requires `T: Sized`. +impl ExplicitTrait for T { + fn foo(&self) {} +} + +// Requires `T: Display`. +impl DisplayTrait for T { + fn foo(&self) {} +} + +fn main() { + // `[u8]` does not implement `Sized`. + let x: &[u8] = &[]; + ImplicitTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: ImplicitTrait` is not satisfied [E0277] + ExplicitTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: ExplicitTrait` is not satisfied [E0277] + + // `UnimplementedTrait` has no implementations. + UnimplementedTrait::foo(x); + //~^ ERROR: the trait bound `[u8]: UnimplementedTrait` is not satisfied [E0277] + + // `[u8; 0]` implements `Sized` but not `Display`. + let x: &[u8; 0] = &[]; + DisplayTrait::foo(x); + //~^ ERROR: the trait bound `[u8; 0]: DisplayTrait` is not satisfied [E0277] +} diff --git a/tests/ui/error-codes/E0277-4.stderr b/tests/ui/error-codes/E0277-4.stderr new file mode 100644 index 000000000000..f38b8146a63d --- /dev/null +++ b/tests/ui/error-codes/E0277-4.stderr @@ -0,0 +1,77 @@ +error[E0277]: the trait bound `[u8]: ImplicitTrait` is not satisfied + --> $DIR/E0277-4.rs:37:24 + | +LL | ImplicitTrait::foo(x); + | ------------------ ^ the trait `Sized` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +note: required for `[u8]` to implement `ImplicitTrait` + --> $DIR/E0277-4.rs:20:9 + | +LL | impl ImplicitTrait for T { + | - ^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound implicitly introduced here +help: consider borrowing here + | +LL | ImplicitTrait::foo(&x); + | + +LL | ImplicitTrait::foo(&mut x); + | ++++ + +error[E0277]: the trait bound `[u8]: ExplicitTrait` is not satisfied + --> $DIR/E0277-4.rs:39:24 + | +LL | ExplicitTrait::foo(x); + | ------------------ ^ the trait `Sized` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +note: required for `[u8]` to implement `ExplicitTrait` + --> $DIR/E0277-4.rs:25:16 + | +LL | impl ExplicitTrait for T { + | ----- ^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +help: consider borrowing here + | +LL | ExplicitTrait::foo(&x); + | + +LL | ExplicitTrait::foo(&mut x); + | ++++ + +error[E0277]: the trait bound `[u8]: UnimplementedTrait` is not satisfied + --> $DIR/E0277-4.rs:43:29 + | +LL | UnimplementedTrait::foo(x); + | ----------------------- ^ the trait `UnimplementedTrait` is not implemented for `[u8]` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/E0277-4.rs:15:1 + | +LL | trait UnimplementedTrait { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `[u8; 0]: DisplayTrait` is not satisfied + --> $DIR/E0277-4.rs:48:23 + | +LL | DisplayTrait::foo(x); + | ----------------- ^ the trait `std::fmt::Display` is not implemented for `[u8; 0]` + | | + | required by a bound introduced by this call + | +note: required for `[u8; 0]` to implement `DisplayTrait` + --> $DIR/E0277-4.rs:30:18 + | +LL | impl DisplayTrait for T { + | ------- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/error-codes/E0393.stderr b/tests/ui/error-codes/E0393.stderr index 4847aa2508da..a6991aa355fa 100644 --- a/tests/ui/error-codes/E0393.stderr +++ b/tests/ui/error-codes/E0393.stderr @@ -7,11 +7,11 @@ LL | LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {} | ^ | - = note: because the parameter default references `Self`, the parameter must be specified on the object type -help: set the type parameter to the desired type + = note: because the parameter default references `Self`, the parameter must be specified on the trait object type +help: explicitly specify the type parameter | -LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {} - | +++ +LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {} + | +++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0433.stderr b/tests/ui/error-codes/E0433.stderr index 1ac8c3ebc4d4..e1e09045e0dc 100644 --- a/tests/ui/error-codes/E0433.stderr +++ b/tests/ui/error-codes/E0433.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of undeclared type `NonExistingMap` +error[E0433]: cannot find type `NonExistingMap` in this scope --> $DIR/E0433.rs:2:15 | LL | let map = NonExistingMap::new(); diff --git a/tests/ui/error-codes/E0458.stderr b/tests/ui/error-codes/E0458.stderr index 524765ea12a1..e56c9473d287 100644 --- a/tests/ui/error-codes/E0458.stderr +++ b/tests/ui/error-codes/E0458.stderr @@ -7,21 +7,6 @@ LL | #[link(kind = "wonderful_unicorn")] extern "C" {} | valid arguments are "static", "dylib", "framework", "raw-dylib" or "link-arg" | = note: for more information, visit -help: try changing it to one of the following valid forms of the attribute - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...")] extern "C" {} - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] extern "C" {} - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...", kind = "dylib|static|...")] extern "C" {} - | -LL - #[link(kind = "wonderful_unicorn")] extern "C" {} -LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] extern "C" {} - | - = and 1 other candidate error[E0459]: `#[link]` attribute requires a `name = "string"` argument --> $DIR/E0458.rs:1:1 diff --git a/tests/ui/error-codes/E0492.stderr b/tests/ui/error-codes/E0492.stderr index 43a3a872e4e7..a5057e8baedb 100644 --- a/tests/ui/error-codes/E0492.stderr +++ b/tests/ui/error-codes/E0492.stderr @@ -4,9 +4,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | const B: &'static AtomicUsize = &A; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error[E0492]: interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed --> $DIR/E0492.rs:5:34 @@ -14,9 +14,9 @@ error[E0492]: interior mutable shared borrows of temporaries that have their lif LL | static C: &'static AtomicUsize = &A; | ^^ this borrow of an interior mutable value refers to such a temporary | - = note: Temporaries in constants and statics can have their lifetime extended until the end of the program - = note: To avoid accidentally creating global mutable state, such temporaries must be immutable - = help: If you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` + = note: temporaries in constants and statics can have their lifetime extended until the end of the program + = note: to avoid accidentally creating global mutable state, such temporaries must be immutable + = help: if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut` error: aborting due to 2 previous errors diff --git a/tests/ui/error-codes/E0565-1.stderr b/tests/ui/error-codes/E0565-1.stderr index 52daf2a62fcd..d1aff042e8fb 100644 --- a/tests/ui/error-codes/E0565-1.stderr +++ b/tests/ui/error-codes/E0565-1.stderr @@ -5,22 +5,6 @@ LL | #[deprecated("since")] | ^^^^^^^^^^^^^-------^^ | | | didn't expect a literal here - | -help: try changing it to one of the following valid forms of the attribute - | -LL - #[deprecated("since")] -LL + #[deprecated = "reason"] - | -LL - #[deprecated("since")] -LL + #[deprecated(note = "reason")] - | -LL - #[deprecated("since")] -LL + #[deprecated(since = "version")] - | -LL - #[deprecated("since")] -LL + #[deprecated(since = "version", note = "reason")] - | - = and 1 other candidate error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0657.stderr b/tests/ui/error-codes/E0657.stderr index c9dfc9eb9069..1d69af5d9654 100644 --- a/tests/ui/error-codes/E0657.stderr +++ b/tests/ui/error-codes/E0657.stderr @@ -1,8 +1,8 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/E0657.rs:10:35 + --> $DIR/E0657.rs:10:27 | LL | -> Box Id>> - | ^^ + | ^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/E0657.rs:10:20 @@ -11,10 +11,10 @@ LL | -> Box Id>> | ^^ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from `dyn` type - --> $DIR/E0657.rs:19:39 + --> $DIR/E0657.rs:19:31 | LL | -> Box Id>> - | ^^ + | ^^^^^^^^--^ `impl Trait` implicitly captures all lifetimes in scope | note: lifetime declared here --> $DIR/E0657.rs:19:24 diff --git a/tests/ui/error-codes/E0778.rs b/tests/ui/error-codes/E0778.rs deleted file mode 100644 index 74653886d415..000000000000 --- a/tests/ui/error-codes/E0778.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[instruction_set()] //~ ERROR -fn no_isa_defined() {} - -fn main() {} diff --git a/tests/ui/error-codes/E0778.stderr b/tests/ui/error-codes/E0778.stderr deleted file mode 100644 index 7eb24c493bf5..000000000000 --- a/tests/ui/error-codes/E0778.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0778]: `#[instruction_set]` requires an argument - --> $DIR/E0778.rs:1:1 - | -LL | #[instruction_set()] - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0778`. diff --git a/tests/ui/error-codes/E0779.rs b/tests/ui/error-codes/E0779.rs deleted file mode 100644 index c32dae12c9cb..000000000000 --- a/tests/ui/error-codes/E0779.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[instruction_set(arm::magic)] //~ ERROR -fn main() {} diff --git a/tests/ui/error-codes/E0779.stderr b/tests/ui/error-codes/E0779.stderr deleted file mode 100644 index a01aa98b914c..000000000000 --- a/tests/ui/error-codes/E0779.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0779]: invalid instruction set specified - --> $DIR/E0779.rs:1:1 - | -LL | #[instruction_set(arm::magic)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0779`. diff --git a/tests/ui/error-codes/E0806.rs b/tests/ui/error-codes/E0806.rs new file mode 100644 index 000000000000..ab6a31673cc0 --- /dev/null +++ b/tests/ui/error-codes/E0806.rs @@ -0,0 +1,12 @@ +#![feature(extern_item_impls)] + +#[eii(foo)] +fn x(); + +#[foo] +fn y(a: u64) -> u64 { + //~^ ERROR E0806 + a +} + +fn main() {} diff --git a/tests/ui/error-codes/E0806.stderr b/tests/ui/error-codes/E0806.stderr new file mode 100644 index 000000000000..ab6ba45185df --- /dev/null +++ b/tests/ui/error-codes/E0806.stderr @@ -0,0 +1,14 @@ +error[E0806]: `y` has 1 parameter but #[foo] requires it to have 0 + --> $DIR/E0806.rs:7:9 + | +LL | fn x(); + | ------- requires 0 parameters +LL | +LL | #[foo] + | ------ required because of this attribute +LL | fn y(a: u64) -> u64 { + | ^^^ expected 0 parameters, found 1 + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0806`. diff --git a/tests/ui/error-emitter/multiline-removal-suggestion.svg b/tests/ui/error-emitter/multiline-removal-suggestion.svg index 1e8621388510..39631e0e306d 100644 --- a/tests/ui/error-emitter/multiline-removal-suggestion.svg +++ b/tests/ui/error-emitter/multiline-removal-suggestion.svg @@ -1,4 +1,4 @@ - + where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable fn foo(&self) where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable } impl A for T where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { type B = () where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable fn foo(&self) where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable {} } @@ -100,12 +100,12 @@ struct C where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { _t: PhantomData, } @@ -114,12 +114,12 @@ union D where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { _t: PhantomData, @@ -129,12 +129,12 @@ enum E where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { E(PhantomData), } @@ -142,21 +142,21 @@ where impl C where #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] T: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] T: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable { fn new() where #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable - #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable - #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable + #[cfg(true)] U: TraitAll, //~ ERROR attributes in `where` clause are unstable + #[cfg(false)] U: TraitAny, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable - #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(true, cfg(true))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable + #[cfg_attr(false, cfg(false))] U: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable {} } diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index 0b0dd80f0115..1560f2b5f4a7 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs @@ -1,4 +1,3 @@ -//~ NOTE: not an `extern crate` item // This is testing whether various builtin attributes signals an // error or warning when put in "weird" places. // @@ -29,7 +28,7 @@ //~| WARN cannot be used on crates //~| WARN previously accepted #![no_link] -//~^ ERROR: attribute should be applied to an `extern crate` item +//~^ ERROR: `#[no_link]` attribute cannot be used on crates #![export_name = "2200"] //~^ ERROR: attribute cannot be used on //~| NOTE takes precedence @@ -60,29 +59,40 @@ mod inline { } #[no_link] -//~^ ERROR attribute should be applied to an `extern crate` item +//~^ ERROR `#[no_link]` attribute cannot be used on modules mod no_link { - //~^ NOTE not an `extern crate` item - mod inner { #![no_link] } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on modules - #[no_link] fn f() { } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + #[no_link] fn f() { + //~^ ERROR `#[no_link]` attribute cannot be used on functions + match () { + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on match arms [unused_attributes] + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + _ => () + } + } - #[no_link] struct S; - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + #[no_link] + //~^ ERROR `#[no_link]` attribute cannot be used on structs + struct S { + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on struct fields [unused_attributes] + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + field: () + } #[no_link]type T = S; - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on type aliases #[no_link] impl S { } - //~^ ERROR attribute should be applied to an `extern crate` item - //~| NOTE not an `extern crate` item + //~^ ERROR `#[no_link]` attribute cannot be used on inherent impl blocks + + #[no_link] + //~^ WARN `#[no_link]` attribute cannot be used on macro defs + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + macro_rules! m{() => {}} } #[export_name = "2200"] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 013e52923811..662776e58026 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -1,5 +1,5 @@ error[E0658]: use of an internal attribute - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1 | LL | #![rustc_main] | ^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | #![rustc_main] = note: the `#[rustc_main]` attribute is used internally to specify test entry point function error: `#[macro_export]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:10:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:9:1 | LL | #![macro_export] | ^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | #![macro_export] = help: `#[macro_export]` can only be applied to macro defs error: `#[rustc_main]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:11:1 | LL | #![rustc_main] | ^^^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | #![rustc_main] = help: `#[rustc_main]` can only be applied to functions error: `#[path]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:20:1 | LL | #![path = "3800"] | ^^^^^^^^^^^^^^^^^ @@ -33,15 +33,23 @@ LL | #![path = "3800"] = help: `#[path]` can only be applied to modules error: `#[automatically_derived]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:23:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:22:1 | LL | #![automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[automatically_derived]` can only be applied to trait impl blocks +error: `#[no_link]` attribute cannot be used on crates + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:30:1 + | +LL | #![no_link] + | ^^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + error: `#[export_name]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:33:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1 | LL | #![export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +57,7 @@ LL | #![export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[inline]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:35:1 | LL | #![inline] | ^^^^^^^^^^ @@ -57,7 +65,7 @@ LL | #![inline] = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:38:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:37:1 | LL | #[inline] | ^^^^^^^^^ @@ -65,7 +73,7 @@ LL | #[inline] = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:43:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:42:17 | LL | mod inner { #![inline] } | ^^^^^^^^^^ @@ -73,7 +81,7 @@ LL | mod inner { #![inline] } = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:52:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:51:5 | LL | #[inline] struct S; | ^^^^^^^^^ @@ -81,7 +89,7 @@ LL | #[inline] struct S; = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:55:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:54:5 | LL | #[inline] type T = S; | ^^^^^^^^^ @@ -89,15 +97,63 @@ LL | #[inline] type T = S; = help: `#[inline]` can only be applied to functions error: `#[inline]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:58:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:57:5 | LL | #[inline] impl S { } | ^^^^^^^^^ | = help: `#[inline]` can only be applied to functions +error: `#[no_link]` attribute cannot be used on modules + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:61:1 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on modules + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:64:17 + | +LL | mod inner { #![no_link] } + | ^^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on functions + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:5 + | +LL | #[no_link] fn f() { + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on structs + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:77:5 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on type aliases + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:86:5 + | +LL | #[no_link]type T = S; + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + +error: `#[no_link]` attribute cannot be used on inherent impl blocks + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:89:5 + | +LL | #[no_link] impl S { } + | ^^^^^^^^^^ + | + = help: `#[no_link]` can only be applied to extern crates + error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:1 | LL | #[export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -105,7 +161,7 @@ LL | #[export_name = "2200"] = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:101:17 | LL | mod inner { #![export_name="2200"] } | ^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +169,7 @@ LL | mod inner { #![export_name="2200"] } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on structs - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:5 | LL | #[export_name = "2200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -121,7 +177,7 @@ LL | #[export_name = "2200"] struct S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:99:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:5 | LL | #[export_name = "2200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,7 +185,7 @@ LL | #[export_name = "2200"] type T = S; = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:102:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:112:5 | LL | #[export_name = "2200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,29 +193,15 @@ LL | #[export_name = "2200"] impl S { } = help: `#[export_name]` can be applied to functions and statics error: `#[export_name]` attribute cannot be used on required trait methods - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:9 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:116:9 | LL | #[export_name = "2200"] fn foo(); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[export_name]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:62:1 - | -LL | #[no_link] - | ^^^^^^^^^^ -LL | -LL | / mod no_link { -LL | | -LL | | -LL | | mod inner { #![no_link] } -... | -LL | | } - | |_- not an `extern crate` item - error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:8 | LL | #[repr(C)] | ^ @@ -172,7 +214,7 @@ LL | | } | |_- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:8 | LL | #[repr(Rust)] | ^^^^ @@ -184,20 +226,14 @@ LL | | mod inner { #![repr(Rust)] } LL | | } | |_- not a struct, enum, or union -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:31:1 - | -LL | #![no_link] - | ^^^^^^^^^^^ not an `extern crate` item - warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:24:1 | LL | #![no_mangle] | ^^^^^^^^^^^^^ `#[no_mangle]` is ignored | note: `#[export_name]` takes precedence - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:33:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:32:1 | LL | #![export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -208,7 +244,7 @@ LL - #![no_mangle] | error: `repr` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![repr()] | ^^^^^^^^^^ @@ -222,86 +258,56 @@ LL - #![repr()] LL + #[repr()] | -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:17 - | -LL | mod inner { #![no_link] } - | ------------^^^^^^^^^^^-- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:71:5 - | -LL | #[no_link] fn f() { } - | ^^^^^^^^^^ ---------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:75:5 - | -LL | #[no_link] struct S; - | ^^^^^^^^^^ --------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:79:5 - | -LL | #[no_link]type T = S; - | ^^^^^^^^^^----------- not an `extern crate` item - -error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:5 - | -LL | #[no_link] impl S { } - | ^^^^^^^^^^ ---------- not an `extern crate` item - error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:117:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:25 | LL | mod inner { #![repr(C)] } | --------------------^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:121:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:12 | LL | #[repr(C)] fn f() { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12 | LL | #[repr(C)] type T = S; | ^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:131:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:12 | LL | #[repr(C)] impl S { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:25 | LL | mod inner { #![repr(Rust)] } | --------------------^^^^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:145:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:155:12 | LL | #[repr(Rust)] fn f() { } | ^^^^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:161:12 | LL | #[repr(Rust)] type T = S; | ^^^^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:155:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:165:12 | LL | #[repr(Rust)] impl S { } | ^^^^ ---------- not a struct, enum, or union error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ @@ -310,8 +316,35 @@ LL | #[inline = "2100"] fn f() { } = note: for more information, see issue #57571 = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default +warning: `#[no_link]` attribute cannot be used on match arms + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:13 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + +warning: `#[no_link]` attribute cannot be used on struct fields + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:9 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + +warning: `#[no_link]` attribute cannot be used on macro defs + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:92:5 + | +LL | #[no_link] + | ^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_link]` can only be applied to extern crates + warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![repr()] | ^^^^^^^^^^ help: remove this attribute @@ -319,7 +352,7 @@ LL | #![repr()] = note: using `repr` with an empty list has no effect warning: `#[no_mangle]` attribute cannot be used on crates - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:25:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:24:1 | LL | #![no_mangle] | ^^^^^^^^^^^^^ @@ -327,13 +360,13 @@ LL | #![no_mangle] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_mangle]` can be applied to functions and statics -error: aborting due to 37 previous errors; 3 warnings emitted +error: aborting due to 37 previous errors; 6 warnings emitted Some errors have detailed explanations: E0517, E0658. For more information about an error, try `rustc --explain E0517`. Future incompatibility report: Future breakage diagnostic: error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 4b5420a2ff8b..83debd17777a 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -467,26 +467,26 @@ mod no_implicit_prelude { #[reexport_test_harness_main = "2900"] //~^ WARN crate-level attribute should be -//~| HELP add a `!` mod reexport_test_harness_main { +//~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![reexport_test_harness_main="2900"] } - //~^ WARN crate-level attribute should be + //~^ WARN the `#![reexport_test_harness_main]` attribute can only be used at the crate root #[reexport_test_harness_main = "2900"] fn f() { } //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[reexport_test_harness_main = "2900"] struct S; //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[reexport_test_harness_main = "2900"] type T = S; //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[reexport_test_harness_main = "2900"] impl S { } //~^ WARN crate-level attribute should be - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } // Cannot feed "2700" to `#[macro_escape]` without signaling an error. @@ -525,25 +525,25 @@ mod macro_escape { #[no_std] //~^ WARN crate-level attribute should be an inner attribute mod no_std { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![no_std] } //~^ WARN the `#![no_std]` attribute can only be used at the crate root #[no_std] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[no_std] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[no_std] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[no_std] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } // At time of authorship, #[proc_macro_derive = "2500"] signals error @@ -680,6 +680,10 @@ mod link_section { //~| HELP remove the attribute trait Tr { #[link_section = "1800"] + //~^ WARN attribute cannot be used on + //~| WARN previously accepted + //~| HELP can be applied to + //~| HELP remove the attribute fn inside_tr_no_default(&self); #[link_section = "1800"] @@ -782,25 +786,25 @@ mod must_use { #[windows_subsystem = "windows"] //~^ WARN crate-level attribute should be an inner attribute mod windows_subsystem { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![windows_subsystem="windows"] } //~^ WARN the `#![windows_subsystem]` attribute can only be used at the crate root #[windows_subsystem = "windows"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[windows_subsystem = "windows"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[windows_subsystem = "windows"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[windows_subsystem = "windows"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } // BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES @@ -808,49 +812,49 @@ mod windows_subsystem { #[crate_name = "0900"] //~^ WARN crate-level attribute should be an inner attribute mod crate_name { -//~^ NOTE This attribute does not have an `!`, which means it is applied to this module +//~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![crate_name="0900"] } //~^ WARN the `#![crate_name]` attribute can only be used at the crate root #[crate_name = "0900"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[crate_name = "0900"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[crate_name = "0900"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[crate_name = "0900"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } #[crate_type = "0800"] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod crate_type { +//~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![crate_type="0800"] } -//~^ WARN crate-level attribute should be in the root module +//~^ WARN the `#![crate_type]` attribute can only be used at the crate root #[crate_type = "0800"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[crate_type = "0800"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[crate_type = "0800"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[crate_type = "0800"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } #[feature(x0600)] @@ -880,98 +884,98 @@ mod feature { #[no_main] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod no_main_1 { + //~^ NOTE: this attribute does not have an `!`, which means it is applied to this module mod inner { #![no_main] } -//~^ WARN crate-level attribute should be in the root module + //~^ WARN the `#![no_main]` attribute can only be used at the crate root #[no_main] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[no_main] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[no_main] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[no_main] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation } #[no_builtins] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod no_builtins { + //~^ NOTE: this attribute does not have an `!`, which means it is applied to this module mod inner { #![no_builtins] } - //~^ WARN crate-level attribute should be in the root module + //~^ WARN the `#![no_builtins]` attribute can only be used at the crate root #[no_builtins] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[no_builtins] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[no_builtins] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[no_builtins] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| HELP add a `!` + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation } #[recursion_limit="0200"] //~^ WARN crate-level attribute should be an inner attribute mod recursion_limit { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![recursion_limit="0200"] } //~^ WARN the `#![recursion_limit]` attribute can only be used at the crate root #[recursion_limit="0200"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[recursion_limit="0200"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[recursion_limit="0200"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[recursion_limit="0200"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } #[type_length_limit="0100"] //~^ WARN crate-level attribute should be an inner attribute mod type_length_limit { - //~^ NOTE This attribute does not have an `!`, which means it is applied to this module + //~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![type_length_limit="0100"] } //~^ WARN the `#![type_length_limit]` attribute can only be used at the crate root #[type_length_limit="0100"] fn f() { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this function + //~| NOTE this attribute does not have an `!`, which means it is applied to this function #[type_length_limit="0100"] struct S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this struct + //~| NOTE this attribute does not have an `!`, which means it is applied to this struct #[type_length_limit="0100"] type T = S; //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias + //~| NOTE this attribute does not have an `!`, which means it is applied to this type alias #[type_length_limit="0100"] impl S { } //~^ WARN crate-level attribute should be an inner attribute - //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block + //~| NOTE this attribute does not have an `!`, which means it is applied to this implementation block } fn main() {} diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 676372ad85e0..482980dde3bf 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -186,24 +186,8 @@ warning: unknown lint: `x5100` LL | #[deny(x5100)] impl S { } | ^^^^^ -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:1 - | -LL | #[reexport_test_harness_main = "2900"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 - | -LL | #![warn(unused_attributes, unknown_lints)] - | ^^^^^^^^^^^^^^^^^ -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:1 | LL | #[link(name = "x")] | ^^^^^^^^^^^^^^^^^^^ @@ -217,20 +201,14 @@ LL | | } | |_- not an `extern` block | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +note: the lint level is defined here + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:36:9 + | +LL | #![warn(unused_attributes, unknown_lints)] + | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:832:1 - | -LL | #[crate_type = "0800"] - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:856:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ @@ -240,28 +218,6 @@ help: add a `!` LL | #![feature(x0600)] | + -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:881:1 - | -LL | #[no_main] - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:905:1 - | -LL | #[no_builtins] - | ^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_builtins] - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI --> $DIR/issue-43106-gating-of-builtin-attrs.rs:71:1 | @@ -278,58 +234,8 @@ LL | #![feature(rust1)] | = note: `#[warn(stable_features)]` on by default -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:17 - | -LL | mod inner { #![reexport_test_harness_main="2900"] } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5 - | -LL | #[reexport_test_harness_main = "2900"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 - | -LL | #[reexport_test_harness_main = "2900"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 - | -LL | #[reexport_test_harness_main = "2900"] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 - | -LL | #[reexport_test_harness_main = "2900"] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![reexport_test_harness_main = "2900"] impl S { } - | + - warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:17 | LL | mod inner { #![link(name = "x")] } | ------------^^^^^^^^^^^^^^^^^^^^-- not an `extern` block @@ -337,7 +243,7 @@ LL | mod inner { #![link(name = "x")] } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5 | LL | #[link(name = "x")] fn f() { } | ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block @@ -345,7 +251,7 @@ LL | #[link(name = "x")] fn f() { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:722:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5 | LL | #[link(name = "x")] struct S; | ^^^^^^^^^^^^^^^^^^^ --------- not an `extern` block @@ -353,7 +259,7 @@ LL | #[link(name = "x")] struct S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:5 | LL | #[link(name = "x")] type T = S; | ^^^^^^^^^^^^^^^^^^^ ----------- not an `extern` block @@ -361,7 +267,7 @@ LL | #[link(name = "x")] type T = S; = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5 | LL | #[link(name = "x")] impl S { } | ^^^^^^^^^^^^^^^^^^^ ---------- not an `extern` block @@ -369,7 +275,7 @@ LL | #[link(name = "x")] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to an `extern` block with non-Rust ABI - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:741:5 | LL | #[link(name = "x")] extern "Rust" {} | ^^^^^^^^^^^^^^^^^^^ @@ -377,63 +283,13 @@ LL | #[link(name = "x")] extern "Rust" {} = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:836:17 - | -LL | mod inner { #![crate_type="0800"] } - | ^^^^^^^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:839:5 - | -LL | #[crate_type = "0800"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 - | -LL | #[crate_type = "0800"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 - | -LL | #[crate_type = "0800"] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5 - | -LL | #[crate_type = "0800"] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] impl S { } - | + - -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:864:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:863:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:867:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ @@ -444,7 +300,7 @@ LL | #![feature(x0600)] fn f() { } | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:867:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:871:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ @@ -455,7 +311,7 @@ LL | #![feature(x0600)] struct S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:871:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:875:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ @@ -466,7 +322,7 @@ LL | #![feature(x0600)] type T = S; | + warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:875:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:879:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ @@ -476,106 +332,6 @@ help: add a `!` LL | #![feature(x0600)] impl S { } | + -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:17 - | -LL | mod inner { #![no_main] } - | ^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:888:5 - | -LL | #[no_main] fn f() { } - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5 - | -LL | #[no_main] struct S; - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5 - | -LL | #[no_main] type T = S; - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5 - | -LL | #[no_main] impl S { } - | ^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_main] impl S { } - | + - -warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:17 - | -LL | mod inner { #![no_builtins] } - | ^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:912:5 - | -LL | #[no_builtins] fn f() { } - | ^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_builtins] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:916:5 - | -LL | #[no_builtins] struct S; - | ^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_builtins] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:5 - | -LL | #[no_builtins] type T = S; - | ^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_builtins] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:924:5 - | -LL | #[no_builtins] impl S { } - | ^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![no_builtins] impl S { } - | + - warning: `#[macro_use]` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs.rs:190:5 | @@ -954,6 +710,76 @@ LL | #[no_implicit_prelude] impl S { } = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[no_implicit_prelude]` can be applied to crates and modules +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:1 + | +LL | #[reexport_test_harness_main = "2900"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:470:1 + | +LL | / mod reexport_test_harness_main { +LL | | +LL | | mod inner { #![reexport_test_harness_main="2900"] } +... | +LL | | } + | |_^ + +warning: the `#![reexport_test_harness_main]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:17 + | +LL | mod inner { #![reexport_test_harness_main="2900"] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5 + | +LL | #[reexport_test_harness_main = "2900"] fn f() { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:44 + | +LL | #[reexport_test_harness_main = "2900"] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:5 + | +LL | #[reexport_test_harness_main = "2900"] struct S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:44 + | +LL | #[reexport_test_harness_main = "2900"] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:5 + | +LL | #[reexport_test_harness_main = "2900"] type T = S; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:483:44 + | +LL | #[reexport_test_harness_main = "2900"] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![reexport_test_harness_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:5 + | +LL | #[reexport_test_harness_main = "2900"] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:487:44 + | +LL | #[reexport_test_harness_main = "2900"] impl S { } + | ^^^^^^^^^^ + warning: `#[macro_escape]` attribute cannot be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:5 | @@ -996,7 +822,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module +note: this attribute does not have an `!`, which means it is applied to this module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:527:1 | LL | / mod no_std { @@ -1018,7 +844,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] fn f() { } | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function +note: this attribute does not have an `!`, which means it is applied to this function --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:15 | LL | #[no_std] fn f() { } @@ -1030,7 +856,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] struct S; | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct +note: this attribute does not have an `!`, which means it is applied to this struct --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:15 | LL | #[no_std] struct S; @@ -1042,7 +868,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] type T = S; | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias +note: this attribute does not have an `!`, which means it is applied to this type alias --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:15 | LL | #[no_std] type T = S; @@ -1054,7 +880,7 @@ warning: crate-level attribute should be an inner attribute: add an exclamation LL | #[no_std] impl S { } | ^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block +note: this attribute does not have an `!`, which means it is applied to this implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:15 | LL | #[no_std] impl S { } @@ -1222,50 +1048,59 @@ LL | #[link_section = "1800"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = help: `#[link_section]` can be applied to functions and statics +warning: `#[link_section]` attribute cannot be used on required trait methods + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:9 + | +LL | #[link_section = "1800"] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[link_section]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks + warning: `#[must_use]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:1 | LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[must_use]` attribute cannot be used on modules - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:17 | LL | mod inner { #![must_use] } | ^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[must_use]` attribute cannot be used on type aliases - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:771:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:775:5 | LL | #[must_use] type T = S; | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: `#[must_use]` attribute cannot be used on inherent impl blocks - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:776:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:780:5 | LL | #[must_use] impl S { } | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:782:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:1 | LL | #[windows_subsystem = "windows"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:784:1 +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:788:1 | LL | / mod windows_subsystem { LL | | @@ -1275,67 +1110,67 @@ LL | | } | |_^ warning: the `#![windows_subsystem]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:17 | LL | mod inner { #![windows_subsystem="windows"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 | LL | #[windows_subsystem = "windows"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:789:38 +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:38 | LL | #[windows_subsystem = "windows"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5 | LL | #[windows_subsystem = "windows"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:793:38 +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:38 | LL | #[windows_subsystem = "windows"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5 | LL | #[windows_subsystem = "windows"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:797:38 +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:38 | LL | #[windows_subsystem = "windows"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:5 | LL | #[windows_subsystem = "windows"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:801:38 +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:805:38 | LL | #[windows_subsystem = "windows"] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:808:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:812:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:810:1 +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:814:1 | LL | / mod crate_name { LL | | @@ -1345,67 +1180,277 @@ LL | | } | |_^ warning: the `#![crate_name]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:812:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:816:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:28 +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:28 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:28 +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:28 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:823:28 +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:28 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:827:28 +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:831:28 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^ +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:836:1 + | +LL | #[crate_type = "0800"] + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:838:1 + | +LL | / mod crate_type { +LL | | +LL | | mod inner { #![crate_type="0800"] } +... | +LL | | } + | |_^ + +warning: the `#![crate_type]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:840:17 + | +LL | mod inner { #![crate_type="0800"] } + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 + | +LL | #[crate_type = "0800"] fn f() { } + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:28 + | +LL | #[crate_type = "0800"] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 + | +LL | #[crate_type = "0800"] struct S; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:28 + | +LL | #[crate_type = "0800"] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5 + | +LL | #[crate_type = "0800"] type T = S; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:28 + | +LL | #[crate_type = "0800"] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:855:5 + | +LL | #[crate_type = "0800"] impl S { } + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:855:28 + | +LL | #[crate_type = "0800"] impl S { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1 + | +LL | #[no_main] + | ^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:887:1 + | +LL | / mod no_main_1 { +LL | | +LL | | mod inner { #![no_main] } +... | +LL | | } + | |_^ + +warning: the `#![no_main]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:889:17 + | +LL | mod inner { #![no_main] } + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5 + | +LL | #[no_main] fn f() { } + | ^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:16 + | +LL | #[no_main] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5 + | +LL | #[no_main] struct S; + | ^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:16 + | +LL | #[no_main] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5 + | +LL | #[no_main] type T = S; + | ^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:16 + | +LL | #[no_main] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:5 + | +LL | #[no_main] impl S { } + | ^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:16 + | +LL | #[no_main] impl S { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_builtins]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:1 + | +LL | #[no_builtins] + | ^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:911:1 + | +LL | / mod no_builtins { +LL | | +LL | | mod inner { #![no_builtins] } +... | +LL | | } + | |_^ + +warning: the `#![no_builtins]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:913:17 + | +LL | mod inner { #![no_builtins] } + | ^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_builtins]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:916:5 + | +LL | #[no_builtins] fn f() { } + | ^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:916:20 + | +LL | #[no_builtins] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_builtins]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:5 + | +LL | #[no_builtins] struct S; + | ^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:920:20 + | +LL | #[no_builtins] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_builtins]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:924:5 + | +LL | #[no_builtins] type T = S; + | ^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:924:20 + | +LL | #[no_builtins] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_builtins]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:928:5 + | +LL | #[no_builtins] impl S { } + | ^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:928:20 + | +LL | #[no_builtins] impl S { } + | ^^^^^^^^^^ + warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:929:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:931:1 +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:935:1 | LL | / mod recursion_limit { LL | | @@ -1415,67 +1460,67 @@ LL | | } | |_^ warning: the `#![recursion_limit]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:937:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:936:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:936:31 +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:31 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:940:31 +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:31 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:944:31 +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:31 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:952:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:948:31 +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:952:31 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:953:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:955:1 +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:959:1 | LL | / mod type_length_limit { LL | | @@ -1485,55 +1530,55 @@ LL | | } | |_^ warning: the `#![type_length_limit]` attribute can only be used at the crate root - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:957:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:961:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:960:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this function - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:960:33 +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:33 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this struct - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:964:33 +note: this attribute does not have an `!`, which means it is applied to this struct + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:33 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this type alias - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:968:33 +note: this attribute does not have an `!`, which means it is applied to this type alias + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:33 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![type_length_limit]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:976:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: This attribute does not have an `!`, which means it is applied to this implementation block - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:972:33 +note: this attribute does not have an `!`, which means it is applied to this implementation block + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:976:33 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^ @@ -1599,7 +1644,7 @@ LL | #![must_use] | ^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = help: `#[must_use]` can be applied to data types, functions, and traits -warning: 174 warnings emitted +warning: 175 warnings emitted diff --git a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs index 67959a318297..274faa4495ef 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.rs @@ -13,7 +13,7 @@ mod macro_escape { //~^ ERROR arguments to `macro_use` are not allowed here #[macro_use = "2700"] struct S; - //~^ ERROR valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` + //~^ ERROR malformed //~| WARN cannot be used on //~| WARN previously accepted diff --git a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr index 5be17e96fb15..1aa0e8fc2830 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-macro_use.stderr @@ -16,11 +16,23 @@ error: arguments to `macro_use` are not allowed here LL | #![macro_use(my_macro)] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` +error[E0539]: malformed `macro_use` attribute input --> $DIR/issue-43106-gating-of-macro_use.rs:15:5 | LL | #[macro_use = "2700"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^--------^ + | | + | expected a list or no arguments here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_use = "2700"] struct S; +LL + #[macro_use(name1, name2, ...)] struct S; + | +LL - #[macro_use = "2700"] struct S; +LL + #[macro_use] struct S; + | warning: `#[macro_use]` attribute cannot be used on structs --> $DIR/issue-43106-gating-of-macro_use.rs:15:5 @@ -61,3 +73,4 @@ LL | #[macro_use] impl S { } error: aborting due to 4 previous errors; 4 warnings emitted +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/feature-gates/remap-path-scope-documentation.rs b/tests/ui/feature-gates/remap-path-scope-documentation.rs new file mode 100644 index 000000000000..55610c037628 --- /dev/null +++ b/tests/ui/feature-gates/remap-path-scope-documentation.rs @@ -0,0 +1,7 @@ +// Test that documentation scope is unstable + +//@ compile-flags: --remap-path-scope=documentation + +//~? ERROR remapping `documentation` path scope requested but `-Zunstable-options` not specified + +fn main() {} diff --git a/tests/ui/feature-gates/remap-path-scope-documentation.stderr b/tests/ui/feature-gates/remap-path-scope-documentation.stderr new file mode 100644 index 000000000000..03316ad86a54 --- /dev/null +++ b/tests/ui/feature-gates/remap-path-scope-documentation.stderr @@ -0,0 +1,2 @@ +error: remapping `documentation` path scope requested but `-Zunstable-options` not specified + diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs index d8c5f48f9fd9..a7dde7c97f6a 100644 --- a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.rs @@ -1,3 +1,4 @@ +#![deny(invalid_doc_attributes)] #![feature(external_doc)] //~ ERROR feature has been removed #![doc(include("README.md"))] //~ ERROR unknown `doc` attribute `include` diff --git a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr index bd8c56c61c3c..a009898761df 100644 --- a/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr +++ b/tests/ui/feature-gates/removed-features-note-version-and-pr-issue-141619.stderr @@ -1,5 +1,5 @@ error[E0557]: feature has been removed - --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:1:12 + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:2:12 | LL | #![feature(external_doc)] | ^^^^^^^^^^^^ feature has been removed @@ -8,12 +8,16 @@ LL | #![feature(external_doc)] = note: use #[doc = include_str!("filename")] instead, which handles macro invocations error: unknown `doc` attribute `include` - --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:2:8 + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:3:8 | LL | #![doc(include("README.md"))] - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ | - = note: `#[deny(invalid_doc_attributes)]` on by default +note: the lint level is defined here + --> $DIR/removed-features-note-version-and-pr-issue-141619.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/unknown-feature.rs b/tests/ui/feature-gates/unknown-feature.rs index 20fd932d4c2f..a9e8e046eb16 100644 --- a/tests/ui/feature-gates/unknown-feature.rs +++ b/tests/ui/feature-gates/unknown-feature.rs @@ -1,3 +1,16 @@ -#![feature(unknown_rust_feature)] //~ ERROR unknown feature +#![feature( + unknown_rust_feature, + //~^ ERROR unknown feature + + // Typo for lang feature + associated_types_default, + //~^ ERROR unknown feature + //~| HELP there is a feature with a similar name + + // Typo for lib feature + core_intrnisics, + //~^ ERROR unknown feature + //~| HELP there is a feature with a similar name +)] fn main() {} diff --git a/tests/ui/feature-gates/unknown-feature.stderr b/tests/ui/feature-gates/unknown-feature.stderr index 0a731ddcc0b6..1e5b953e99ca 100644 --- a/tests/ui/feature-gates/unknown-feature.stderr +++ b/tests/ui/feature-gates/unknown-feature.stderr @@ -1,9 +1,33 @@ error[E0635]: unknown feature `unknown_rust_feature` - --> $DIR/unknown-feature.rs:1:12 + --> $DIR/unknown-feature.rs:2:5 | -LL | #![feature(unknown_rust_feature)] - | ^^^^^^^^^^^^^^^^^^^^ +LL | unknown_rust_feature, + | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0635]: unknown feature `associated_types_default` + --> $DIR/unknown-feature.rs:6:5 + | +LL | associated_types_default, + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: there is a feature with a similar name: `associated_type_defaults` + | +LL - associated_types_default, +LL + associated_type_defaults, + | + +error[E0635]: unknown feature `core_intrnisics` + --> $DIR/unknown-feature.rs:11:5 + | +LL | core_intrnisics, + | ^^^^^^^^^^^^^^^ + | +help: there is a feature with a similar name: `core_intrinsics` + | +LL - core_intrnisics, +LL + core_intrinsics, + | + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr b/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr index d599523c7274..319056a9c889 100644 --- a/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr +++ b/tests/ui/feature-gates/unstable-attribute-rejects-already-stable-features.stderr @@ -1,17 +1,3 @@ -error: can't mark as unstable using an already stable feature - --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 - | -LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable -LL | const fn my_fun() {} - | -------------------- the stability attribute annotates this item - | -help: consider removing the attribute - --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 - | -LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: can't mark as unstable using an already stable feature --> $DIR/unstable-attribute-rejects-already-stable-features.rs:6:1 | @@ -27,5 +13,19 @@ help: consider removing the attribute LL | #[unstable(feature = "arbitrary_enum_discriminant", issue = "42")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: can't mark as unstable using an already stable feature + --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 + | +LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this feature is already stable +LL | const fn my_fun() {} + | -------------------- the stability attribute annotates this item + | +help: consider removing the attribute + --> $DIR/unstable-attribute-rejects-already-stable-features.rs:7:1 + | +LL | #[rustc_const_unstable(feature = "arbitrary_enum_discriminant", issue = "42")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-3656.rs b/tests/ui/ffi/ffi-struct-size-alignment.rs similarity index 100% rename from tests/ui/issues/issue-3656.rs rename to tests/ui/ffi/ffi-struct-size-alignment.rs diff --git a/tests/ui/fmt/format-args-argument-span.stderr b/tests/ui/fmt/format-args-argument-span.stderr index d46cfb438cf6..a486abe821b7 100644 --- a/tests/ui/fmt/format-args-argument-span.stderr +++ b/tests/ui/fmt/format-args-argument-span.stderr @@ -6,7 +6,6 @@ LL | println!("{x:?} {x} {x:?}"); | = help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Option<{integer}>` doesn't implement `std::fmt::Display` --> $DIR/format-args-argument-span.rs:15:37 @@ -18,7 +17,6 @@ LL | println!("{x:?} {x} {x:?}", x = Some(1)); | = help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `DisplayOnly` doesn't implement `Debug` --> $DIR/format-args-argument-span.rs:18:19 @@ -28,7 +26,6 @@ LL | println!("{x} {x:?} {x}"); | = help: the trait `Debug` is not implemented for `DisplayOnly` = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `DisplayOnly` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -45,7 +42,6 @@ LL | println!("{x} {x:?} {x}", x = DisplayOnly); | = help: the trait `Debug` is not implemented for `DisplayOnly` = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `DisplayOnly` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/fmt/format-args-capture-issue-102057.stderr b/tests/ui/fmt/format-args-capture-issue-102057.stderr index f2d625e7f8dc..9a5bc5365df7 100644 --- a/tests/ui/fmt/format-args-capture-issue-102057.stderr +++ b/tests/ui/fmt/format-args-capture-issue-102057.stderr @@ -14,31 +14,61 @@ error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:9:22 | LL | format!("\x7Ba} {b}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba} {b}"); +LL + format!("\x7Ba} {a}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:11:25 | LL | format!("\x7Ba\x7D {b}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba\x7D {b}"); +LL + format!("\x7Ba\x7D {a}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:13:25 | LL | format!("\x7Ba} \x7Bb}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba} \x7Bb}"); +LL + format!("\x7Ba} \x7Ba}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:15:28 | LL | format!("\x7Ba\x7D \x7Bb}"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba\x7D \x7Bb}"); +LL + format!("\x7Ba\x7D \x7Ba}"); + | error[E0425]: cannot find value `b` in this scope --> $DIR/format-args-capture-issue-102057.rs:17:28 | LL | format!("\x7Ba\x7D \x7Bb\x7D"); - | ^ help: a local variable with a similar name exists: `a` + | ^ + | +help: a local variable with a similar name exists + | +LL - format!("\x7Ba\x7D \x7Bb\x7D"); +LL + format!("\x7Ba\x7D \x7Ba\x7D"); + | error: aborting due to 7 previous errors diff --git a/tests/ui/fmt/format-args-capture-issue-94010.stderr b/tests/ui/fmt/format-args-capture-issue-94010.stderr index ed90dc855360..ccdaf0c67b2b 100644 --- a/tests/ui/fmt/format-args-capture-issue-94010.stderr +++ b/tests/ui/fmt/format-args-capture-issue-94010.stderr @@ -4,7 +4,13 @@ error[E0425]: cannot find value `foo` in this scope LL | const FOO: i32 = 123; | --------------------- similarly named constant `FOO` defined here LL | println!("{foo:X}"); - | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` + | ^^^ + | +help: a constant with a similar name exists (notice the capitalization) + | +LL - println!("{foo:X}"); +LL + println!("{FOO:X}"); + | error[E0425]: cannot find value `foo` in this scope --> $DIR/format-args-capture-issue-94010.rs:5:18 @@ -13,7 +19,13 @@ LL | const FOO: i32 = 123; | --------------------- similarly named constant `FOO` defined here ... LL | println!("{:.foo$}", 0); - | ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO` + | ^^^ + | +help: a constant with a similar name exists (notice the capitalization) + | +LL - println!("{:.foo$}", 0); +LL + println!("{:.FOO$}", 0); + | error: aborting due to 2 previous errors diff --git a/tests/ui/fmt/format-string-error-2.rs b/tests/ui/fmt/format-string-error-2.rs index 357dd7b10a3e..c1d228bfbc9c 100644 --- a/tests/ui/fmt/format-string-error-2.rs +++ b/tests/ui/fmt/format-string-error-2.rs @@ -83,4 +83,12 @@ raw { \n println!(r#"\x7B}\u8 {"#, 1); //~^ ERROR invalid format string: unmatched `}` found + + println!("{x?}, world!",); + //~^ ERROR invalid format string: expected `}`, found `?` + println!("{x,}, world!",); + //~^ ERROR invalid format string: python's numeric grouping `,` is not supported in rust format strings + + println!("{x=}"); + //~^ ERROR invalid format string: python's f-string debug `=` is not supported in rust, use `dbg(x)` instead } diff --git a/tests/ui/fmt/format-string-error-2.stderr b/tests/ui/fmt/format-string-error-2.stderr index 6d8c34fdb709..b12e827853f8 100644 --- a/tests/ui/fmt/format-string-error-2.stderr +++ b/tests/ui/fmt/format-string-error-2.stderr @@ -177,5 +177,36 @@ LL | println!(r#"\x7B}\u8 {"#, 1); | = note: if you intended to print `}`, you can escape it using `}}` -error: aborting due to 18 previous errors +error: invalid format string: expected `}`, found `?` + --> $DIR/format-string-error-2.rs:87:17 + | +LL | println!("{x?}, world!",); + | ^ + | | + | expected `:` before `?` to format with `Debug` in format string + | help: add a colon before the format specifier: `:?` + | + = note: to print `{`, you can escape it using `{{` + +error: invalid format string: python's numeric grouping `,` is not supported in rust format strings + --> $DIR/format-string-error-2.rs:89:17 + | +LL | println!("{x,}, world!",); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: to print `{`, you can escape it using `{{` + +error: invalid format string: python's f-string debug `=` is not supported in rust, use `dbg(x)` instead + --> $DIR/format-string-error-2.rs:92:17 + | +LL | println!("{x=}"); + | - ^ expected `}` in format string + | | + | because of this opening brace + | + = note: to print `{`, you can escape it using `{{` + +error: aborting due to 21 previous errors diff --git a/tests/ui/fmt/format-string-error-3.fixed b/tests/ui/fmt/format-string-error-3.fixed new file mode 100644 index 000000000000..16a169db1147 --- /dev/null +++ b/tests/ui/fmt/format-string-error-3.fixed @@ -0,0 +1,5 @@ +//@ run-rustfix +fn main() { + let x = 32; + dbg!(x); //~ ERROR invalid format string: python's f-string debug +} diff --git a/tests/ui/fmt/format-string-error-3.rs b/tests/ui/fmt/format-string-error-3.rs new file mode 100644 index 000000000000..bd61233a475e --- /dev/null +++ b/tests/ui/fmt/format-string-error-3.rs @@ -0,0 +1,5 @@ +//@ run-rustfix +fn main() { + let x = 32; + println!("{=}", x); //~ ERROR invalid format string: python's f-string debug +} diff --git a/tests/ui/fmt/format-string-error-3.stderr b/tests/ui/fmt/format-string-error-3.stderr new file mode 100644 index 000000000000..e07f47cff5a6 --- /dev/null +++ b/tests/ui/fmt/format-string-error-3.stderr @@ -0,0 +1,17 @@ +error: invalid format string: python's f-string debug `=` is not supported in rust, use `dbg(x)` instead + --> $DIR/format-string-error-3.rs:4:16 + | +LL | println!("{=}", x); + | -^ expected `}` in format string + | | + | because of this opening brace + | + = note: to print `{`, you can escape it using `{{` +help: use rust debug printing macro + | +LL - println!("{=}", x); +LL + dbg!(x); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index b565b836f211..9018482e7078 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -320,7 +320,6 @@ LL | println!("{} {:.*} {}", 1, 3.2, 4); found reference `&{float}` note: associated function defined here --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:81:35 @@ -334,7 +333,6 @@ LL | println!("{} {:07$.*} {}", 1, 3.2, 4); found reference `&{float}` note: associated function defined here --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 38 previous errors diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr index 5e80f892dcb5..5e97e69c7cf3 100644 --- a/tests/ui/fmt/ifmt-unimpl.stderr +++ b/tests/ui/fmt/ifmt-unimpl.stderr @@ -17,7 +17,6 @@ LL | format!("{:X}", "3"); i32 and 9 others = note: required for `&str` to implement `UpperHex` - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/fmt/non-source-literals.stderr b/tests/ui/fmt/non-source-literals.stderr index 5f042e1e631a..953a4a64fd8d 100644 --- a/tests/ui/fmt/non-source-literals.stderr +++ b/tests/ui/fmt/non-source-literals.stderr @@ -10,7 +10,6 @@ help: the trait `std::fmt::Display` is not implemented for `NonDisplay` LL | pub struct NonDisplay; | ^^^^^^^^^^^^^^^^^^^^^ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `NonDisplay` doesn't implement `std::fmt::Display` --> $DIR/non-source-literals.rs:10:45 @@ -24,7 +23,6 @@ help: the trait `std::fmt::Display` is not implemented for `NonDisplay` LL | pub struct NonDisplay; | ^^^^^^^^^^^^^^^^^^^^^ = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `NonDebug` doesn't implement `Debug` --> $DIR/non-source-literals.rs:11:42 @@ -34,7 +32,6 @@ LL | let _ = format!(concat!("{:", "?}"), NonDebug); | = help: the trait `Debug` is not implemented for `NonDebug` = note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug` - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `NonDebug` with `#[derive(Debug)]` | LL + #[derive(Debug)] @@ -49,7 +46,6 @@ LL | let _ = format!(concat!("{", "0", ":?}"), NonDebug); | = help: the trait `Debug` is not implemented for `NonDebug` = note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug` - = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider annotating `NonDebug` with `#[derive(Debug)]` | LL + #[derive(Debug)] diff --git a/tests/ui/fmt/println-float.rs b/tests/ui/fmt/println-float.rs new file mode 100644 index 000000000000..3adb0b434349 --- /dev/null +++ b/tests/ui/fmt/println-float.rs @@ -0,0 +1,5 @@ +//! regression test for https://github.com/rust-lang/rust/issues/11382 +//@ run-pass +fn main() { + println!("{}", 1.2); +} diff --git a/tests/ui/fn/error-recovery-mismatch.stderr b/tests/ui/fn/error-recovery-mismatch.stderr index 400af46e2a27..7a320c6bc695 100644 --- a/tests/ui/fn/error-recovery-mismatch.stderr +++ b/tests/ui/fn/error-recovery-mismatch.stderr @@ -26,7 +26,7 @@ LL | fn fold(&self, _: T, &self._) {} | ^ help: try naming the parameter or explicitly ignoring it: `_: _` | = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 + = note: for more information, see = note: `#[warn(anonymous_parameters)]` (part of `#[warn(rust_2018_compatibility)]`) on by default error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods diff --git a/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr b/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr index 85e3452fbf2c..95fac3ce51d2 100644 --- a/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr +++ b/tests/ui/fn/implied-bounds-unnorm-associated-type-2.stderr @@ -9,9 +9,6 @@ LL | f::<'a, 'b>(()); | ^^^^^^^^^^^^^^^ generic argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of a function pointer to `f` - = note: the function `f` is invariant over the parameter `'a` - = help: see for more information about variance error: aborting due to 1 previous error diff --git a/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs b/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs new file mode 100644 index 000000000000..15554482931b --- /dev/null +++ b/tests/ui/fn_traits/call-unit-struct-impl-fn-once.rs @@ -0,0 +1,18 @@ +//! regression test for +//@ run-pass +#![feature(unboxed_closures)] +#![feature(fn_traits)] + +struct Test; + +impl FnOnce<(u32, u32)> for Test { + type Output = u32; + + extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { + a + b + } +} + +fn main() { + assert_eq!(Test(1u32, 2u32), 3u32); +} diff --git a/tests/ui/fn_traits/fn-trait-explicit-call.rs b/tests/ui/fn_traits/fn-trait-explicit-call.rs new file mode 100644 index 000000000000..f37e0a558baa --- /dev/null +++ b/tests/ui/fn_traits/fn-trait-explicit-call.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ run-pass +#![feature(fn_traits)] + +fn say(x: u32, y: u32) { + println!("{} {}", x, y); +} + +fn main() { + Fn::call(&say, (1, 2)); +} diff --git a/tests/ui/for-loop-while/break-continue-in-loop-while-condition.rs b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.rs new file mode 100644 index 000000000000..d1fcb6dbb537 --- /dev/null +++ b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.rs @@ -0,0 +1,65 @@ +//! regression test for #37576, #50802 +//! Tests that using unlabeled `break` or `continue` within a loop or while's condition. + +fn main() { + 'test_1: while break 'test_1 {} + while break {} + //~^ ERROR `break` or `continue` with no label + + 'test_2: while let true = break 'test_2 {} + while let true = break {} + //~^ ERROR `break` or `continue` with no label + + loop { + 'test_3: while break 'test_3 {} + } + loop { + while break {} + //~^ ERROR `break` or `continue` with no label + } + + loop { + 'test_4: while break 'test_4 {} + break; + } + loop { + while break {} + //~^ ERROR `break` or `continue` with no label + break; + } + + 'test_5: while continue 'test_5 {} + while continue {} + //~^ ERROR `break` or `continue` with no label + + 'test_6: while let true = continue 'test_6 {} + while let true = continue {} + //~^ ERROR `break` or `continue` with no label + + loop { + 'test_7: while continue 'test_7 {} + } + loop { + while continue {} + //~^ ERROR `break` or `continue` with no label + } + + loop { + 'test_8: while continue 'test_8 {} + continue; + } + loop { + while continue {} + //~^ ERROR `break` or `continue` with no label + continue; + } + + 'test_9: loop { + break while continue 'test_9 {}; + } + loop { + break while continue { + //~^ ERROR `break` or `continue` with no label + }; + } +} diff --git a/tests/ui/for-loop-while/break-continue-in-loop-while-condition.stderr b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.stderr new file mode 100644 index 000000000000..dac6dc2e30bc --- /dev/null +++ b/tests/ui/for-loop-while/break-continue-in-loop-while-condition.stderr @@ -0,0 +1,57 @@ +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:6:11 + | +LL | while break {} + | ^^^^^ unlabeled `break` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:10:22 + | +LL | while let true = break {} + | ^^^^^ unlabeled `break` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:17:15 + | +LL | while break {} + | ^^^^^ unlabeled `break` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:26:15 + | +LL | while break {} + | ^^^^^ unlabeled `break` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:32:11 + | +LL | while continue {} + | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:36:22 + | +LL | while let true = continue {} + | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:43:15 + | +LL | while continue {} + | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:52:15 + | +LL | while continue {} + | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop + +error[E0590]: `break` or `continue` with no label in the condition of a `while` loop + --> $DIR/break-continue-in-loop-while-condition.rs:61:21 + | +LL | break while continue { + | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0590`. diff --git a/tests/ui/for-loop-while/break-outside-loop.rs b/tests/ui/for-loop-while/break-outside-loop.rs index 26769b30dd5f..06c513aa8457 100644 --- a/tests/ui/for-loop-while/break-outside-loop.rs +++ b/tests/ui/for-loop-while/break-outside-loop.rs @@ -1,25 +1,41 @@ struct Foo { - t: String + t: String, } -fn cond() -> bool { true } +fn cond() -> bool { + true +} -fn foo(_: F) where F: FnOnce() {} +fn foo(_: F) +where + F: FnOnce(), +{ +} fn main() { let pth = break; //~ ERROR: `break` outside of a loop - if cond() { continue } //~ ERROR: `continue` outside of a loop + if cond() { + continue; //~ ERROR: `continue` outside of a loop + } while cond() { - if cond() { break } - if cond() { continue } + if cond() { + break; + } + if cond() { + continue; + } foo(|| { - if cond() { break } //~ ERROR: `break` inside of a closure - if cond() { continue } //~ ERROR: `continue` inside of a closure + if cond() { + break; //~ ERROR: `break` inside of a closure + } + if cond() { + continue; //~ ERROR: `continue` inside of a closure + } }) } - let rs: Foo = Foo{t: pth}; + let rs: Foo = Foo { t: pth }; let unconstrained = break; //~ ERROR: `break` outside of a loop @@ -32,4 +48,10 @@ fn main() { //~| ERROR `break` inside of a closure }; } + + // Make sure that a continue span actually contains the keyword. (#28105) + continue //~ ERROR `continue` outside of a loop + ; + break //~ ERROR `break` outside of a loop + ; } diff --git a/tests/ui/for-loop-while/break-outside-loop.stderr b/tests/ui/for-loop-while/break-outside-loop.stderr index 9092f34df354..7dbff2d41245 100644 --- a/tests/ui/for-loop-while/break-outside-loop.stderr +++ b/tests/ui/for-loop-while/break-outside-loop.stderr @@ -1,5 +1,5 @@ error[E0767]: use of unreachable label `'lab` - --> $DIR/break-outside-loop.rs:30:19 + --> $DIR/break-outside-loop.rs:46:19 | LL | 'lab: loop { | ---- unreachable label defined here @@ -10,49 +10,62 @@ LL | break 'lab; = note: labels are unreachable through functions, closures, async blocks and modules error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-outside-loop.rs:10:15 + --> $DIR/break-outside-loop.rs:16:15 | LL | let pth = break; | ^^^^^ cannot `break` outside of a loop or labeled block error[E0268]: `continue` outside of a loop - --> $DIR/break-outside-loop.rs:11:17 + --> $DIR/break-outside-loop.rs:18:9 | -LL | if cond() { continue } - | ^^^^^^^^ cannot `continue` outside of a loop +LL | continue; + | ^^^^^^^^ cannot `continue` outside of a loop error[E0267]: `break` inside of a closure - --> $DIR/break-outside-loop.rs:17:25 + --> $DIR/break-outside-loop.rs:30:17 | LL | foo(|| { | -- enclosing closure -LL | if cond() { break } - | ^^^^^ cannot `break` inside of a closure +LL | if cond() { +LL | break; + | ^^^^^ cannot `break` inside of a closure error[E0267]: `continue` inside of a closure - --> $DIR/break-outside-loop.rs:18:25 + --> $DIR/break-outside-loop.rs:33:17 | LL | foo(|| { | -- enclosing closure -LL | if cond() { break } -LL | if cond() { continue } - | ^^^^^^^^ cannot `continue` inside of a closure +... +LL | continue; + | ^^^^^^^^ cannot `continue` inside of a closure error[E0268]: `break` outside of a loop or labeled block - --> $DIR/break-outside-loop.rs:24:25 + --> $DIR/break-outside-loop.rs:40:25 | LL | let unconstrained = break; | ^^^^^ cannot `break` outside of a loop or labeled block error[E0267]: `break` inside of a closure - --> $DIR/break-outside-loop.rs:30:13 + --> $DIR/break-outside-loop.rs:46:13 | LL | || { | -- enclosing closure LL | break 'lab; | ^^^^^^^^^^ cannot `break` inside of a closure -error: aborting due to 7 previous errors +error[E0268]: `continue` outside of a loop + --> $DIR/break-outside-loop.rs:53:5 + | +LL | continue + | ^^^^^^^^ cannot `continue` outside of a loop + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/break-outside-loop.rs:55:5 + | +LL | break + | ^^^^^ cannot `break` outside of a loop or labeled block + +error: aborting due to 9 previous errors Some errors have detailed explanations: E0267, E0268, E0767. For more information about an error, try `rustc --explain E0267`. diff --git a/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.rs b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.rs new file mode 100644 index 000000000000..69b57486138d --- /dev/null +++ b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.rs @@ -0,0 +1,39 @@ +//! Don't suggest breaking with value from `for` or `while` loops +//! +//! Regression test for https://github.com/rust-lang/rust/issues/150850 + +fn returns_i32() -> i32 { 0 } + +fn suggest_breaking_from_loop() { + let _ = loop { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + //~| SUGGESTION break + }; +} + +fn dont_suggest_breaking_from_for() { + let _ = for _ in 0.. { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + }; +} + +fn dont_suggest_breaking_from_while() { + let cond = true; + let _ = while cond { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + }; +} + +fn dont_suggest_breaking_from_for_nested_in_loop() { + let _ = loop { + for _ in 0.. { + returns_i32() //~ ERROR mismatched types + //~^ SUGGESTION ; + } + }; +} + +fn main() {} diff --git a/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.stderr b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.stderr new file mode 100644 index 000000000000..880cc53f9a7c --- /dev/null +++ b/tests/ui/for-loop-while/dont-suggest-break-from-unbreakable-loops.stderr @@ -0,0 +1,42 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:9:9 + | +LL | returns_i32() + | ^^^^^^^^^^^^^ expected `()`, found `i32` + | +help: consider using a semicolon here + | +LL | returns_i32(); + | + +help: you might have meant to break the loop with this value + | +LL | break returns_i32(); + | +++++ + + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:17:9 + | +LL | returns_i32() + | ^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:25:9 + | +LL | returns_i32() + | ^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-from-unbreakable-loops.rs:33:13 + | +LL | returns_i32() + | ^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `i32` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/for-loop-while/nested-loop-break-unit.rs b/tests/ui/for-loop-while/nested-loop-break-unit.rs new file mode 100644 index 000000000000..b31d9ee8f50d --- /dev/null +++ b/tests/ui/for-loop-while/nested-loop-break-unit.rs @@ -0,0 +1,10 @@ +//! regression test for issue #2642 +//@ run-pass +#![allow(dead_code)] + +fn f() { + let _x: usize = loop { loop { break; } }; +} + +pub fn main() { +} diff --git a/tests/ui/force-inlining/asm.rs b/tests/ui/force-inlining/asm.rs index d48af8253d83..d48b9fc01be6 100644 --- a/tests/ui/force-inlining/asm.rs +++ b/tests/ui/force-inlining/asm.rs @@ -2,6 +2,7 @@ //@ build-fail //@ compile-flags: --crate-type=lib --target thumbv4t-none-eabi //@ needs-llvm-components: arm +//@ ignore-backends: gcc // Checks that forced inlining won't mix asm with incompatible instruction sets. diff --git a/tests/ui/force-inlining/asm.stderr b/tests/ui/force-inlining/asm.stderr index 1744c0215bb4..a73b3f665ae2 100644 --- a/tests/ui/force-inlining/asm.stderr +++ b/tests/ui/force-inlining/asm.stderr @@ -1,5 +1,5 @@ error: `instruction_set_a32` could not be inlined into `t32` but is required to be inlined - --> $DIR/asm.rs:45:5 + --> $DIR/asm.rs:46:5 | LL | instruction_set_a32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_a32` called here @@ -7,7 +7,7 @@ LL | instruction_set_a32(); = note: could not be inlined due to: incompatible instruction set error: `inline_always_and_using_inline_asm` could not be inlined into `t32` but is required to be inlined - --> $DIR/asm.rs:49:5 + --> $DIR/asm.rs:50:5 | LL | inline_always_and_using_inline_asm(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...`inline_always_and_using_inline_asm` called here @@ -15,7 +15,7 @@ LL | inline_always_and_using_inline_asm(); = note: could not be inlined due to: cannot move inline-asm across instruction sets error: `instruction_set_a32` could not be inlined into `default` but is required to be inlined - --> $DIR/asm.rs:54:5 + --> $DIR/asm.rs:55:5 | LL | instruction_set_a32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_a32` called here @@ -23,7 +23,7 @@ LL | instruction_set_a32(); = note: could not be inlined due to: incompatible instruction set error: `instruction_set_t32` could not be inlined into `default` but is required to be inlined - --> $DIR/asm.rs:56:5 + --> $DIR/asm.rs:57:5 | LL | instruction_set_t32(); | ^^^^^^^^^^^^^^^^^^^^^ ...`instruction_set_t32` called here diff --git a/tests/ui/force-inlining/invalid.stderr b/tests/ui/force-inlining/invalid.stderr index df3b646b6cec..ce4f1d77ad2d 100644 --- a/tests/ui/force-inlining/invalid.stderr +++ b/tests/ui/force-inlining/invalid.stderr @@ -152,7 +152,7 @@ LL | #[rustc_force_inline] | = help: `#[rustc_force_inline]` can only be applied to functions -error: `#[rustc_force_inline]` attribute cannot be used on function params +error: `#[rustc_force_inline]` attribute cannot be used on type parameters --> $DIR/invalid.rs:72:10 | LL | enum Bar<#[rustc_force_inline] T> { diff --git a/tests/ui/foreign/stashed-issue-121451.rs b/tests/ui/foreign/stashed-issue-121451.rs index 77a736739bfa..f71e9dd8cc4e 100644 --- a/tests/ui/foreign/stashed-issue-121451.rs +++ b/tests/ui/foreign/stashed-issue-121451.rs @@ -1,4 +1,4 @@ extern "C" fn _f() -> libc::uintptr_t {} -//~^ ERROR failed to resolve +//~^ ERROR cannot find fn main() {} diff --git a/tests/ui/foreign/stashed-issue-121451.stderr b/tests/ui/foreign/stashed-issue-121451.stderr index 31dd3b4fb5e8..8a84d5e918ee 100644 --- a/tests/ui/foreign/stashed-issue-121451.stderr +++ b/tests/ui/foreign/stashed-issue-121451.stderr @@ -1,4 +1,4 @@ -error[E0433]: failed to resolve: use of unresolved module or unlinked crate `libc` +error[E0433]: cannot find module or crate `libc` in this scope --> $DIR/stashed-issue-121451.rs:1:23 | LL | extern "C" fn _f() -> libc::uintptr_t {} diff --git a/tests/ui/frontmatter/content-cr.rs b/tests/ui/frontmatter/content-cr.rs new file mode 100644 index 000000000000..71bede928f37 --- /dev/null +++ b/tests/ui/frontmatter/content-cr.rs @@ -0,0 +1,10 @@ +--- +package.name = " " # //~ ERROR bare CR not allowed in frontmatter +package.description = "é" +--- + +// ignore-tidy-cr + +#![feature(frontmatter)] + +pub fn main() {} diff --git a/tests/ui/frontmatter/content-cr.stderr b/tests/ui/frontmatter/content-cr.stderr new file mode 100644 index 000000000000..d59b899cc4c3 --- /dev/null +++ b/tests/ui/frontmatter/content-cr.stderr @@ -0,0 +1,8 @@ +error: bare CR not allowed in frontmatter + --> $DIR/content-cr.rs:2:17 + | +LL | package.name = "â" # + | ^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/functions-closures/parallel-codegen-closures.rs b/tests/ui/functions-closures/parallel-codegen-closures.rs index 1842ac4db606..8628376c7334 100644 --- a/tests/ui/functions-closures/parallel-codegen-closures.rs +++ b/tests/ui/functions-closures/parallel-codegen-closures.rs @@ -1,15 +1,12 @@ //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] -#![allow(stable_features)] // Tests parallel codegen - this can fail if the symbol for the anonymous // closure in `sum` pollutes the second codegen unit from the first. //@ compile-flags: -C codegen_units=2 -#![feature(iter_arith)] - mod a { fn foo() { let x = ["a", "bob", "c"]; diff --git a/tests/ui/generic-associated-types/equality-bound.rs b/tests/ui/generic-associated-types/equality-bound.rs index be05181f5d09..c136a6d4bdf2 100644 --- a/tests/ui/generic-associated-types/equality-bound.rs +++ b/tests/ui/generic-associated-types/equality-bound.rs @@ -8,7 +8,7 @@ fn sum2(i: I) -> i32 where I::Item = i32 { } fn sum3(i: J) -> i32 where I::Item = i32 { //~^ ERROR equality constraints are not yet supported in `where` clauses -//~| ERROR failed to resolve: use of undeclared type `I` +//~| ERROR cannot find type `I` panic!() } diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index 03fafe3e21c1..0ceb5e329ab3 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -114,28 +114,46 @@ error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:20:79 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ ... LL | struct K {} | -------- similarly named struct `K` defined here + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:31:68 | LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ ... LL | struct K {} | -------- similarly named struct `K` defined here + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, +LL + fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:42:76 | LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ ... LL | struct K {} | -------- similarly named struct `K` defined here + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, +LL + fn from_iter(_: T) -> Self where IntoIterator::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:53:65 @@ -144,7 +162,13 @@ LL | struct K {} | -------- similarly named struct `K` defined here ... LL | fn from_iter(_: T) -> Self where T::Item = A, - | ^ help: a struct with a similar name exists: `K` + | ^ + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T::Item = A, +LL + fn from_iter(_: T) -> Self where T::Item = K, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:64:62 @@ -153,7 +177,13 @@ LL | struct K {} | -------- similarly named struct `K` defined here ... LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, - | ^ help: a struct with a similar name exists: `K` + | ^ + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, +LL + fn from_iter(_: T) -> Self where IntoIterator::Item = K, T: IntoIterator, + | error[E0425]: cannot find type `A` in this scope --> $DIR/equality-bound.rs:75:51 @@ -162,16 +192,25 @@ LL | struct K {} | -------- similarly named struct `K` defined here ... LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, - | ^ help: a struct with a similar name exists: `K` + | ^ + | +help: a struct with a similar name exists + | +LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, +LL + fn from_iter(_: T) -> Self where T::Item = K, T: IntoIterator, + | -error[E0433]: failed to resolve: use of undeclared type `I` +error[E0433]: cannot find type `I` in this scope --> $DIR/equality-bound.rs:9:41 | LL | fn sum3(i: J) -> i32 where I::Item = i32 { - | ^ - | | - | use of undeclared type `I` - | help: a type parameter with a similar name exists: `J` + | ^ use of undeclared type `I` + | +help: a type parameter with a similar name exists + | +LL - fn sum3(i: J) -> i32 where I::Item = i32 { +LL + fn sum3(i: J) -> i32 where J::Item = i32 { + | error: aborting due to 16 previous errors diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.stderr index d4ccd80f1465..8dec88f6d932 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path.stderr +++ b/tests/ui/generic-associated-types/gat-in-trait-path.stderr @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Foo { | --- this trait is not dyn compatible... LL | type A<'a> where Self: 'a; - | ^ ...because it contains the generic associated type `A` + | ^ ...because it contains generic associated type `A` = help: consider moving `A` to another trait error[E0038]: the trait `Foo` is not dyn compatible @@ -27,7 +27,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait Foo { | --- this trait is not dyn compatible... LL | type A<'a> where Self: 'a; - | ^ ...because it contains the generic associated type `A` + | ^ ...because it contains generic associated type `A` = help: consider moving `A` to another trait error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/impl_bounds.stderr b/tests/ui/generic-associated-types/impl_bounds.stderr index 7847bbd813cd..65e1dff479e5 100644 --- a/tests/ui/generic-associated-types/impl_bounds.stderr +++ b/tests/ui/generic-associated-types/impl_bounds.stderr @@ -29,10 +29,12 @@ LL | type C = String where Self: Copy; | ^^^^ the trait `Copy` is not implemented for `T` | note: required for `Fooy` to implement `Copy` - --> $DIR/impl_bounds.rs:10:10 + --> $DIR/impl_bounds.rs:11:8 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ---- in this derive macro expansion +LL | struct Fooy(T); + | ^^^^ - type parameter would need to implement `Copy` note: the requirement `Fooy: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type --> $DIR/impl_bounds.rs:6:10 | @@ -53,10 +55,12 @@ LL | fn d() where Self: Copy {} | ^^^^ the trait `Copy` is not implemented for `T` | note: required for `Fooy` to implement `Copy` - --> $DIR/impl_bounds.rs:10:10 + --> $DIR/impl_bounds.rs:11:8 | LL | #[derive(Copy, Clone)] - | ^^^^ unsatisfied trait bound introduced in this `derive` macro + | ---- in this derive macro expansion +LL | struct Fooy(T); + | ^^^^ - type parameter would need to implement `Copy` note: the requirement `Fooy: Copy` appears on the `impl`'s associated function `d` but not on the corresponding trait's associated function --> $DIR/impl_bounds.rs:7:8 | diff --git a/tests/ui/generic-associated-types/issue-67510-pass.stderr b/tests/ui/generic-associated-types/issue-67510-pass.stderr index 4b56c4ef35f4..8f47407089c7 100644 --- a/tests/ui/generic-associated-types/issue-67510-pass.stderr +++ b/tests/ui/generic-associated-types/issue-67510-pass.stderr @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait X { | - this trait is not dyn compatible... LL | type Y<'a>; - | ^ ...because it contains the generic associated type `Y` + | ^ ...because it contains generic associated type `Y` = help: consider moving `Y` to another trait error: aborting due to 1 previous error diff --git a/tests/ui/generic-associated-types/issue-76535.stderr b/tests/ui/generic-associated-types/issue-76535.stderr index 2daf9d817bb3..324f35e88293 100644 --- a/tests/ui/generic-associated-types/issue-76535.stderr +++ b/tests/ui/generic-associated-types/issue-76535.stderr @@ -27,7 +27,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | pub trait SuperTrait { | ---------- this trait is not dyn compatible... LL | type SubType<'a>: SubTrait where Self: 'a; - | ^^^^^^^ ...because it contains the generic associated type `SubType` + | ^^^^^^^ ...because it contains generic associated type `SubType` = help: consider moving `SubType` to another trait = help: only type `SuperStruct` implements `SuperTrait` within this crate; consider using it directly instead. = note: `SuperTrait` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type diff --git a/tests/ui/generic-associated-types/issue-78671.stderr b/tests/ui/generic-associated-types/issue-78671.stderr index fff061a8ada7..8b744622fc81 100644 --- a/tests/ui/generic-associated-types/issue-78671.stderr +++ b/tests/ui/generic-associated-types/issue-78671.stderr @@ -27,7 +27,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait CollectionFamily { | ---------------- this trait is not dyn compatible... LL | type Member; - | ^^^^^^ ...because it contains the generic associated type `Member` + | ^^^^^^ ...because it contains generic associated type `Member` = help: consider moving `Member` to another trait error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/issue-79422.stderr b/tests/ui/generic-associated-types/issue-79422.stderr index dcf3a9008de5..d22cc48e5290 100644 --- a/tests/ui/generic-associated-types/issue-79422.stderr +++ b/tests/ui/generic-associated-types/issue-79422.stderr @@ -27,7 +27,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait MapLike { | ------- this trait is not dyn compatible... LL | type VRefCont<'a>: RefCont<'a, V> - | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` + | ^^^^^^^^ ...because it contains generic associated type `VRefCont` = help: consider moving `VRefCont` to another trait error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/trait-objects.stderr b/tests/ui/generic-associated-types/trait-objects.stderr index 8c3af6b654ab..03a7eb76d91b 100644 --- a/tests/ui/generic-associated-types/trait-objects.stderr +++ b/tests/ui/generic-associated-types/trait-objects.stderr @@ -11,7 +11,7 @@ note: for a trait to be dyn compatible it needs to allow building a vtable LL | trait StreamingIterator { | ----------------- this trait is not dyn compatible... LL | type Item<'a> where Self: 'a; - | ^^^^ ...because it contains the generic associated type `Item` + | ^^^^ ...because it contains generic associated type `Item` = help: consider moving `Item` to another trait error: aborting due to 1 previous error diff --git a/tests/ui/generic-const-items/assoc-const-bindings.rs b/tests/ui/generic-const-items/assoc-const-bindings.rs new file mode 100644 index 000000000000..c187c87c7763 --- /dev/null +++ b/tests/ui/generic-const-items/assoc-const-bindings.rs @@ -0,0 +1,34 @@ +//@ check-pass + +#![feature(generic_const_items, min_generic_const_args)] +#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)] +#![expect(incomplete_features)] + +use std::marker::{ConstParamTy, ConstParamTy_}; + +trait Owner { + type const C: u32; + type const K: u32; + type const Q: Maybe; +} + +impl Owner for () { + type const C: u32 = N; + type const K: u32 = const { 99 + 1 }; + type const Q: Maybe = Maybe::Nothing::; +} + +fn take0(_: impl Owner = { N }>) {} +fn take1(_: impl Owner = 100>) {} +fn take2(_: impl Owner = { Maybe::Just::<()>(()) }>) {} + +fn main() { + take0::<128>(()); + take1(()); +} + +#[derive(PartialEq, Eq, ConstParamTy)] +enum Maybe { + Nothing, + Just(T), +} diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.rs b/tests/ui/generic-const-items/assoc-const-missing-type.rs index dde47cf993ea..2b7167ad067e 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.rs +++ b/tests/ui/generic-const-items/assoc-const-missing-type.rs @@ -14,7 +14,7 @@ impl Trait for () { //~| ERROR mismatched types const Q = ""; //~^ ERROR missing type for `const` item - //~| ERROR lifetime parameters or bounds on associated const `Q` do not match the trait declaration + //~| ERROR lifetime parameters or bounds on associated constant `Q` do not match the trait declaration } fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-missing-type.stderr b/tests/ui/generic-const-items/assoc-const-missing-type.stderr index 9f6db575ec23..7c79133d64ec 100644 --- a/tests/ui/generic-const-items/assoc-const-missing-type.stderr +++ b/tests/ui/generic-const-items/assoc-const-missing-type.stderr @@ -15,14 +15,14 @@ error: missing type for `const` item LL | const K = (); | ^ help: provide a type for the associated constant: `()` -error[E0195]: lifetime parameters or bounds on associated const `Q` do not match the trait declaration +error[E0195]: lifetime parameters or bounds on associated constant `Q` do not match the trait declaration --> $DIR/assoc-const-missing-type.rs:15:12 | LL | const Q<'a>: &'a str; - | ---- lifetimes in impl do not match this associated const in trait + | ---- lifetimes in impl do not match this associated constant in trait ... LL | const Q = ""; - | ^ lifetimes do not match associated const in trait + | ^ lifetimes do not match associated constant in trait error: missing type for `const` item --> $DIR/assoc-const-missing-type.rs:15:12 diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index 7f4926fa2b71..df680f30fed9 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -1,6 +1,6 @@ // ICE: assertion failed: !value.has_infer() // issue: rust-lang/rust#115806 -#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)] +#![feature(adt_const_params, min_generic_const_args, unsized_const_params)] #![allow(incomplete_features)] pub struct NoPin; @@ -8,13 +8,12 @@ pub struct NoPin; impl Pins for NoPin {} pub trait PinA { - #[type_const] - const A: &'static () = &(); + type const A: &'static () = const { &() }; } pub trait Pins {} -impl Pins for T where T: PinA {} +impl Pins for T where T: PinA {} //~^ ERROR conflicting implementations of trait `Pins<_>` for type `NoPin` pub fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr index 34546349592f..b719ebe0664f 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr @@ -1,11 +1,11 @@ error[E0119]: conflicting implementations of trait `Pins<_>` for type `NoPin` - --> $DIR/assoc-const-no-infer-ice-115806.rs:17:1 + --> $DIR/assoc-const-no-infer-ice-115806.rs:16:1 | LL | impl Pins for NoPin {} | --------------------------- first implementation here ... -LL | impl Pins for T where T: PinA {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `NoPin` +LL | impl Pins for T where T: PinA {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `NoPin` | = note: downstream crates may implement trait `PinA<_>` for type `NoPin` diff --git a/tests/ui/generic-const-items/associated-const-equality.rs b/tests/ui/generic-const-items/associated-const-equality.rs deleted file mode 100644 index 6f5d4985ae53..000000000000 --- a/tests/ui/generic-const-items/associated-const-equality.rs +++ /dev/null @@ -1,40 +0,0 @@ -//@ check-pass - -#![feature(generic_const_items, min_generic_const_args)] -#![feature(associated_const_equality, adt_const_params)] -#![allow(incomplete_features)] - -trait Owner { - #[type_const] - const C: u32; - #[type_const] - const K: u32; - // #[type_const] - // const Q: Maybe; -} - -impl Owner for () { - #[type_const] - const C: u32 = N; - #[type_const] - const K: u32 = 99 + 1; - // FIXME(mgca): re-enable once we properly support ctors and generics on paths - // #[type_const] - // const Q: Maybe = Maybe::Nothing; -} - -fn take0(_: impl Owner = { N }>) {} -fn take1(_: impl Owner = 100>) {} -// FIXME(mgca): re-enable once we properly support ctors and generics on paths -// fn take2(_: impl Owner = { Maybe::Just(()) }>) {} - -fn main() { - take0::<128>(()); - take1(()); -} - -#[derive(PartialEq, Eq, std::marker::ConstParamTy)] -enum Maybe { - Nothing, - Just(T), -} diff --git a/tests/ui/generic-const-items/compare-impl-item.rs b/tests/ui/generic-const-items/compare-impl-item.rs index b301cd0dae0c..e8a23b5c44bb 100644 --- a/tests/ui/generic-const-items/compare-impl-item.rs +++ b/tests/ui/generic-const-items/compare-impl-item.rs @@ -14,15 +14,15 @@ trait Trait